summaryrefslogtreecommitdiffstats
path: root/pki/base/common
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common')
-rw-r--r--pki/base/common/CMakeLists.txt27
-rw-r--r--pki/base/common/LICENSE291
-rw-r--r--pki/base/common/build.xml427
-rw-r--r--pki/base/common/scripts/functions1046
-rwxr-xr-xpki/base/common/scripts/pki_apache_initscript246
-rw-r--r--pki/base/common/setup/CertServer.directory23
-rw-r--r--pki/base/common/setup/menu.xml10
-rw-r--r--pki/base/common/setup/web-app_2_3.dtd1063
-rw-r--r--pki/base/common/src/CMakeLists.txt1037
-rw-r--r--pki/base/common/src/LogMessages.properties2456
-rw-r--r--pki/base/common/src/UserMessages.properties1128
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/ACL.java184
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/ACLEntry.java228
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/ACLsResources.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/EACLsException.java138
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/IACL.java67
-rw-r--r--pki/base/common/src/com/netscape/certsrv/acls/IACLEntry.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/apps/CMS.java1606
-rw-r--r--pki/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java1088
-rw-r--r--pki/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java98
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java56
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java85
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/AuthResources.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/AuthToken.java443
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EAuthException.java81
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java33
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java106
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java223
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java208
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java46
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java31
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authority/IAuthority.java69
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java104
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java56
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java80
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java164
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java82
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java169
-rw-r--r--pki/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java149
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ASubsystem.java71
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java70
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/BaseResources.java47
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/EBaseException.java150
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java91
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IArgBlock.java285
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IAttrSet.java72
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IAuthInfo.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java40
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IConfigStore.java276
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java84
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IPluginImpl.java107
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java72
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java40
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java82
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ISubsystem.java82
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java40
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/ITimeSource.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java225
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/MessageFormatter.java155
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java198
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/MetaInfo.java116
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/Nonces.java128
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/PasswordResources.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/Plugin.java65
-rw-r--r--pki/base/common/src/com/netscape/certsrv/base/SessionContext.java163
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/CAResources.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ECAException.java86
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java37
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ICAService.java101
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java74
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java59
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java546
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java497
-rw-r--r--pki/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java58
-rw-r--r--pki/base/common/src/com/netscape/certsrv/client/IDataProcessor.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java29
-rw-r--r--pki/base/common/src/com/netscape/certsrv/client/connection/IConnection.java51
-rw-r--r--pki/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/ConfigConstants.java334
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/Constants.java750
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/DestDef.java57
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/NameValuePair.java77
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/NameValuePairs.java191
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/OpDef.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/PrefixDef.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/ScopeDef.java193
-rw-r--r--pki/base/common/src/com/netscape/certsrv/common/TaskId.java130
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IConnector.java62
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java48
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java59
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java68
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java56
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/connector/IResender.java51
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/DBResources.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/EDBException.java84
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java80
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java22
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBObj.java42
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java171
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java211
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java49
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java213
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java149
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/Modification.java91
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java62
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java176
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java97
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java512
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java54
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java165
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java183
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java125
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java54
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java177
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java102
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java92
-rw-r--r--pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java49
-rw-r--r--pki/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java89
-rw-r--r--pki/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java57
-rw-r--r--pki/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java77
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/EJobsException.java77
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/IJob.java87
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/IJobCron.java55
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java160
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java75
-rw-r--r--pki/base/common/src/com/netscape/certsrv/jobs/JobsResources.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/EKRAException.java88
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/IJoinShares.java33
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java319
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/IKeyService.java177
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java87
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/IShare.java32
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/KRAResources.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java440
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ELdapException.java86
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java35
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java103
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java90
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java84
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java60
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ldap/LdapResources.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/listeners/EListenersException.java84
-rw-r--r--pki/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java77
-rw-r--r--pki/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/AuditEvent.java331
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/AuditFormat.java112
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ConsoleError.java42
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java121
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ELogException.java148
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java35
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogEvent.java106
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java55
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java125
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogQueue.java74
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java105
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/ILogger.java496
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/LogPlugin.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/LogResources.java59
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java334
-rw-r--r--pki/base/common/src/com/netscape/certsrv/logging/SystemEvent.java330
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/ENotificationException.java77
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java84
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java57
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/IMailNotification.java85
-rw-r--r--pki/base/common/src/com/netscape/certsrv/notification/NotificationResources.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java181
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java197
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java100
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java76
-rw-r--r--pki/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java83
-rw-r--r--pki/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java58
-rw-r--r--pki/base/common/src/com/netscape/certsrv/pattern/Pattern.java164
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/EPolicyException.java165
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IExpression.java63
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java54
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java67
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java80
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java54
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java34
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java34
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java195
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java127
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IPolicySet.java106
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java34
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java34
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/policy/PolicyResources.java46
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java112
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/EDeferException.java47
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/EProfileException.java43
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/ERejectException.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java158
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java90
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java144
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfile.java407
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java118
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileContext.java48
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileEx.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileInput.java116
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java117
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java49
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java136
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java75
-rw-r--r--pki/base/common/src/com/netscape/certsrv/property/Descriptor.java94
-rw-r--r--pki/base/common/src/com/netscape/certsrv/property/EPropertyException.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java70
-rw-r--r--pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java88
-rw-r--r--pki/base/common/src/com/netscape/certsrv/property/PropertySet.java58
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java42
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java38
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java106
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java70
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java59
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java71
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java81
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java46
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java51
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java47
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java86
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/ILdapRule.java78
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java122
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java341
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java58
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/MapperProxy.java64
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java63
-rw-r--r--pki/base/common/src/com/netscape/certsrv/publish/RulePlugin.java42
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ra/IRAService.java74
-rw-r--r--pki/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java175
-rw-r--r--pki/base/common/src/com/netscape/certsrv/registry/ERegistryException.java39
-rw-r--r--pki/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java65
-rw-r--r--pki/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java91
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java538
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/AgentApproval.java64
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/AgentApprovals.java156
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java31
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/INotify.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IPolicy.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequest.java729
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestList.java58
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestListener.java55
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java133
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java414
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestRecord.java113
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java53
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java105
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/IService.java48
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/PolicyMessage.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/PolicyResult.java36
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/RequestId.java72
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/RequestStatus.java171
-rw-r--r--pki/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java56
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/Credential.java61
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java462
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java130
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/ISigningUnit.java165
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java106
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/IToken.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java55
-rw-r--r--pki/base/common/src/com/netscape/certsrv/security/KeyCertData.java813
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java225
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java225
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java234
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java123
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java140
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java358
-rw-r--r--pki/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java41
-rw-r--r--pki/base/common/src/com/netscape/certsrv/template/ArgList.java68
-rw-r--r--pki/base/common/src/com/netscape/certsrv/template/ArgSet.java74
-rw-r--r--pki/base/common/src/com/netscape/certsrv/template/ArgString.java48
-rw-r--r--pki/base/common/src/com/netscape/certsrv/template/IArgValue.java28
-rw-r--r--pki/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java71
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java83
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java49
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java70
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java50
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java44
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java232
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IUser.java154
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java70
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java110
-rw-r--r--pki/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java45
-rw-r--r--pki/base/common/src/com/netscape/certsrv/util/HttpInput.java296
-rw-r--r--pki/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java63
-rw-r--r--pki/base/common/src/com/netscape/certsrv/util/StatsEvent.java194
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/AVAPattern.java542
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java325
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/CMCAuth.java1048
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/Crypt.java437
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/DNPattern.java211
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java657
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java678
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/HashAuthData.java117
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/HashAuthentication.java290
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/PortalEnroll.java458
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/RDNPattern.java227
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java353
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/SharedSecret.java36
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java298
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java199
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java270
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java464
-rw-r--r--pki/base/common/src/com/netscape/cms/authorization/AAclAuthz.java885
-rw-r--r--pki/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java226
-rw-r--r--pki/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java368
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java263
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java154
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java108
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java99
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java222
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java110
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java238
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java157
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java101
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java281
-rw-r--r--pki/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java336
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java182
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java130
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java153
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java171
-rw-r--r--pki/base/common/src/com/netscape/cms/jobs/AJobBase.java281
-rw-r--r--pki/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java405
-rw-r--r--pki/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java718
-rw-r--r--pki/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java219
-rw-r--r--pki/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java395
-rw-r--r--pki/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java445
-rw-r--r--pki/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java439
-rw-r--r--pki/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java182
-rw-r--r--pki/base/common/src/com/netscape/cms/listeners/RequestInQListener.java277
-rw-r--r--pki/base/common/src/com/netscape/cms/logging/LogEntry.java136
-rw-r--r--pki/base/common/src/com/netscape/cms/logging/LogFile.java1492
-rw-r--r--pki/base/common/src/com/netscape/cms/logging/RollingLogFile.java651
-rw-r--r--pki/base/common/src/com/netscape/cms/notification/MailNotification.java195
-rw-r--r--pki/base/common/src/com/netscape/cms/ocsp/DefStore.java924
-rw-r--r--pki/base/common/src/com/netscape/cms/ocsp/LDAPStore.java724
-rw-r--r--pki/base/common/src/com/netscape/cms/password/PasswordChecker.java116
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/APolicyRule.java354
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java165
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java401
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java249
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java105
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java207
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java221
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java103
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java274
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java235
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java342
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java208
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java442
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java47
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java299
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java316
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java381
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java418
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java498
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java464
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java521
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java247
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java320
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java271
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java471
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java252
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java351
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java288
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java541
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java468
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java183
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java282
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java417
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java164
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java250
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java141
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java350
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java322
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java434
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java368
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java1186
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java147
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java252
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java1403
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java36
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/ProfileContext.java41
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java53
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java138
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java135
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java137
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java223
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java58
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java134
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java207
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java150
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java144
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java299
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java286
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java240
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java96
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java162
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java153
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java130
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java290
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java233
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java209
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java455
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java152
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java191
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java96
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java301
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java106
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java342
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java696
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java760
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java191
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java783
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java42
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java253
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java588
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java260
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/ImageDefault.java106
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java272
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java313
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java509
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java247
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java421
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java658
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/NoDefault.java106
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java289
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java422
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java315
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java184
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java536
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java523
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java449
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java213
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java181
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java133
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java229
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java126
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java139
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java149
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java259
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java211
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java409
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java212
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java448
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java129
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/CertReqInput.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java164
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/EnrollInput.java297
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java141
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/GenericInput.java155
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/ImageInput.java86
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java187
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java94
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java141
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java382
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java107
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java160
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java138
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java157
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/output/CertOutput.java121
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java130
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java157
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java118
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java179
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java592
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java366
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java179
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java193
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java337
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java159
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java439
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java639
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java320
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java634
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java202
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java218
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/NoMap.java108
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java424
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java408
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java332
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java306
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java367
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java342
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java315
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java351
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/Utils.java131
-rw-r--r--pki/base/common/src/com/netscape/cms/request/RequestScheduler.java88
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ASelfTest.java194
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java279
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java279
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java235
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java270
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java297
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java297
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java279
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java323
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java915
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java44
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java1304
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java1690
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java100
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java1642
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java3677
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java1004
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java887
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java2550
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java560
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java1243
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java2683
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java3054
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java576
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java362
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java2332
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java2235
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java111
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java92
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java330
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/GetStats.java177
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java118
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java93
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java246
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java287
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/UserInfo.java91
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java1141
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java701
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java160
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java242
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java173
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java465
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java469
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java231
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java1156
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java911
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java659
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java613
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java183
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java1831
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java292
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java405
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java468
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java338
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java174
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java368
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java1241
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java372
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java733
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java389
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java281
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java607
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java517
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java386
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java101
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java758
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java512
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java734
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java2126
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java142
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java187
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java100
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java1063
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSFile.java104
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java163
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java46
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java369
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java64
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java298
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java596
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java73
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java74
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java102
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java270
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java95
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java65
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java80
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java69
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java78
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java50
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/IRawJS.java27
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java121
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/RawJS.java36
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/common/Utils.java106
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java567
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java1092
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java294
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java341
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java326
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java687
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java229
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java193
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java430
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java114
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java328
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java184
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java216
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java757
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java652
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java115
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java117
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java37
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java46
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java46
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java190
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java318
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java287
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java46
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java185
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java135
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java302
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java1507
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java45
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java235
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java45
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java800
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java146
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java160
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java211
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java276
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java241
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java115
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java155
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java147
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java203
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java342
-rwxr-xr-xpki/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java161
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java195
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java333
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java70
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java155
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java330
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java86
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java986
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java255
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java693
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java159
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java81
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java500
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java100
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java47
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java652
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java137
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java203
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java486
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java284
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java180
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java123
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java45
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java1603
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java131
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java131
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java130
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java183
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java194
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java212
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java135
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java251
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java238
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java241
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java235
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java288
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java315
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java102
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java528
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java293
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java314
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java322
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java605
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java224
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java173
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java211
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java272
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java225
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java463
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java370
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java105
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java185
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java342
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java417
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java519
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java169
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java936
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java436
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java401
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java499
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java877
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java1530
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java40
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java893
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java591
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/IReqParser.java55
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java83
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java1912
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java327
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/QueryReq.java547
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/ReqParser.java88
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java327
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java1380
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java106
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java498
-rw-r--r--pki/base/common/src/com/netscape/cms/shares/OldJoinShares.java90
-rw-r--r--pki/base/common/src/com/netscape/cms/shares/OldShare.java68
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/CMSEngine.java1915
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/CommandQueue.java98
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java43
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java36
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/Setup.java347
-rw-r--r--pki/base/common/src/com/netscape/cmscore/apps/Upgrade.java339
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java501
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java266
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java408
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java154
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java264
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java286
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java161
-rw-r--r--pki/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java459
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/ArgBlock.java712
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/FileConfigStore.java213
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java256
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/PropConfigStore.java767
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/SimpleProperties.java610
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java55
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java74
-rw-r--r--pki/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java43
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java52
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java44
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CertUtils.java1072
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CertificatePair.java271
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java257
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java44
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java491
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java47
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java183
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java166
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java294
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java45
-rw-r--r--pki/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java277
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java315
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/HttpConnection.java238
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/HttpConnector.java198
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java221
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java73
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/LocalConnector.java203
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java70
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java124
-rw-r--r--pki/base/common/src/com/netscape/cmscore/connector/Resender.java249
-rw-r--r--pki/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java122
-rw-r--r--pki/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java33
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java118
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java57
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java325
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java365
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java64
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java278
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java118
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java98
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java1985
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java553
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java447
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java56
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java92
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java951
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java769
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java105
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java108
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java86
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java58
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java348
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java111
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java553
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java80
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java61
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java117
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java119
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java135
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java150
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java82
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/Repository.java504
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java112
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java44
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java81
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java167
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java91
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java106
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java107
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java363
-rw-r--r--pki/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java159
-rw-r--r--pki/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java239
-rw-r--r--pki/base/common/src/com/netscape/cmscore/jobs/CronItem.java167
-rw-r--r--pki/base/common/src/com/netscape/cmscore/jobs/CronRange.java88
-rw-r--r--pki/base/common/src/com/netscape/cmscore/jobs/JobCron.java355
-rw-r--r--pki/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java541
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java75
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java141
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java79
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java374
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java796
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java531
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapRule.java297
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java475
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/PublishObject.java92
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java1504
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java468
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java87
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java299
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java530
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java214
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java118
-rw-r--r--pki/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java104
-rw-r--r--pki/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java57
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java97
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/AuditFormat.java110
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/LogQueue.java127
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java272
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/Logger.java374
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java124
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java47
-rw-r--r--pki/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java98
-rw-r--r--pki/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java250
-rw-r--r--pki/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java86
-rw-r--r--pki/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java185
-rw-r--r--pki/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java151
-rw-r--r--pki/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java268
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/AndExpression.java59
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java672
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java1552
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java46
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/OrExpression.java65
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java373
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/PolicySet.java301
-rw-r--r--pki/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java435
-rw-r--r--pki/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java319
-rw-r--r--pki/base/common/src/com/netscape/cmscore/registry/PluginInfo.java54
-rw-r--r--pki/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java287
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/ARequestQueue.java1540
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/ARequestRecord.java44
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java74
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java71
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/RequestAttr.java63
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java708
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/RequestRecord.java870
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/RequestRepository.java214
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java190
-rw-r--r--pki/base/common/src/com/netscape/cmscore/request/Schema.java51
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/CASigningCert.java169
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/CertificateInfo.java255
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/JssSubsystem.java2153
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/KRATransportCert.java110
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java1088
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java147
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/PWCBsdr.java276
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/PWUtil.java83
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/PWsdrCache.java639
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/Provider.java53
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/RASigningCert.java125
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/SSLCert.java137
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java131
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/SubsystemCert.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java139
-rw-r--r--pki/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java1907
-rw-r--r--pki/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java30
-rw-r--r--pki/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java76
-rw-r--r--pki/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java82
-rw-r--r--pki/base/common/src/com/netscape/cmscore/usrgrp/Group.java119
-rw-r--r--pki/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java1747
-rw-r--r--pki/base/common/src/com/netscape/cmscore/usrgrp/User.java216
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/Assert.java49
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/AssertionException.java32
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/Debug.java363
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java91
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/FileAsString.java123
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java146
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/OsSubsystem.java488
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/PFXUtils.java162
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java294
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java210
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/UtilMessage.java179
-rw-r--r--pki/base/common/src/com/netscape/cmscore/util/UtilResources.java74
-rw-r--r--pki/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java540
-rw-r--r--pki/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java274
-rw-r--r--pki/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java70
-rw-r--r--pki/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java81
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java86
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java74
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java170
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java70
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java84
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java87
-rw-r--r--pki/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java39
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java31
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java279
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java87
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java269
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java21
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java59
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java168
-rw-r--r--pki/base/common/test/com/netscape/cmscore/request/RequestTest.java650
-rw-r--r--pki/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java98
-rw-r--r--pki/base/common/test/com/netscape/cmscore/test/TestHelper.java30
953 files changed, 258958 insertions, 0 deletions
diff --git a/pki/base/common/CMakeLists.txt b/pki/base/common/CMakeLists.txt
new file mode 100644
index 000000000..d8fb5d2c1
--- /dev/null
+++ b/pki/base/common/CMakeLists.txt
@@ -0,0 +1,27 @@
+project(common Java)
+
+install(
+ FILES
+ scripts/functions
+ scripts/pki_apache_initscript
+ DESTINATION
+ ${DATA_INSTALL_DIR}/scripts/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ setup/CertServer.directory
+ setup/menu.xml
+ DESTINATION
+ ${DATA_INSTALL_DIR}/setup/
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
+
+add_subdirectory(src)
diff --git a/pki/base/common/LICENSE b/pki/base/common/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/pki/base/common/LICENSE
@@ -0,0 +1,291 @@
+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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/pki/base/common/build.xml b/pki/base/common/build.xml
new file mode 100644
index 000000000..53f248d65
--- /dev/null
+++ b/pki/base/common/build.xml
@@ -0,0 +1,427 @@
+<!-- ### 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.
+
+ Copyright (C) 2007 Red Hat, Inc.
+ All rights reserved.
+ ### END COPYRIGHT BLOCK ### -->
+<project name="common" default="main" basedir=".">
+
+ <import file="config/product.xml"/>
+ <import file="config/product-ext.xml" optional="true"/>
+
+ <property name="jss.home" value="${jni-jar.home}${dirsec}"/>
+ <property name="jss.jar" value="${jss.home}/jss4.jar"/>
+ <property name="osutil.jar" value="${jni-jar.home}/osutil.jar"/>
+ <property name="symkey.jar" value="${jni-jar.home}/symkey.jar"/>
+ <property name="ldapjdk.jar" value="${jar.home}/ldapjdk.jar"/>
+ <property name="servlet.jar" value="${jar.home}/servlet.jar"/>
+ <property name="velocity.jar" value="${jar.home}/velocity.jar"/>
+ <property name="xalan-j2.jar" value="${jar.home}/xalan-j2.jar"/>
+ <property name="xerces-j2.jar" value="${jar.home}/xerces-j2.jar"/>
+ <property name="pki-cmsutil.jar" value="${pki-jar.home}/pki-cmsutil.jar"/>
+ <property name="pki-nsutil.jar" value="${pki-jar.home}/pki-nsutil.jar"/>
+
+ <path id="classpath">
+ <pathelement location="${servlet.jar}"/>
+ <pathelement location="${jss.jar}"/>
+ <pathelement location="${ldapjdk.jar}"/>
+ <pathelement location="${pki-nsutil.jar}"/>
+ <pathelement location="${pki-cmsutil.jar}"/>
+ <pathelement location="${osutil.jar}"/>
+ <pathelement location="${symkey.jar}"/>
+ <pathelement location="${velocity.jar}"/>
+ </path>
+ <path id="javadoc_classpath">
+ <path refid="classpath"/>
+ <pathelement location="${xalan-j2.jar}"/>
+ <pathelement location="${xerces-j2.jar}"/>
+ <pathelement location="./build/classes"/>
+ </path>
+ <path id="test_classpath">
+ <pathelement location="${jar.home}/junit.jar"/>
+ <pathelement location="${build.classes}"/>
+ <pathelement location="${build.tests}"/>
+ <path refid="classpath"/>
+ </path>
+
+ <!-- Set up component-specific properties -->
+ <exec executable="perl"
+ failonerror="true"
+ outputproperty="request.queue.version">
+ <arg value="-pi -e"/>
+ <arg value='s/REQUEST_VERSION = ".*";/REQUEST_VERSION = "${version}";/'/>
+ <arg value="src/com/netscape/cmscore/request/ARequestQueue.java"/>
+ </exec>
+
+
+ <target name="clean"
+ depends=""
+ description="--> remove component directories">
+ <echo message="${begin.clean.log.message}"/>
+ <delete dir="${dist.base}"/>
+ <delete dir="${build.dir}"/>
+ <echo message="${end.clean.log.message}"/>
+ </target>
+
+
+ <target name="download"
+ depends=""
+ description="--> download dependent components">
+ <echo message="${begin.download.log.message}"/>
+ <echo message="${empty.download.log.message}"/>
+ <echo message="${end.download.log.message}"/>
+ </target>
+
+
+ <target name="compile_java"
+ depends=""
+ description="--> compile java source code into classes">
+ <echo message="${begin.compile.java.log.message}"/>
+ <mkdir dir="${build.classes}"/>
+ <javac debug="on"
+ srcdir="${src.dir}/com/netscape/certsrv"
+ destdir="${build.classes}">
+ <classpath refid="classpath"/>
+ </javac>
+ <javac debug="on"
+ srcdir="${src.dir}/com/netscape/cms"
+ destdir="${build.classes}">
+ <classpath refid="classpath"/>
+ </javac>
+ <javac debug="on"
+ srcdir="${src.dir}/com/netscape/cmscore"
+ destdir="${build.classes}">
+ <classpath refid="classpath"/>
+ </javac>
+ <echo message="${end.compile.java.log.message}"/>
+ </target>
+
+
+ <target name="build_jars"
+ depends="compile_java"
+ description="--> generate jar files">
+ <echo message="${begin.build.jars.log.message}"/>
+ <mkdir dir="${build.jars}"/>
+ <jar jarfile="${build.jars}/pki-certsrv.jar">
+ <fileset dir="${build.classes}">
+ <include name="com/netscape/certsrv/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${build.jars}/pki-cms.jar">
+ <fileset dir="${build.classes}">
+ <include name="com/netscape/cms/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${build.jars}/pki-cmscore.jar">
+ <fileset dir="${build.classes}">
+ <include name="com/netscape/cmscore/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${build.jars}/pki-cmsbundle.jar">
+ <fileset dir="${src.dir}">
+ <include name="LogMessages.properties"/>
+ <include name="UserMessages.properties"/>
+ </fileset>
+ </jar>
+ <echo message="${end.build.jars.log.message}"/>
+ </target>
+
+
+ <target name="build_jni_headers"
+ depends="compile_java"
+ description="--> generate jni header files">
+ <echo message="${begin.build.jni.headers.log.message}"/>
+ <echo message="${empty.build.jni.headers.log.message}"/>
+ <echo message="${end.build.jni.headers.log.message}"/>
+ </target>
+
+
+ <target name="build"
+ depends="build_jars,build_jni_headers"
+ description="--> build classes, jars, and jni headers">
+ <echo message="${notify.build.log.message}"/>
+ </target>
+
+
+ <target name="compile_junit_tests"
+ depends="build"
+ description="--> compile junit test source code">
+ <echo message="${begin.compile.junit.tests.log.message}"/>
+ <mkdir dir="${build.tests}"/>
+ <javac debug="on"
+ srcdir="${test.dir}"
+ destdir="${build.tests}">
+ <classpath refid="test_classpath"/>
+ </javac>
+ <echo message="${end.compile.junit.tests.log.message}"/>
+ </target>
+
+
+ <target name="run_junit_tests"
+ depends="compile_junit_tests"
+ description="--> execute junit tests">
+ <echo message="${begin.run.junit.tests.log.message}"/>
+ <junit showoutput="yes"
+ printsummary="yes"
+ haltonfailure="no">
+ <classpath refid="test_classpath"/>
+ <formatter type="plain"
+ usefile="no"/>
+ <batchtest fork="yes">
+ <fileset dir="${build.tests}">
+ <include name="**/*Test.class"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ <echo message="${end.run.junit.tests.log.message}"/>
+ </target>
+
+
+ <target name="verify"
+ depends="run_junit_tests"
+ description="--> build and execute junit tests">
+ <echo message="${notify.verify.log.message}"/>
+ </target>
+
+
+ <target name="clean_javadocs"
+ depends=""
+ description="--> remove javadocs directory">
+ <echo message="${begin.clean.javadocs.log.message}"/>
+ <delete dir="${docs.dir}"/>
+ <echo message="${end.clean.javadocs.log.message}"/>
+ </target>
+
+
+ <target name="compose_javadocs"
+ depends="build"
+ description="--> generate javadocs">
+ <echo message="${begin.compose.javadocs.log.message}"/>
+ <mkdir dir="${docs.dir}"/>
+ <javadoc destdir="${docs.dir}"
+ maxmemory="512m"
+ author="true"
+ breakiterator="true"
+ version="true"
+ use="true"
+ windowtitle="${ant.project.name}"
+ classpathref="javadoc_classpath"
+ verbose="false">
+ <doctitle>
+ <![CDATA[<h1>${ant.project.name}</h1>]]>
+ </doctitle>
+ <fileset dir="src"
+ defaultexcludes="yes">
+ <include name="com/netscape/certsrv/**"/>
+ <include name="com/netscape/cms/**"/>
+ </fileset>
+ </javadoc>
+ <echo message="${end.compose.javadocs.log.message}"/>
+ </target>
+
+
+ <target name="document"
+ depends="clean_javadocs,compose_javadocs"
+ description="--> remove old javadocs and compose new javadocs">
+ <echo message="${notify.document.log.message}"/>
+ </target>
+
+
+ <target name="distribute_binaries"
+ depends="document"
+ description="--> create the zip and gzipped tar binary distributions">
+ <echo message="${begin.distribute.binaries.log.message}"/>
+ <mkdir dir="${dist.base.binaries}"/>
+
+ <echo message="${begin.binary.wrappers.log.message}"/>
+ <echo message="${empty.binary.wrappers.log.message}"/>
+ <echo message="${end.binary.wrappers.log.message}"/>
+
+ <echo message="${begin.binary.zip.log.message}"/>
+ <zip destfile="${dist.base.binaries}/${dist.name}.zip">
+ <zipfileset dir="./build/jars"
+ filemode="755"
+ prefix="usr/share/java/${product.prefix}">
+ <include name="**"/>
+ </zipfileset>
+ <zipfileset dir="./scripts"
+ filemode="755"
+ prefix="usr/share/${product.prefix}/scripts">
+ <include name="**"/>
+ </zipfileset>
+ <zipfileset dir="./setup"
+ filemode="644"
+ prefix="usr/share/${product.prefix}/setup">
+ <include name="**"/>
+ </zipfileset>
+ <zipfileset dir="."
+ filemode="644"
+ prefix="usr/share/doc/${dist.name}">
+ <include name="EULA"/>
+ <include name="LICENSE"/>
+ </zipfileset>
+ <zipfileset dir="./docs"
+ filemode="644"
+ prefix="usr/share/javadoc/${product.name}-${version}">
+ <include name="**"/>
+ </zipfileset>
+ </zip>
+ <echo message="${end.binary.zip.log.message}"/>
+
+ <echo message="${begin.binary.tar.log.message}"/>
+ <tar longfile="gnu"
+ destfile="${dist.base.binaries}/${dist.name}.tar">
+ <tarfileset dir="./build/jars"
+ mode="755"
+ prefix="${dist.name}/usr/share/java/${product.prefix}">
+ <include name="**"/>
+ </tarfileset>
+ <tarfileset dir="./scripts"
+ mode="755"
+ prefix="${dist.name}/usr/share/${product.prefix}/scripts">
+ <include name="**"/>
+ </tarfileset>
+ <tarfileset dir="./setup"
+ mode="644"
+ prefix="usr/share/${product.prefix}/setup">
+ <include name="**"/>
+ </tarfileset>
+ <tarfileset dir="."
+ mode="644"
+ prefix="${dist.name}/usr/share/doc/${dist.name}">
+ <include name="EULA"/>
+ <include name="LICENSE"/>
+ </tarfileset>
+ <tarfileset dir="./docs"
+ mode="644"
+ prefix="${dist.name}/usr/share/javadoc/${product.name}-${version}">
+ <include name="**"/>
+ </tarfileset>
+ </tar>
+ <echo message="${end.binary.tar.log.message}"/>
+
+ <echo message="${begin.binary.gtar.log.message}"/>
+ <gzip destfile="${dist.base.binaries}/${dist.name}.tar.gz"
+ src="${dist.base.binaries}/${dist.name}.tar"/>
+ <delete file="${dist.base.binaries}/${dist.name}.tar"/>
+ <delete dir="${dist.name}"/>
+ <checksum fileext=".md5">
+ <fileset dir="${dist.base.binaries}/">
+ <include name="**/*"/>
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ </fileset>
+ </checksum>
+ <checksum fileext=".sha1"
+ algorithm="SHA">
+ <fileset dir="${dist.base.binaries}/">
+ <include name="**/*"/>
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ </fileset>
+ </checksum>
+ <echo message="${end.binary.gtar.log.message}"/>
+
+ <echo message="${end.distribute.binaries.log.message}"/>
+ </target>
+
+
+ <target name="distribute_source"
+ depends=""
+ description="--> create the zip and gzipped tar source distributions">
+ <echo message="${begin.distribute.source.log.message}"/>
+ <mkdir dir="${dist.base.source}"/>
+
+ <echo message="${begin.source.zip.log.message}"/>
+ <zip destfile="${dist.base.source}/${src.dist.name}.zip">
+ <zipfileset dir="."
+ filemode="644"
+ prefix="${src.dist.name}">
+ <include name="${specfile}"/>
+ <include name="EULA"/>
+ <include name="LICENSE"/>
+ <include name="build.xml"/>
+ <include name="config/product*.xml"/>
+ <include name="config/release*.xml"/>
+ <include name="release"/>
+ <include name="scripts/**"/>
+ <include name="setup/**"/>
+ <include name="src/**"/>
+ <include name="test/**"/>
+ </zipfileset>
+ </zip>
+ <echo message="${end.source.zip.log.message}"/>
+
+ <echo message="${begin.source.tar.log.message}"/>
+ <tar longfile="gnu"
+ destfile="${dist.base.source}/${src.dist.name}.tar">
+ <tarfileset dir="."
+ mode="644"
+ prefix="${src.dist.name}">
+ <include name="${specfile}"/>
+ <include name="EULA"/>
+ <include name="LICENSE"/>
+ <include name="build.xml"/>
+ <include name="config/product*.xml"/>
+ <include name="config/release*.xml"/>
+ <include name="release"/>
+ <include name="scripts/**"/>
+ <include name="setup/**"/>
+ <include name="src/**"/>
+ <include name="test/**"/>
+ </tarfileset>
+ </tar>
+ <echo message="${end.source.tar.log.message}"/>
+
+ <echo message="${begin.source.gtar.log.message}"/>
+ <gzip destfile="${dist.base.source}/${src.dist.name}.tar.gz"
+ src="${dist.base.source}/${src.dist.name}.tar"/>
+ <delete file="${dist.base.source}/${src.dist.name}.tar"/>
+ <delete dir="${dist.name}"/>
+ <checksum fileext=".md5">
+ <fileset dir="${dist.base.source}/">
+ <include name="**/*"/>
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ </fileset>
+ </checksum>
+ <checksum fileext=".sha1"
+ algorithm="SHA">
+ <fileset dir="${dist.base.source}/">
+ <include name="**/*"/>
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ </fileset>
+ </checksum>
+ <echo message="${end.source.gtar.log.message}"/>
+
+ <echo message="${end.distribute.source.log.message}"/>
+ </target>
+
+
+ <target name="distribute"
+ depends="distribute_binaries,distribute_source"
+ description="--> create binary and source component distributions">
+ <echo message="${notify.distribute.log.message}"/>
+ </target>
+
+
+ <target name="main"
+ depends="clean,distribute"
+ description="--> clean, build, verify, document, distribute [default]">
+ <echo message="${notify.main.log.message}"/>
+ </target>
+
+</project>
+
diff --git a/pki/base/common/scripts/functions b/pki/base/common/scripts/functions
new file mode 100644
index 000000000..e1c3e496a
--- /dev/null
+++ b/pki/base/common/scripts/functions
@@ -0,0 +1,1046 @@
+#!/bin/bash
+
+# From "http://fedoraproject.org/wiki/FCNewInit/Initscripts":
+#
+# Status Exit Codes
+#
+# 0 program is running or service is OK
+# 1 program is dead and /var/run pid file exists
+# 2 program is dead and /var/lock lock file exists
+# 3 program is not running
+# 4 program or service status is unknown
+# 5-99 reserved for future LSB use
+# 100-149 reserved for distribution use
+# 150-199 reserved for application use
+# 200-254 reserved
+#
+# Non-Status Exit Codes
+#
+# 0 action was successful
+# 1 generic or unspecified error (current practice)
+# 2 invalid or excess argument(s)
+# 3 unimplemented feature (for example, "reload")
+# 4 user had insufficient privilege
+# 5 program is not installed
+# 6 program is not configured
+# 7 program is not running
+# 8-99 reserved for future LSB use
+# 100-149 reserved for distribution use
+# 150-199 reserved for application use
+# 200-254 reserved
+#
+
+# PKI subsystem-level directory and file values for locks
+lockfile="/var/lock/subsys/${SERVICE_NAME}"
+
+default_error=0
+
+case $command in
+ start|stop|restart|condrestart|force-restart|try-restart)
+ # 1 generic or unspecified error (current practice)
+ default_error=1
+ ;;
+ reload)
+ default_error=3
+ ;;
+ status)
+ # 4 program or service status is unknown
+ default_error=4
+ ;;
+ *)
+ # 2 invalid argument(s)
+ default_error=2
+ ;;
+esac
+
+# Enable nullglob, if set then shell pattern globs which do not match any
+# file returns the empty string rather than the unmodified glob pattern.
+shopt -s nullglob
+
+OS=`uname -s`
+ARCHITECTURE=`uname -i`
+
+# Check to insure that this script's original invocation directory
+# has not been deleted!
+CWD=`/bin/pwd > /dev/null 2>&1`
+if [ $? -ne 0 ] ; then
+ echo "Cannot invoke '$PROG_NAME' from non-existent directory!"
+ exit ${default_error}
+fi
+
+# Check to insure that this script's associated PKI
+# subsystem currently resides on this system.
+if [ ! -d ${PKI_PATH} ] ; then
+ echo "This machine is missing the '${PKI_TYPE}' subsystem!"
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ exit ${default_error}
+ fi
+fi
+
+# Check to insure that this script's associated PKI
+# subsystem instance registry currently resides on this system.
+if [ ! -d ${PKI_REGISTRY} ] ; then
+ echo "This machine contains no registered '${PKI_TYPE}' subsystem instances!"
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ exit ${default_error}
+ fi
+fi
+
+# This script must be run as root!
+RV=0
+if [ `id -u` -ne 0 ] ; then
+ echo "Must be 'root' to execute '$PROG_NAME'!"
+ if [ "${command}" != "status" ]; then
+ # 4 user had insufficient privilege
+ exit 4
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+fi
+
+PKI_REGISTRY_ENTRIES=""
+TOTAL_PKI_REGISTRY_ENTRIES=0
+TOTAL_UNCONFIGURED_PKI_ENTRIES=0
+
+# Gather ALL registered instances of this PKI subsystem type
+for FILE in ${PKI_REGISTRY}/*; do
+ if [ -f "$FILE" ] ; then
+ PKI_REGISTRY_ENTRIES="${PKI_REGISTRY_ENTRIES} $FILE"
+ TOTAL_PKI_REGISTRY_ENTRIES=`expr ${TOTAL_PKI_REGISTRY_ENTRIES} + 1`
+ fi
+done
+
+if [ -n "${pki_instance}" ]; then
+ for I in ${PKI_REGISTRY_ENTRIES}; do
+ if [ "${PKI_REGISTRY}/${pki_instance}" = "$I" ]; then
+ PKI_REGISTRY_ENTRIES="${PKI_REGISTRY}/${pki_instance}"
+ TOTAL_PKI_REGISTRY_ENTRIES=1
+ break
+ fi
+ done
+fi
+
+usage()
+{
+ echo -n "Usage: ${SERVICE_PROG} ${SERVICE_NAME}"
+ echo -n "{start"
+ echo -n "|stop"
+ echo -n "|restart"
+ echo -n "|condrestart"
+ echo -n "|force-restart"
+ echo -n "|try-restart"
+ echo -n "|reload"
+ echo -n "|status} "
+ echo -n "[instance-name]"
+ echo
+ echo
+}
+
+list_instances()
+{
+ echo
+ for PKI_REGISTRY_ENTRY in $PKI_REGISTRY_ENTRIES; do
+ instance_name=`basename $PKI_REGISTRY_ENTRY`
+ echo " $instance_name"
+ done
+ echo
+}
+
+# Check arguments
+if [ $# -lt 1 ] ; then
+ # 3 unimplemented feature (for example, "reload")
+ # [insufficient arguments]
+ echo "$PROG_NAME: Insufficient arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit 3
+elif [ ${default_error} -eq 2 ] ; then
+ # 2 invalid argument
+ echo "$PROG_NAME: Invalid arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit 2
+elif [ $# -gt 2 ] ; then
+ echo "$PROG_NAME: Excess arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ if [ "${command}" != "status" ]; then
+ # 2 excess arguments
+ exit 2
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+fi
+
+# If an "instance" was supplied, check that it is a "valid" instance
+if [ -n "${pki_instance}" ]; then
+ valid=0
+ for PKI_REGISTRY_ENTRY in $PKI_REGISTRY_ENTRIES; do
+ instance_name=`basename $PKI_REGISTRY_ENTRY`
+ if [ $pki_instance == $instance_name ]; then
+ valid=1
+ break
+ fi
+ done
+ if [ $valid -eq 0 ]; then
+ echo -n "${pki_instance} is an invalid '${PKI_TYPE}' instance"
+ echo_failure
+ echo
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+ fi
+fi
+
+check_pki_configuration_status()
+{
+ rv=0
+
+ rv=`grep -c ^preop ${pki_instance_configuration_file}`
+
+ rv=`expr ${rv} + 0`
+
+ if [ $rv -ne 0 ] ; then
+ echo " '${PKI_INSTANCE_ID}' must still be CONFIGURED!"
+ echo " (see /var/log/${PKI_INSTANCE_ID}-install.log)"
+ if [ "${command}" != "status" ]; then
+ # 6 program is not configured
+ rv=6
+ else
+ # 4 program or service status is unknown
+ rv=4
+ fi
+ TOTAL_UNCONFIGURED_PKI_ENTRIES=`expr ${TOTAL_UNCONFIGURED_PKI_ENTRIES} + 1`
+ elif [ -f ${RESTART_SERVER} ] ; then
+ echo -n " Although '${PKI_INSTANCE_ID}' has been CONFIGURED, "
+ echo -n "it must still be RESTARTED!"
+ echo
+ if [ "${command}" != "status" ]; then
+ # 1 generic or unspecified error (current practice)
+ rv=1
+ else
+ # 4 program or service status is unknown
+ rv=4
+ fi
+ fi
+
+ return $rv
+}
+
+get_pki_status_definitions()
+{
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ get_pki_status_definitions_tomcat
+ return $?
+ ;;
+ ra)
+ get_pki_status_definitions_ra
+ return $?
+ ;;
+ tps)
+ get_pki_status_definitions_tps
+ return $?
+ ;;
+ *)
+ echo "Unknown subsystem type ($PKI_SUBSYSTEM_TYPE)"
+ exit ${default_error}
+ ;;
+ esac
+}
+
+get_pki_status_definitions_ra()
+{
+ # establish well-known strings
+ total_ports=0
+ UNSECURE_PORT=""
+ CLIENTAUTH_PORT=""
+ NON_CLIENTAUTH_PORT=""
+
+ # check to see that an instance-specific "httpd.conf" file exists
+ if [ ! -f ${PKI_HTTPD_CONF} ] ; then
+ echo "File '${PKI_HTTPD_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # check to see that an instance-specific "nss.conf" file exists
+ if [ ! -f ${PKI_NSS_CONF} ] ; then
+ echo "File '${PKI_NSS_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_HTTPD_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 0 ]; then
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ else
+ echo "ERROR: extra Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_NSS_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 1 ]; then
+ CLIENTAUTH_PORT=$port
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}"
+ fi
+ if [ $total_ports -eq 2 ]; then
+ NON_CLIENTAUTH_PORT=$port
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ if [ ${total_ports} -eq $PKI_TOTAL_PORTS ] ; then
+ return 0
+ else
+ return ${default_error}
+ fi
+}
+
+get_pki_status_definitions_tps()
+{
+ # establish well-known strings
+ total_ports=0
+ UNSECURE_PORT=""
+ CLIENTAUTH_PORT=""
+ NON_CLIENTAUTH_PORT=""
+
+ # check to see that an instance-specific "httpd.conf" file exists
+ if [ ! -f ${PKI_HTTPD_CONF} ] ; then
+ echo "File '${PKI_HTTPD_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # check to see that an instance-specific "nss.conf" file exists
+ if [ ! -f ${PKI_NSS_CONF} ] ; then
+ echo "File '${PKI_NSS_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_HTTPD_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 0 ]; then
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}/cgi-bin/so/enroll.cgi"
+ echo " (ESC Security Officer Enrollment)"
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}/cgi-bin/home/index.cgi"
+ echo " (ESC Phone Home)"
+ else
+ echo "ERROR: extra Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_NSS_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 1 ]; then
+ CLIENTAUTH_PORT=$port
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}/cgi-bin/sow/welcome.cgi"
+ echo " (ESC Security Officer Workstation)"
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}/tus"
+ echo " (TPS Roles - Operator/Administrator/Agent)"
+ fi
+ if [ $total_ports -eq 2 ]; then
+ NON_CLIENTAUTH_PORT=$port
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}/cgi-bin/so/enroll.cgi"
+ echo " (ESC Security Officer Enrollment)"
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}/cgi-bin/home/index.cgi"
+ echo " (ESC Phone Home)"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ if [ ${total_ports} -eq $PKI_TOTAL_PORTS ] ; then
+ return 0
+ else
+ return ${default_error}
+ fi
+}
+
+get_pki_status_definitions_tomcat()
+{
+ # establish well-known strings
+ begin_pki_status_comment="<!-- DO NOT REMOVE - Begin PKI Status Definitions -->"
+ end_pki_status_comment="<!-- DO NOT REMOVE - End PKI Status Definitions -->"
+ total_ports=0
+ unsecure_port_statement="Unsecure Port"
+ secure_agent_port_statement="Secure Agent Port"
+ secure_ee_port_statement="Secure EE Port"
+ secure_ee_client_auth_port_statement="EE Client Auth Port"
+ secure_admin_port_statement="Secure Admin Port"
+ pki_console_port_statement="PKI Console Port"
+ tomcat_port_statement="Tomcat Port"
+
+ # initialize looping variables
+ pki_status_comment_found=0
+
+ # first check to see that an instance-specific "server.xml" file exists
+ if [ ! -f ${PKI_SERVER_XML_CONF} ] ; then
+ echo "File '${PKI_SERVER_XML_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # read this instance-specific "server.xml" file line-by-line
+ # to obtain the current PKI Status Definitions
+ exec < ${PKI_SERVER_XML_CONF}
+ while read line; do
+ # first look for the well-known end PKI Status comment
+ # (to turn off processing)
+ if [ "$line" == "$end_pki_status_comment" ] ; then
+ pki_status_comment_found=0
+ break;
+ fi
+
+ # then look for the well-known begin PKI Status comment
+ # (to turn on processing)
+ if [ "$line" == "$begin_pki_status_comment" ] ; then
+ pki_status_comment_found=1
+ fi
+
+ # once the well-known begin PKI Status comment has been found,
+ # begin processing to obtain all of the PKI Status Definitions
+ if [ $pki_status_comment_found -eq 1 ] ; then
+ # look for a PKI Status Definition and print it
+ head=`echo "$line" | sed -e 's/^\([^=]*\)[ \t]*= .*$/\1/' -e 's/[ \t]*$//'`
+ if [ "$head" == "$unsecure_port_statement" ] ||
+ [ "$head" == "$secure_agent_port_statement" ] ||
+ [ "$head" == "$secure_ee_port_statement" ] ||
+ [ "$head" == "$secure_ee_client_auth_port_statement" ] ||
+ [ "$head" == "$secure_admin_port_statement" ] ||
+ [ "$head" == "$pki_console_port_statement" ] ||
+ [ "$head" == "$tomcat_port_statement" ] ; then
+ echo " $line"
+ total_ports=`expr ${total_ports} + 1`
+ fi
+ fi
+ done
+
+ if [ ${total_ports} -eq $PKI_TOTAL_PORTS ] ; then
+ return 0
+ else
+ return ${default_error}
+ fi
+}
+
+get_pki_configuration_definitions()
+{
+ # Obtain the PKI Subsystem Type
+ line=`grep -e '^[ \t]*cs.type[ \t]*=' ${pki_instance_configuration_file}`
+ pki_subsystem=`echo "${line}" | sed -e 's/^[^=]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${line}" != "" ] ; then
+ if [ "${pki_subsystem}" != "CA" ] &&
+ [ "${pki_subsystem}" != "KRA" ] &&
+ [ "${pki_subsystem}" != "OCSP" ] &&
+ [ "${pki_subsystem}" != "TKS" ] &&
+ [ "${pki_subsystem}" != "RA" ] &&
+ [ "${pki_subsystem}" != "TPS" ]
+ then
+ return ${default_error}
+ fi
+ if [ "${pki_subsystem}" == "KRA" ] ; then
+ # Rename "KRA" to "DRM"
+ pki_subsystem="DRM"
+ fi
+ else
+ return ${default_error}
+ fi
+
+ # If "${pki_subsystem}" is a CA, DRM, OCSP, or TKS,
+ # check to see if "${pki_subsystem}" is a "Clone"
+ pki_clone=""
+ if [ "${pki_subsystem}" == "CA" ] ||
+ [ "${pki_subsystem}" == "DRM" ] ||
+ [ "${pki_subsystem}" == "OCSP" ] ||
+ [ "${pki_subsystem}" == "TKS" ]
+ then
+ line=`grep -e '^[ \t]*subsystem.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_clone=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${pki_clone}" != "Clone" ] ; then
+ # Reset "${pki_clone}" to be empty
+ pki_clone=""
+ fi
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # If "${pki_subsystem}" is a CA, and is NOT a "Clone", check to
+ # see "${pki_subsystem}" is a "Root" or a "Subordinate" CA
+ pki_hierarchy=""
+ if [ "${pki_subsystem}" == "CA" ] &&
+ [ "${pki_clone}" != "Clone" ]
+ then
+ line=`grep -e '^[ \t]*hierarchy.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_hierarchy=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # If ${pki_subsystem} is a CA, check to
+ # see if it is also a Security Domain
+ pki_security_domain=""
+ if [ "${pki_subsystem}" == "CA" ] ; then
+ line=`grep -e '^[ \t]*securitydomain.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${pki_security_domain}" == "new" ] ; then
+ # Set a fixed value for "${pki_security_domain}"
+ pki_security_domain="(Security Domain)"
+ else
+ # Reset "${pki_security_domain}" to be empty
+ pki_security_domain=""
+ fi
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # Always obtain this PKI instance's "registered"
+ # security domain information
+ pki_security_domain_name=""
+ pki_security_domain_hostname=""
+ pki_security_domain_https_admin_port=""
+
+ line=`grep -e '^[ \t]*securitydomain.name[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_name=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ line=`grep -e '^[ \t]*securitydomain.host[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_hostname=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ line=`grep -e '^[ \t]*securitydomain.httpsadminport[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_https_admin_port=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ # Compose the "PKI Instance Name" Status Line
+ pki_instance_name="PKI Instance Name: ${PKI_INSTANCE_ID}"
+
+ # Compose the "PKI Subsystem Type" Status Line
+ header="PKI Subsystem Type: "
+ if [ "${pki_clone}" != "" ] ; then
+ if [ "${pki_security_domain}" != "" ]; then
+ # Possible Values:
+ #
+ # "CA Clone (Security Domain)"
+ #
+ data="${pki_subsystem} ${pki_clone} ${pki_security_domain}"
+ else
+ # Possible Values:
+ #
+ # "CA Clone"
+ # "DRM Clone"
+ # "OCSP Clone"
+ # "TKS Clone"
+ #
+ data="${pki_subsystem} ${pki_clone}"
+ fi
+ elif [ "${pki_hierarchy}" != "" ] ; then
+ if [ "${pki_security_domain}" != "" ]; then
+ # Possible Values:
+ #
+ # "Root CA (Security Domain)"
+ # "Subordinate CA (Security Domain)"
+ #
+ data="${pki_hierarchy} ${pki_subsystem} ${pki_security_domain}"
+ else
+ # Possible Values:
+ #
+ # "Root CA"
+ # "Subordinate CA"
+ #
+ data="${pki_hierarchy} ${pki_subsystem}"
+ fi
+ else
+ # Possible Values:
+ #
+ # "DRM"
+ # "OCSP"
+ # "RA"
+ # "TKS"
+ # "TPS"
+ #
+ data="${pki_subsystem}"
+ fi
+ pki_subsystem_type="${header} ${data}"
+
+ # Compose the "Registered PKI Security Domain Information" Status Line
+ header="Name: "
+ registered_pki_security_domain_name="${header} ${pki_security_domain_name}"
+
+ header="URL: "
+ if [ "${pki_security_domain_hostname}" != "" ] &&
+ [ "${pki_security_domain_https_admin_port}" != "" ]
+ then
+ data="https://${pki_security_domain_hostname}:${pki_security_domain_https_admin_port}"
+ else
+ return ${default_error}
+ fi
+ registered_pki_security_domain_url="${header} ${data}"
+
+ # Print the "PKI Subsystem Type" Status Line
+ echo
+ echo " ${pki_instance_name}"
+
+ # Print the "PKI Subsystem Type" Status Line
+ echo
+ echo " ${pki_subsystem_type}"
+
+ # Print the "Registered PKI Security Domain Information" Status Line
+ echo
+ echo " Registered PKI Security Domain Information:"
+ echo " =========================================================================="
+ echo " ${registered_pki_security_domain_name}"
+ echo " ${registered_pki_security_domain_url}"
+ echo " =========================================================================="
+
+ return 0
+}
+
+display_configuration_information()
+{
+ result=0
+ check_pki_configuration_status
+ rv=$?
+ if [ $rv -eq 0 ] ; then
+ get_pki_status_definitions
+ rv=$?
+ if [ $rv -ne 0 ] ; then
+ result=$rv
+ echo
+ echo "${PKI_INSTANCE_ID} Status Definitions not found"
+ else
+ get_pki_configuration_definitions
+ rv=$?
+ if [ $rv -ne 0 ] ; then
+ result=$rv
+ echo
+ echo "${PKI_INSTANCE_ID} Configuration Definitions not found"
+ fi
+ fi
+ fi
+ return $result
+}
+
+display_instance_status()
+{
+ rv=0
+
+ # Verify there is an initscript for this instance
+ if [ ! -f $PKI_INSTANCE_INITSCRIPT ]; then
+ # 4 program or service status is unknown
+ return 4
+ fi
+
+ # Invoke the initscript for this instance
+ $PKI_INSTANCE_INITSCRIPT status
+ rv=$?
+
+ if [ $rv -eq 0 ] ; then
+ display_configuration_information
+ fi
+
+ return $rv
+}
+
+start_instance()
+{
+ rv=0
+
+ if [ -f ${RESTART_SERVER} ] ; then
+ rm -f ${RESTART_SERVER}
+ fi
+
+ # Invoke the initscript for this instance
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
+ /usr/bin/runcon -t pki_${PKI_SUBSYSTEM_TYPE}_script_t \
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ else
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ fi
+ ;;
+ ra|tps)
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ ;;
+ esac
+
+ if [ $rv -ne 0 ] ; then
+ return $rv
+ fi
+
+ # On Tomcat subsystems, make certain that the service has started
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ count=0
+ tries=30
+ port=`grep '^pkicreate.unsecure_port=' ${pki_instance_configuration_file} | cut -b25- -`
+ while [ $count -lt $tries ]
+ do
+ netstat -antl | grep ${port} > /dev/null
+ netrv=$?
+ if [ $netrv -eq 0 ] ; then
+ break;
+ fi
+ sleep 1
+ let count=$count+1;
+ done
+ if [ $netrv -ne 0 ] ; then
+ return 1
+ fi
+ ;;
+ esac
+
+ if [ $rv -eq 0 ] ; then
+ # From the PKI point of view a returned error code of 6 implies
+ # that the program is not "configured". An error code of 1 implies
+ # that the program was "configured" but must still be restarted.
+ #
+ # If the return code is 6 return this value unchanged to the
+ # calling routine so that the total number of configuration errors
+ # may be counted. Other return codes are ignored.
+ #
+ check_pki_configuration_status
+ rv=$?
+ if [ $rv -eq 6 ]; then
+ # 6 program is not configured
+ return 6
+ else
+ # 0 success
+
+ # Tomcat instances automatically place pid files under
+ # '/var/run' and lock files under '/var/lock/subsys'.
+ #
+ # However, since PKI subsystem instances can have any name,
+ # in order to identify the PKI subsystem type of a particular
+ # PKI instance, we create a separate "pki subsystem identity"
+ # symlink to the PKI instance pid file and place it under
+ # '/var/run/pki/<pki subsystem>', and a separate
+ # "pki subsystem identity" symlink to the PKI instance
+ # lock file and place it under '/var/lock/pki/<pki subsystem>'.
+ #
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ -h ${PKI_PIDFILE} ]; then
+ rm -f ${PKI_PIDFILE}
+ fi
+ if [ -f ${TOMCAT_PIDFILE} ]; then
+ ln -s ${TOMCAT_PIDFILE} ${PKI_PIDFILE}
+ chown -h ${TOMCAT_USER}:${TOMCAT_GROUP} ${PKI_PIDFILE}
+ fi
+ if [ -h ${PKI_LOCKFILE} ]; then
+ rm -f ${PKI_LOCKFILE}
+ fi
+ if [ -f ${TOMCAT_LOCKFILE} ]; then
+ ln -s ${TOMCAT_LOCKFILE} ${PKI_LOCKFILE}
+ fi
+ ;;
+ esac
+
+ return 0
+ fi
+ fi
+ return $rv
+}
+
+stop_instance()
+{
+ rv=0
+
+ # Invoke the initscript for this instance
+ $PKI_INSTANCE_INITSCRIPT stop
+ rv=$?
+
+ # On Tomcat subsystems, always remove the "pki subsystem identity" symlinks
+ # that were previously associated with the Tomcat 'pid' and 'lock' files.
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ -h ${PKI_PIDFILE} ]; then
+ rm -f ${PKI_PIDFILE}
+ fi
+ if [ -h ${PKI_LOCKFILE} ]; then
+ rm -f ${PKI_LOCKFILE}
+ fi
+ ;;
+ esac
+
+ return $rv
+}
+
+start()
+{
+ error_rv=0
+ rv=0
+ config_errors=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 5 program is not installed
+ return 5
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ]; then
+ echo "BEGIN STARTING '${PKI_TYPE}' INSTANCES:"
+ fi
+
+ # Start every PKI instance of this type that isn't already running
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ start_instance
+ rv=$?
+ if [ $rv = 6 ] ; then
+ # Since at least ONE configuration error exists, then there
+ # is at least ONE unconfigured instance from the PKI point
+ # of view.
+ #
+ # However, it must still be considered that the
+ # instance is "running" from the point of view of other
+ # OS programs such as 'chkconfig'.
+ #
+ # Therefore, ignore non-zero return codes resulting
+ # from configuration errors.
+ #
+
+ config_errors=`expr $config_errors + 1`
+ rv=0
+ elif [ $rv != 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt ${errors} ] ; then
+ touch ${lockfile}
+ chmod 00600 ${lockfile}
+ fi
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ # NOTE: "bad" return code(s) OVERRIDE configuration errors!
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "1 generic or unspecified error (current practice)"
+ rv=1
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances failed to start!"
+ echo
+ fi
+
+ if [ ${TOTAL_UNCONFIGURED_PKI_ENTRIES} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${TOTAL_UNCONFIGURED_PKI_ENTRIES} "
+ echo -n "of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances MUST be configured!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED STARTING '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
+stop()
+{
+ error_rv=0
+ rv=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 5 program is not installed
+ return 5
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ echo "BEGIN SHUTTING DOWN '${PKI_TYPE}' INSTANCE(S):"
+ fi
+
+ # Shutdown every PKI instance of this type that is running
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ stop_instance
+ rv=$?
+ if [ $rv != 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ if [ ${errors} -eq 0 ] ; then
+ rm -f ${lockfile}
+ fi
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "1 generic or unspecified error (current practice)"
+ rv=1
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances were "
+ echo -n "unsuccessfully stopped!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED SHUTTING DOWN '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
+restart()
+{
+ stop
+ sleep 2
+ start
+
+ return $?
+}
+
+registry_status()
+{
+ error_rv=0
+ rv=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 4 program or service status is unknown
+ return 4
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ echo "REPORT STATUS OF '${PKI_TYPE}' INSTANCE(S):"
+ fi
+
+ # Obtain status of every PKI instance of this type
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ display_instance_status
+ rv=$?
+ if [ $rv -ne 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "4 - program or service status is unknown"
+ rv=4
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances reported status failures!"
+ echo
+ fi
+
+ if [ ${TOTAL_UNCONFIGURED_PKI_ENTRIES} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${TOTAL_UNCONFIGURED_PKI_ENTRIES} "
+ echo -n "of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances MUST be configured!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED REPORTING STATUS OF '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
diff --git a/pki/base/common/scripts/pki_apache_initscript b/pki/base/common/scripts/pki_apache_initscript
new file mode 100755
index 000000000..e51231065
--- /dev/null
+++ b/pki/base/common/scripts/pki_apache_initscript
@@ -0,0 +1,246 @@
+#!/bin/bash
+
+command="$1"
+
+# Source function library.
+. /etc/init.d/functions
+
+PKI_REGISTRY_FILE=[PKI_REGISTRY_FILE]
+
+# Enable nullglob, if set then shell pattern globs which do not match any
+# file returns the empty string rather than the unmodified glob pattern.
+shopt -s nullglob
+
+OS=`uname -s`
+ARCHITECTURE=`uname -i`
+
+# Source values associated with this particular PKI instance
+if [ -f $PKI_REGISTRY_FILE ]; then
+ . ${PKI_REGISTRY_FILE}
+else
+ echo "No PKI registry file ($PKI_REGISTRY_FILE)"
+ case $command in
+ status)
+ exit 4
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+fi
+
+prog=$PKI_INSTANCE_ID
+lockfile=$PKI_LOCK_FILE
+pidfile=$PKI_PID_FILE
+
+
+STARTUP_WAIT=30
+SHUTDOWN_WAIT=30
+
+start()
+{
+ rv=0
+
+ echo -n $"Starting ${prog}: "
+
+ if [ -f ${lockfile} ] ; then
+ if [ -f ${pidfile} ]; then
+ read kpid < ${pidfile}
+ if checkpid $kpid 2>&1; then
+ echo
+ echo "${PKI_INSTANCE_ID} (pid ${kpid}) is already running ..."
+ echo
+ return 0
+ else
+ echo
+ echo -n "lock file found but no process "
+ echo -n "running for pid $kpid, continuing"
+ echo
+ echo
+ rm -f ${lockfile}
+ fi
+ fi
+ fi
+
+ touch ${pidfile}
+ chown ${PKI_USER}:${PKI_GROUP} ${pidfile}
+ chmod 00600 ${pidfile}
+ [ -x /sbin/restorecon ] && /sbin/restorecon ${pidfile}
+
+ # restore context for ncipher hsm
+ [ -x /sbin/restorecon ] && [ -d /dev/nfast ] && /sbin/restorecon -R /dev/nfast
+
+ /usr/sbin/selinuxenabled
+ rv=$?
+ if [ ${rv} = 0 ] ; then
+ if [ ${ARCHITECTURE} = "i386" ] ; then
+ LANG=${PKI_HTTPD_LANG} daemon runcon -t ${PKI_SELINUX_TYPE} -- ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ # overwrite output from "daemon"
+ echo -n $"Starting ${prog}: "
+ elif [ ${ARCHITECTURE} = "x86_64" ] ; then
+ # NOTE: "daemon" is incompatible with "httpd" on 64-bit architectures
+ LANG=${PKI_HTTPD_LANG} runcon -t ${PKI_SELINUX_TYPE} -- ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ fi
+ else
+ LANG=${PKI_HTTPD_LANG} daemon ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ # overwrite output from "daemon"
+ echo -n $"Starting ${prog}: "
+ fi
+
+ if [ ${rv} = 0 ] ; then
+ touch ${lockfile}
+ chown ${PKI_USER}:${PKI_GROUP} ${lockfile}
+ chmod 00600 ${lockfile}
+
+ count=0;
+
+ let swait=$STARTUP_WAIT
+ until [ -s ${pidfile} ] ||
+ [ $count -gt $swait ]
+ do
+ echo -n "."
+ sleep 1
+ let count=$count+1;
+ done
+
+ echo_success
+ echo
+
+ # Set permissions of log files
+ for file in ${pki_logs_directory}/*; do
+ if [ `basename $file` != "signedAudit" ]; then
+ chown ${PKI_USER}:${PKI_GROUP} ${file}
+ chmod 00640 ${file}
+ fi
+ done
+
+ if [ -d ${pki_logs_directory}/signedAudit ]; then
+ for file in ${pki_logs_directory}/signedAudit/*; do
+ chown ${PKI_USER} ${file}
+ chmod 00640 ${file}
+ done
+ fi
+
+ else
+ echo_failure
+ echo
+ fi
+
+
+ return ${rv}
+}
+
+stop()
+{
+ rv=0
+
+ echo -n "Stopping ${prog}: "
+
+ if [ -f ${lockfile} ] ; then
+ ${httpd} ${PKI_OPTIONS} -k stop
+ rv=$?
+
+ if [ ${rv} = 0 ]; then
+ count=0;
+
+ if [ -f ${pidfile} ]; then
+ read kpid < ${pidfile}
+ let kwait=$SHUTDOWN_WAIT
+
+ until [ `ps -p $kpid | grep -c $kpid` = '0' ] ||
+ [ $count -gt $kwait ]
+ do
+ echo -n "."
+ sleep 1
+ let count=$count+1;
+ done
+
+ if [ $count -gt $kwait ]; then
+ kill -9 $kpid
+ fi
+ fi
+
+ rm -f ${lockfile}
+ rm -f ${pidfile}
+
+ echo_success
+ echo
+ else
+ echo_failure
+ echo
+ rv=${default_error}
+ fi
+ else
+ echo
+ echo "process already stopped"
+ rv=0
+ fi
+
+ return ${rv}
+}
+
+reload()
+{
+ rv=0
+
+ echo -n $"Reloading ${prog}: "
+
+ if ! LANG=${PKI_HTTPD_LANG} ${httpd} ${PKI_OPTIONS} -t >&/dev/null; then
+ rv=$?
+ echo $"not reloading due to configuration syntax error"
+ failure $"not reloading ${httpd} due to configuration syntax error"
+ else
+ killproc -p ${pidfile} ${httpd} -HUP
+ rv=$?
+ fi
+ echo
+
+ return ${rv}
+}
+
+instance_status()
+{
+ status -p ${pidfile} ${prog}
+ rv=$?
+ return $rv
+}
+
+# See how we were called.
+case $command in
+ status)
+ instance_status
+ exit $?
+ ;;
+ start)
+ start
+ exit $?
+ ;;
+ restart)
+ restart
+ exit $?
+ ;;
+ stop)
+ stop
+ exit $?
+ ;;
+ condrestart|force-restart|try-restart)
+ [ ! -f ${lockfile} ] || restart
+ exit $?
+ ;;
+ reload)
+ echo "The 'reload' action is an unimplemented feature."
+ exit 3
+ ;;
+ condrestart|force-restart|try-restart)
+ [ ! -f ${lockfile} ] || restart
+ exit $?
+ ;;
+ *)
+ echo "unknown action ($command)"
+ exit 2
+ ;;
+esac
+
diff --git a/pki/base/common/setup/CertServer.directory b/pki/base/common/setup/CertServer.directory
new file mode 100644
index 000000000..6d21bacb9
--- /dev/null
+++ b/pki/base/common/setup/CertServer.directory
@@ -0,0 +1,23 @@
+# --- 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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+[Desktop Entry]
+Name=CertServer
+Comment=Certificate Server
+Icon=
+Type=Directory
diff --git a/pki/base/common/setup/menu.xml b/pki/base/common/setup/menu.xml
new file mode 100644
index 000000000..562ea0261
--- /dev/null
+++ b/pki/base/common/setup/menu.xml
@@ -0,0 +1,10 @@
+ <!-- Certificate Server -->
+ <Menu>
+ <Name>CertificateServer</Name>
+ <Directory>CertServer.directory</Directory>
+ <Include>
+ <And>
+ <Category>CertServer</Category>
+ </And>
+ </Include>
+ </Menu> <!-- End Certificate Server -->
diff --git a/pki/base/common/setup/web-app_2_3.dtd b/pki/base/common/setup/web-app_2_3.dtd
new file mode 100644
index 000000000..5e3ab01c0
--- /dev/null
+++ b/pki/base/common/setup/web-app_2_3.dtd
@@ -0,0 +1,1063 @@
+<!--
+Copyright (c) 2000 Sun Microsystems, Inc.,
+901 San Antonio Road,
+Palo Alto, California 94303, U.S.A.
+All rights reserved.
+
+Sun Microsystems, Inc. has intellectual property rights relating to
+technology embodied in the product that is described in this document.
+In particular, and without limitation, these intellectual property
+rights may include one or more of the U.S. patents listed at
+http://www.sun.com/patents and one or more additional patents or
+pending patent applications in the U.S. and in other countries.
+
+This document and the product to which it pertains are distributed
+under licenses restricting their use, copying, distribution, and
+decompilation. This document may be reproduced and distributed but may
+not be changed without prior written authorization of Sun and its
+licensors, if any.
+
+Third-party software, including font technology, is copyrighted and
+licensed from Sun suppliers.
+
+Sun, Sun Microsystems, the Sun logo, Java, JavaServer Pages, Java
+Naming and Directory Interface, JDBC, JDK, JavaMail and and
+Enterprise JavaBeans are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the U.S. and other countries.
+
+Federal Acquisitions: Commercial Software - Government Users Subject to
+Standard License Terms and Conditions.
+
+DOCUMENTATION IS PROVIDED "AS IS" AND ALL EXPRESS OR IMPLIED
+CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED
+WARRANTY OF MERCHANTABILITY, FITNESS FOR FOR A PARTICULAR PURPOSE OR
+NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
+DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
+
+
+_________________________________________________________________________
+
+Copyright (c) 2000 Sun Microsystems, Inc.,
+901 San Antonio Road,
+Palo Alto, California 94303, E'tats-Unis.
+Tous droits re'serve's.
+
+Sun Microsystems, Inc. a les droits de proprie'te' intellectuels
+relatants a` la technologie incorpore'e dans le produit qui est de'crit
+dans ce document. En particulier, et sans la limitation, ces droits de
+proprie'te' intellectuels peuvent inclure un ou plus des brevets
+ame'ricains e'nume're's a` http://www.sun.com/patents et un ou les
+brevets plus supple'mentaires ou les applications de brevet en attente
+dans les E'tats-Unis et dans les autres pays.
+
+Ce produit ou document est prote'ge' par un copyright et distribue'
+avec des licences qui en restreignent l'utilisation, la copie, la
+distribution, et la de'compilation. Ce documention associe n peut
+e^tre reproduite et distribuer, par quelque moyen que ce soit, sans
+l'autorisation pre'alable et e'crite de Sun et de ses bailleurs de
+licence, le cas e'che'ant.
+
+Le logiciel de'tenu par des tiers, et qui comprend la technologie
+relative aux polices de caracte`res, est prote'ge' par un copyright et
+licencie' par des fournisseurs de Sun.
+
+Sun, Sun Microsystems, le logo Sun, Java, JavaServer Pages, Java
+Naming and Directory Interface, JDBC, JDK, JavaMail et and
+Enterprise JavaBeans sont des marques de fabrique ou des marques
+de'pose'es de Sun Microsystems, Inc. aux E'tats-Unis et dans d'autres
+pays.
+
+LA DOCUMENTATION EST FOURNIE "EN L'E'TAT" ET TOUTES AUTRES CONDITIONS,
+DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT FORMELLEMENT
+EXCLUES, DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE, Y COMPRIS
+NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE MARCHANDE, A
+L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE DE
+CONTREFAC,ON.
+-->
+
+<!--
+This is the XML DTD for the Servlet 2.3 deployment descriptor.
+All Servlet 2.3 deployment descriptors must include a DOCTYPE
+of the following form:
+
+ <!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+-->
+
+<!--
+The following conventions apply to all J2EE deployment descriptor
+elements unless indicated otherwise.
+
+- In elements that contain PCDATA, leading and trailing whitespace
+ in the data may be ignored.
+
+- In elements whose value is an "enumerated type", the value is
+ case sensitive.
+
+- In elements that specify a pathname to a file within the same
+ JAR file, relative filenames (i.e., those not starting with "/")
+ are considered relative to the root of the JAR file's namespace.
+ Absolute filenames (i.e., those starting with "/") also specify
+ names in the root of the JAR file's namespace. In general, relative
+ names are preferred. The exception is .war files where absolute
+ names are preferred for consistency with the servlet API.
+-->
+
+
+<!--
+The web-app element is the root of the deployment descriptor for
+a web application.
+-->
+<!ELEMENT web-app (icon?, display-name?, description?, distributable?,
+context-param*, filter*, filter-mapping*, listener*, servlet*,
+servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,
+error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,
+login-config?, security-role*, env-entry*, ejb-ref*, ejb-local-ref*)>
+
+<!--
+The auth-constraint element indicates the user roles that should
+be permitted access to this resource collection. The role-name
+used here must either correspond to the role-name of one of the
+security-role elements defined for this web application, or be
+the specially reserved role-name "*" that is a compact syntax for
+indicating all roles in the web application. If both "*" and
+rolenames appear, the container interprets this as all roles.
+If no roles are defined, no user is allowed access to the portion of
+the web application described by the containing security-constraint.
+The container matches role names case sensitively when determining
+access.
+
+
+Used in: security-constraint
+-->
+<!ELEMENT auth-constraint (description?, role-name*)>
+
+<!--
+The auth-method element is used to configure the authentication
+mechanism for the web application. As a prerequisite to gaining access to any web resources which are protected by an authorization
+constraint, a user must have authenticated using the configured
+mechanism. Legal values for this element are "BASIC", "DIGEST",
+"FORM", or "CLIENT-CERT".
+
+Used in: login-config
+-->
+<!ELEMENT auth-method (#PCDATA)>
+
+<!--
+The context-param element contains the declaration of a web
+application's servlet context initialization parameters.
+
+Used in: web-app
+-->
+<!ELEMENT context-param (param-name, param-value, description?)>
+
+<!--
+The description element is used to provide text describing the parent
+element. The description element should include any information that
+the web application war file producer wants to provide to the consumer of
+the web application war file (i.e., to the Deployer). Typically, the tools
+used by the web application war file consumer will display the description
+when processing the parent element that contains the description.
+
+Used in: auth-constraint, context-param, ejb-local-ref, ejb-ref,
+env-entry, filter, init-param, resource-env-ref, resource-ref, run-as,
+security-role, security-role-ref, servlet, user-data-constraint,
+web-app, web-resource-collection
+-->
+<!ELEMENT description (#PCDATA)>
+
+<!--
+The display-name element contains a short name that is intended to be
+displayed by tools. The display name need not be unique.
+
+Used in: filter, security-constraint, servlet, web-app
+
+Example:
+
+<display-name>Employee Self Service</display-name>
+-->
+<!ELEMENT display-name (#PCDATA)>
+
+<!--
+The distributable element, by its presence in a web application
+deployment descriptor, indicates that this web application is
+programmed appropriately to be deployed into a distributed servlet
+container
+
+Used in: web-app
+-->
+<!ELEMENT distributable EMPTY>
+
+<!--
+The ejb-link element is used in the ejb-ref or ejb-local-ref
+elements to specify that an EJB reference is linked to an
+enterprise bean.
+
+The name in the ejb-link element is composed of a
+path name specifying the ejb-jar containing the referenced enterprise
+bean with the ejb-name of the target bean appended and separated from
+the path name by "#". The path name is relative to the war file
+containing the web application that is referencing the enterprise bean.
+This allows multiple enterprise beans with the same ejb-name to be
+uniquely identified.
+
+Used in: ejb-local-ref, ejb-ref
+
+Examples:
+
+ <ejb-link>EmployeeRecord</ejb-link>
+
+ <ejb-link>../products/product.jar#ProductEJB</ejb-link>
+
+-->
+<!ELEMENT ejb-link (#PCDATA)>
+
+<!--
+The ejb-local-ref element is used for the declaration of a reference to
+an enterprise bean's local home. The declaration consists of:
+
+ - an optional description
+ - the EJB reference name used in the code of the web application
+ that's referencing the enterprise bean
+ - the expected type of the referenced enterprise bean
+ - the expected local home and local interfaces of the referenced
+ enterprise bean
+ - optional ejb-link information, used to specify the referenced
+ enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-local-ref (description?, ejb-ref-name, ejb-ref-type,
+ local-home, local, ejb-link?)>
+
+<!--
+The ejb-ref element is used for the declaration of a reference to
+an enterprise bean's home. The declaration consists of:
+
+ - an optional description
+ - the EJB reference name used in the code of
+ the web application that's referencing the enterprise bean
+ - the expected type of the referenced enterprise bean
+ - the expected home and remote interfaces of the referenced
+ enterprise bean
+ - optional ejb-link information, used to specify the referenced
+ enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-ref (description?, ejb-ref-name, ejb-ref-type,
+ home, remote, ejb-link?)>
+
+<!--
+The ejb-ref-name element contains the name of an EJB reference. The
+EJB reference is an entry in the web application's environment and is
+relative to the java:comp/env context. The name must be unique
+within the web application.
+
+It is recommended that name is prefixed with "ejb/".
+
+Used in: ejb-local-ref, ejb-ref
+
+Example:
+
+<ejb-ref-name>ejb/Payroll</ejb-ref-name>
+-->
+<!ELEMENT ejb-ref-name (#PCDATA)>
+
+<!--
+The ejb-ref-type element contains the expected type of the
+referenced enterprise bean.
+
+The ejb-ref-type element must be one of the following:
+
+ <ejb-ref-type>Entity</ejb-ref-type>
+ <ejb-ref-type>Session</ejb-ref-type>
+
+Used in: ejb-local-ref, ejb-ref
+-->
+<!ELEMENT ejb-ref-type (#PCDATA)>
+
+<!--
+The env-entry element contains the declaration of a web application's
+environment entry. The declaration consists of an optional
+description, the name of the environment entry, and an optional
+value. If a value is not specified, one must be supplied
+during deployment.
+-->
+<!ELEMENT env-entry (description?, env-entry-name, env-entry-value?,
+env-entry-type)>
+
+<!--
+The env-entry-name element contains the name of a web applications's
+environment entry. The name is a JNDI name relative to the
+java:comp/env context. The name must be unique within a web application.
+
+Example:
+
+<env-entry-name>minAmount</env-entry-name>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-name (#PCDATA)>
+
+<!--
+The env-entry-type element contains the fully-qualified Java type of
+the environment entry value that is expected by the web application's
+code.
+
+The following are the legal values of env-entry-type:
+
+ java.lang.Boolean
+ java.lang.Byte
+ java.lang.Character
+ java.lang.String
+ java.lang.Short
+ java.lang.Integer
+ java.lang.Long
+ java.lang.Float
+ java.lang.Double
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-type (#PCDATA)>
+
+<!--
+The env-entry-value element contains the value of a web application's
+environment entry. The value must be a String that is valid for the
+constructor of the specified type that takes a single String
+parameter, or for java.lang.Character, a single character.
+
+Example:
+
+<env-entry-value>100.00</env-entry-value>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-value (#PCDATA)>
+
+<!--
+The error-code contains an HTTP error code, ex: 404
+
+Used in: error-page
+-->
+<!ELEMENT error-code (#PCDATA)>
+
+<!--
+The error-page element contains a mapping between an error code
+or exception type to the path of a resource in the web application
+
+Used in: web-app
+-->
+<!ELEMENT error-page ((error-code | exception-type), location)>
+
+<!--
+The exception type contains a fully qualified class name of a
+Java exception type.
+
+Used in: error-page
+-->
+<!ELEMENT exception-type (#PCDATA)>
+
+<!--
+The extension element contains a string describing an
+extension. example: "txt"
+
+Used in: mime-mapping
+-->
+<!ELEMENT extension (#PCDATA)>
+
+<!--
+Declares a filter in the web application. The filter is mapped to
+either a servlet or a URL pattern in the filter-mapping element, using
+the filter-name value to reference. Filters can access the
+initialization parameters declared in the deployment descriptor at
+runtime via the FilterConfig interface.
+
+Used in: web-app
+-->
+<!ELEMENT filter (icon?, filter-name, display-name?, description?,
+filter-class, init-param*)>
+
+<!--
+The fully qualified classname of the filter.
+
+Used in: filter
+-->
+<!ELEMENT filter-class (#PCDATA)>
+
+<!--
+Declaration of the filter mappings in this web application. The
+container uses the filter-mapping declarations to decide which filters
+to apply to a request, and in what order. The container matches the
+request URI to a Servlet in the normal way. To determine which filters
+to apply it matches filter-mapping declarations either on servlet-name,
+or on url-pattern for each filter-mapping element, depending on which
+style is used. The order in which filters are invoked is the order in
+which filter-mapping declarations that match a request URI for a
+servlet appear in the list of filter-mapping elements.The filter-name
+value must be the value of the <filter-name> sub-elements of one of the
+<filter> declarations in the deployment descriptor.
+
+Used in: web-app
+-->
+<!ELEMENT filter-mapping (filter-name, (url-pattern | servlet-name))>
+
+<!--
+The logical name of the filter. This name is used to map the filter.
+Each filter name is unique within the web application.
+
+Used in: filter, filter-mapping
+-->
+<!ELEMENT filter-name (#PCDATA)>
+
+<!--
+The form-error-page element defines the location in the web app
+where the error page that is displayed when login is not successful
+can be found. The path begins with a leading / and is interpreted
+relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-error-page (#PCDATA)>
+
+<!--
+The form-login-config element specifies the login and error pages
+that should be used in form based login. If form based authentication
+is not used, these elements are ignored.
+
+Used in: login-config
+-->
+<!ELEMENT form-login-config (form-login-page, form-error-page)>
+
+<!--
+The form-login-page element defines the location in the web app
+where the page that can be used for login can be found. The path
+begins with a leading / and is interpreted relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-login-page (#PCDATA)>
+
+<!--
+The home element contains the fully-qualified name of the enterprise
+bean's home interface.
+
+Used in: ejb-ref
+
+Example:
+
+<home>com.aardvark.payroll.PayrollHome</home>
+-->
+<!ELEMENT home (#PCDATA)>
+
+<!--
+The http-method contains an HTTP method (GET | POST |...).
+
+Used in: web-resource-collection
+-->
+<!ELEMENT http-method (#PCDATA)>
+
+<!--
+The icon element contains small-icon and large-icon elements that
+specify the file names for small and a large GIF or JPEG icon images
+used to represent the parent element in a GUI tool.
+
+Used in: filter, servlet, web-app
+-->
+<!ELEMENT icon (small-icon?, large-icon?)>
+
+<!--
+The init-param element contains a name/value pair as an
+initialization param of the servlet
+
+Used in: filter, servlet
+-->
+<!ELEMENT init-param (param-name, param-value, description?)>
+
+<!--
+The jsp-file element contains the full path to a JSP file within
+the web application beginning with a `/'.
+
+Used in: servlet
+-->
+<!ELEMENT jsp-file (#PCDATA)>
+
+<!--
+The large-icon element contains the name of a file
+containing a large (32 x 32) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<large-icon>employee-service-icon32x32.jpg</large-icon>
+-->
+<!ELEMENT large-icon (#PCDATA)>
+
+<!--
+The listener element indicates the deployment properties for a web
+application listener bean.
+
+Used in: web-app
+-->
+<!ELEMENT listener (listener-class)>
+
+<!--
+The listener-class element declares a class in the application must be
+registered as a web application listener bean. The value is the fully qualified classname of the listener class.
+
+
+Used in: listener
+-->
+<!ELEMENT listener-class (#PCDATA)>
+
+<!--
+The load-on-startup element indicates that this servlet should be
+loaded (instantiated and have its init() called) on the startup
+of the web application. The optional contents of
+these element must be an integer indicating the order in which
+the servlet should be loaded. If the value is a negative integer,
+or the element is not present, the container is free to load the
+servlet whenever it chooses. If the value is a positive integer
+or 0, the container must load and initialize the servlet as the
+application is deployed. The container must guarantee that
+servlets marked with lower integers are loaded before servlets
+marked with higher integers. The container may choose the order
+of loading of servlets with the same load-on-start-up value.
+
+Used in: servlet
+-->
+<!ELEMENT load-on-startup (#PCDATA)>
+
+<!--
+
+The local element contains the fully-qualified name of the
+enterprise bean's local interface.
+
+Used in: ejb-local-ref
+
+-->
+<!ELEMENT local (#PCDATA)>
+
+<!--
+
+The local-home element contains the fully-qualified name of the
+enterprise bean's local home interface.
+
+Used in: ejb-local-ref
+-->
+<!ELEMENT local-home (#PCDATA)>
+
+<!--
+The location element contains the location of the resource in the web
+application relative to the root of the web application. The value of
+the location must have a leading `/'.
+
+Used in: error-page
+-->
+<!ELEMENT location (#PCDATA)>
+
+<!--
+The login-config element is used to configure the authentication
+method that should be used, the realm name that should be used for
+this application, and the attributes that are needed by the form login
+mechanism.
+
+Used in: web-app
+-->
+<!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>
+
+<!--
+The mime-mapping element defines a mapping between an extension
+and a mime type.
+
+Used in: web-app
+-->
+<!ELEMENT mime-mapping (extension, mime-type)>
+
+<!--
+The mime-type element contains a defined mime type. example:
+"text/plain"
+
+Used in: mime-mapping
+-->
+<!ELEMENT mime-type (#PCDATA)>
+
+<!--
+The param-name element contains the name of a parameter. Each parameter
+name must be unique in the web application.
+
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-name (#PCDATA)>
+
+<!--
+The param-value element contains the value of a parameter.
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-value (#PCDATA)>
+
+<!--
+The realm name element specifies the realm name to use in HTTP
+Basic authorization.
+
+Used in: login-config
+-->
+<!ELEMENT realm-name (#PCDATA)>
+
+<!--
+The remote element contains the fully-qualified name of the enterprise
+bean's remote interface.
+
+Used in: ejb-ref
+
+Example:
+
+<remote>com.wombat.empl.EmployeeService</remote>
+-->
+<!ELEMENT remote (#PCDATA)>
+
+<!--
+The res-auth element specifies whether the web application code signs
+on programmatically to the resource manager, or whether the Container
+will sign on to the resource manager on behalf of the web application. In the
+latter case, the Container uses information that is supplied by the
+Deployer.
+
+The value of this element must be one of the two following:
+
+ <res-auth>Application</res-auth>
+ <res-auth>Container</res-auth>
+
+Used in: resource-ref
+-->
+<!ELEMENT res-auth (#PCDATA)>
+
+<!--
+The res-ref-name element specifies the name of a resource manager
+connection factory reference. The name is a JNDI name relative to the
+java:comp/env context. The name must be unique within a web application.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-ref-name (#PCDATA)>
+
+<!--
+The res-sharing-scope element specifies whether connections obtained
+through the given resource manager connection factory reference can be
+shared. The value of this element, if specified, must be one of the
+two following:
+
+ <res-sharing-scope>Shareable</res-sharing-scope>
+ <res-sharing-scope>Unshareable</res-sharing-scope>
+
+The default value is Shareable.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-sharing-scope (#PCDATA)>
+
+<!--
+The res-type element specifies the type of the data source. The type
+is specified by the fully qualified Java language class or interface
+expected to be implemented by the data source.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-type (#PCDATA)>
+
+<!--
+The resource-env-ref element contains a declaration of a web application's
+reference to an administered object associated with a resource
+in the web application's environment. It consists of an optional
+description, the resource environment reference name, and an
+indication of the resource environment reference type expected by
+the web application code.
+
+Used in: web-app
+
+Example:
+
+<resource-env-ref>
+ <resource-env-ref-name>jms/StockQueue</resource-env-ref-name>
+ <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
+</resource-env-ref>
+-->
+<!ELEMENT resource-env-ref (description?, resource-env-ref-name,
+ resource-env-ref-type)>
+
+<!--
+The resource-env-ref-name element specifies the name of a resource
+environment reference; its value is the environment entry name used in
+the web application code. The name is a JNDI name relative to the
+java:comp/env context and must be unique within a web application.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-name (#PCDATA)>
+
+<!--
+The resource-env-ref-type element specifies the type of a resource
+environment reference. It is the fully qualified name of a Java
+language class or interface.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-type (#PCDATA)>
+
+<!--
+The resource-ref element contains a declaration of a web application's
+reference to an external resource. It consists of an optional
+description, the resource manager connection factory reference name,
+the indication of the resource manager connection factory type
+expected by the web application code, the type of authentication
+(Application or Container), and an optional specification of the
+shareability of connections obtained from the resource (Shareable or
+Unshareable).
+
+Used in: web-app
+
+Example:
+
+ <resource-ref>
+ <res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
+ <res-type>javax.sql.DataSource</res-type>
+ <res-auth>Container</res-auth>
+ <res-sharing-scope>Shareable</res-sharing-scope>
+ </resource-ref>
+-->
+<!ELEMENT resource-ref (description?, res-ref-name, res-type, res-auth,
+ res-sharing-scope?)>
+
+<!--
+The role-link element is a reference to a defined security role. The
+role-link element must contain the name of one of the security roles
+defined in the security-role elements.
+
+Used in: security-role-ref
+-->
+<!ELEMENT role-link (#PCDATA)>
+
+<!--
+The role-name element contains the name of a security role.
+
+The name must conform to the lexical rules for an NMTOKEN.
+
+Used in: auth-constraint, run-as, security-role, security-role-ref
+-->
+<!ELEMENT role-name (#PCDATA)>
+
+<!--
+The run-as element specifies the run-as identity to be used for the
+execution of the web application. It contains an optional description, and
+the name of a security role.
+
+Used in: servlet
+-->
+<!ELEMENT run-as (description?, role-name)>
+
+<!--
+The security-constraint element is used to associate security
+constraints with one or more web resource collections
+
+Used in: web-app
+-->
+<!ELEMENT security-constraint (display-name?, web-resource-collection+,
+auth-constraint?, user-data-constraint?)>
+
+<!--
+The security-role element contains the definition of a security
+role. The definition consists of an optional description of the
+security role, and the security role name.
+
+Used in: web-app
+
+Example:
+
+ <security-role>
+ <description>
+ This role includes all employees who are authorized
+ to access the employee service application.
+ </description>
+ <role-name>employee</role-name>
+ </security-role>
+-->
+<!ELEMENT security-role (description?, role-name)>
+
+<!--
+The security-role-ref element contains the declaration of a security
+role reference in the web application's code. The declaration consists
+of an optional description, the security role name used in the code,
+and an optional link to a security role. If the security role is not
+specified, the Deployer must choose an appropriate security role.
+
+The value of the role-name element must be the String used as the
+parameter to the EJBContext.isCallerInRole(String roleName) method
+or the HttpServletRequest.isUserInRole(String role) method.
+
+Used in: servlet
+
+-->
+<!ELEMENT security-role-ref (description?, role-name, role-link?)>
+
+<!--
+The servlet element contains the declarative data of a
+servlet. If a jsp-file is specified and the load-on-startup element is
+present, then the JSP should be precompiled and loaded.
+
+Used in: web-app
+-->
+<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,
+(servlet-class|jsp-file), init-param*, load-on-startup?, run-as?, security-role-ref*)>
+
+<!--
+The servlet-class element contains the fully qualified class name
+of the servlet.
+
+Used in: servlet
+-->
+<!ELEMENT servlet-class (#PCDATA)>
+
+<!--
+The servlet-mapping element defines a mapping between a servlet
+and a url pattern
+
+Used in: web-app
+-->
+<!ELEMENT servlet-mapping (servlet-name, url-pattern)>
+
+<!--
+The servlet-name element contains the canonical name of the
+servlet. Each servlet name is unique within the web application.
+
+Used in: filter-mapping, servlet, servlet-mapping
+-->
+<!ELEMENT servlet-name (#PCDATA)>
+
+<!--
+The session-config element defines the session parameters for
+this web application.
+
+Used in: web-app
+-->
+<!ELEMENT session-config (session-timeout?)>
+
+<!--
+The session-timeout element defines the default session timeout
+interval for all sessions created in this web application. The
+specified timeout must be expressed in a whole number of minutes.
+If the timeout is 0 or less, the container ensures the default
+behaviour of sessions is never to time out.
+
+Used in: session-config
+-->
+<!ELEMENT session-timeout (#PCDATA)>
+
+<!--
+The small-icon element contains the name of a file
+containing a small (16 x 16) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<small-icon>employee-service-icon16x16.jpg</small-icon>
+-->
+<!ELEMENT small-icon (#PCDATA)>
+
+<!--
+The taglib element is used to describe a JSP tag library.
+
+Used in: web-app
+-->
+<!ELEMENT taglib (taglib-uri, taglib-location)>
+
+<!--
+the taglib-location element contains the location (as a resource
+relative to the root of the web application) where to find the Tag
+Libary Description file for the tag library.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-location (#PCDATA)>
+
+<!--
+The taglib-uri element describes a URI, relative to the location
+of the web.xml document, identifying a Tag Library used in the Web
+Application.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-uri (#PCDATA)>
+
+<!--
+The transport-guarantee element specifies that the communication
+between client and server should be NONE, INTEGRAL, or
+CONFIDENTIAL. NONE means that the application does not require any
+transport guarantees. A value of INTEGRAL means that the application
+requires that the data sent between the client and server be sent in
+such a way that it can't be changed in transit. CONFIDENTIAL means
+that the application requires that the data be transmitted in a
+fashion that prevents other entities from observing the contents of
+the transmission. In most cases, the presence of the INTEGRAL or
+CONFIDENTIAL flag will indicate that the use of SSL is required.
+
+Used in: user-data-constraint
+-->
+<!ELEMENT transport-guarantee (#PCDATA)>
+
+<!--
+The url-pattern element contains the url pattern of the mapping. Must
+follow the rules specified in Section 11.2 of the Servlet API
+Specification.
+
+Used in: filter-mapping, servlet-mapping, web-resource-collection
+-->
+<!ELEMENT url-pattern (#PCDATA)>
+
+<!--
+The user-data-constraint element is used to indicate how data
+communicated between the client and container should be protected.
+
+Used in: security-constraint
+-->
+<!ELEMENT user-data-constraint (description?, transport-guarantee)>
+
+<!--
+The web-resource-collection element is used to identify a subset
+of the resources and HTTP methods on those resources within a web
+application to which a security constraint applies. If no HTTP methods
+are specified, then the security constraint applies to all HTTP
+methods.
+
+Used in: security-constraint
+-->
+<!ELEMENT web-resource-collection (web-resource-name, description?,
+url-pattern*, http-method*)>
+
+<!--
+The web-resource-name contains the name of this web resource
+collection.
+
+Used in: web-resource-collection
+-->
+<!ELEMENT web-resource-name (#PCDATA)>
+
+<!--
+The welcome-file element contains file name to use as a default
+welcome file, such as index.html
+
+Used in: welcome-file-list
+-->
+<!ELEMENT welcome-file (#PCDATA)>
+
+<!--
+The welcome-file-list contains an ordered list of welcome files
+elements.
+
+Used in: web-app
+-->
+<!ELEMENT welcome-file-list (welcome-file+)>
+
+<!--
+The ID mechanism is to allow tools that produce additional deployment
+information (i.e., information beyond the standard deployment
+descriptor information) to store the non-standard information in a
+separate file, and easily refer from these tool-specific files to the
+information in the standard deployment descriptor.
+
+Tools are not allowed to add the non-standard information into the
+standard deployment descriptor.
+-->
+
+<!ATTLIST auth-constraint id ID #IMPLIED>
+<!ATTLIST auth-method id ID #IMPLIED>
+<!ATTLIST context-param id ID #IMPLIED>
+<!ATTLIST description id ID #IMPLIED>
+<!ATTLIST display-name id ID #IMPLIED>
+<!ATTLIST distributable id ID #IMPLIED>
+<!ATTLIST ejb-link id ID #IMPLIED>
+<!ATTLIST ejb-local-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref-name id ID #IMPLIED>
+<!ATTLIST ejb-ref-type id ID #IMPLIED>
+<!ATTLIST env-entry id ID #IMPLIED>
+<!ATTLIST env-entry-name id ID #IMPLIED>
+<!ATTLIST env-entry-type id ID #IMPLIED>
+<!ATTLIST env-entry-value id ID #IMPLIED>
+<!ATTLIST error-code id ID #IMPLIED>
+<!ATTLIST error-page id ID #IMPLIED>
+<!ATTLIST exception-type id ID #IMPLIED>
+<!ATTLIST extension id ID #IMPLIED>
+<!ATTLIST filter id ID #IMPLIED>
+<!ATTLIST filter-class id ID #IMPLIED>
+<!ATTLIST filter-mapping id ID #IMPLIED>
+<!ATTLIST filter-name id ID #IMPLIED>
+<!ATTLIST form-error-page id ID #IMPLIED>
+<!ATTLIST form-login-config id ID #IMPLIED>
+<!ATTLIST form-login-page id ID #IMPLIED>
+<!ATTLIST home id ID #IMPLIED>
+<!ATTLIST http-method id ID #IMPLIED>
+<!ATTLIST icon id ID #IMPLIED>
+<!ATTLIST init-param id ID #IMPLIED>
+<!ATTLIST jsp-file id ID #IMPLIED>
+<!ATTLIST large-icon id ID #IMPLIED>
+<!ATTLIST listener id ID #IMPLIED>
+<!ATTLIST listener-class id ID #IMPLIED>
+<!ATTLIST load-on-startup id ID #IMPLIED>
+<!ATTLIST local id ID #IMPLIED>
+<!ATTLIST local-home id ID #IMPLIED>
+<!ATTLIST location id ID #IMPLIED>
+<!ATTLIST login-config id ID #IMPLIED>
+<!ATTLIST mime-mapping id ID #IMPLIED>
+<!ATTLIST mime-type id ID #IMPLIED>
+<!ATTLIST param-name id ID #IMPLIED>
+<!ATTLIST param-value id ID #IMPLIED>
+<!ATTLIST realm-name id ID #IMPLIED>
+<!ATTLIST remote id ID #IMPLIED>
+<!ATTLIST res-auth id ID #IMPLIED>
+<!ATTLIST res-ref-name id ID #IMPLIED>
+<!ATTLIST res-sharing-scope id ID #IMPLIED>
+<!ATTLIST res-type id ID #IMPLIED>
+<!ATTLIST resource-env-ref id ID #IMPLIED>
+<!ATTLIST resource-env-ref-name id ID #IMPLIED>
+<!ATTLIST resource-env-ref-type id ID #IMPLIED>
+<!ATTLIST resource-ref id ID #IMPLIED>
+<!ATTLIST role-link id ID #IMPLIED>
+<!ATTLIST role-name id ID #IMPLIED>
+<!ATTLIST run-as id ID #IMPLIED>
+<!ATTLIST security-constraint id ID #IMPLIED>
+<!ATTLIST security-role id ID #IMPLIED>
+<!ATTLIST security-role-ref id ID #IMPLIED>
+<!ATTLIST servlet id ID #IMPLIED>
+<!ATTLIST servlet-class id ID #IMPLIED>
+<!ATTLIST servlet-mapping id ID #IMPLIED>
+<!ATTLIST servlet-name id ID #IMPLIED>
+<!ATTLIST session-config id ID #IMPLIED>
+<!ATTLIST session-timeout id ID #IMPLIED>
+<!ATTLIST small-icon id ID #IMPLIED>
+<!ATTLIST taglib id ID #IMPLIED>
+<!ATTLIST taglib-location id ID #IMPLIED>
+<!ATTLIST taglib-uri id ID #IMPLIED>
+<!ATTLIST transport-guarantee id ID #IMPLIED>
+<!ATTLIST url-pattern id ID #IMPLIED>
+<!ATTLIST user-data-constraint id ID #IMPLIED>
+<!ATTLIST web-app id ID #IMPLIED>
+<!ATTLIST web-resource-collection id ID #IMPLIED>
+<!ATTLIST web-resource-name id ID #IMPLIED>
+<!ATTLIST welcome-file id ID #IMPLIED>
+<!ATTLIST welcome-file-list id ID #IMPLIED>
diff --git a/pki/base/common/src/CMakeLists.txt b/pki/base/common/src/CMakeLists.txt
new file mode 100644
index 000000000..2df82b8bb
--- /dev/null
+++ b/pki/base/common/src/CMakeLists.txt
@@ -0,0 +1,1037 @@
+project(pki-certsrv_java Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(OSUTIL_JAR
+ NAMES
+ osutil.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(SERVLET_JAR
+ NAMES
+ servlet.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(VELOCITY_JAR
+ NAMES
+ velocity.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(XALAN_JAR
+ NAMES
+ xalan-j2.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ /usr/lib/java
+ /usr/share/java
+)
+
+set(pki-certsrv_java_SRCS
+ com/netscape/certsrv/apps/ICommandQueue.java
+ com/netscape/certsrv/apps/CMS.java
+ com/netscape/certsrv/apps/ICMSEngine.java
+ com/netscape/certsrv/ldap/ILdapBoundConnFactory.java
+ com/netscape/certsrv/ldap/ILdapConnFactory.java
+ com/netscape/certsrv/ldap/ELdapException.java
+ com/netscape/certsrv/ldap/ILdapConnInfo.java
+ com/netscape/certsrv/ldap/ELdapServerDownException.java
+ com/netscape/certsrv/ldap/ILdapAuthInfo.java
+ com/netscape/certsrv/ldap/LdapResources.java
+ com/netscape/certsrv/ldap/ILdapConnModule.java
+ com/netscape/certsrv/listeners/ListenersResources.java
+ com/netscape/certsrv/listeners/IRequestListenerPlugin.java
+ com/netscape/certsrv/listeners/EListenersException.java
+ com/netscape/certsrv/common/TaskId.java
+ com/netscape/certsrv/common/DestDef.java
+ com/netscape/certsrv/common/NameValuePairs.java
+ com/netscape/certsrv/common/ScopeDef.java
+ com/netscape/certsrv/common/PrefixDef.java
+ com/netscape/certsrv/common/ConfigConstants.java
+ com/netscape/certsrv/common/NameValuePair.java
+ com/netscape/certsrv/common/OpDef.java
+ com/netscape/certsrv/common/Constants.java
+ com/netscape/certsrv/usrgrp/EUsrGrpException.java
+ com/netscape/certsrv/usrgrp/IGroupConstants.java
+ com/netscape/certsrv/usrgrp/Certificates.java
+ com/netscape/certsrv/usrgrp/ICertUserLocator.java
+ com/netscape/certsrv/usrgrp/IGroup.java
+ com/netscape/certsrv/usrgrp/IUser.java
+ com/netscape/certsrv/usrgrp/IUGSubsystem.java
+ com/netscape/certsrv/usrgrp/IIdEvaluator.java
+ com/netscape/certsrv/usrgrp/UsrGrpResources.java
+ com/netscape/certsrv/usrgrp/IUserConstants.java
+ com/netscape/certsrv/usrgrp/IUsrGrp.java
+ com/netscape/certsrv/pattern/Pattern.java
+ com/netscape/certsrv/pattern/AttrSetCollection.java
+ com/netscape/certsrv/publish/ILdapPlugin.java
+ com/netscape/certsrv/publish/ECompSyntaxErr.java
+ com/netscape/certsrv/publish/ERuleNotFound.java
+ com/netscape/certsrv/publish/ILdapPublishModule.java
+ com/netscape/certsrv/publish/EMapperPluginNotFound.java
+ com/netscape/certsrv/publish/RulePlugin.java
+ com/netscape/certsrv/publish/EPublisherNotFound.java
+ com/netscape/certsrv/publish/MapperPlugin.java
+ com/netscape/certsrv/publish/EPublisherPluginNotFound.java
+ com/netscape/certsrv/publish/IXcertPublisherProcessor.java
+ com/netscape/certsrv/publish/PublisherProxy.java
+ com/netscape/certsrv/publish/ICRLPublisher.java
+ com/netscape/certsrv/publish/ILdapPublisher.java
+ com/netscape/certsrv/publish/EMapperNotFound.java
+ com/netscape/certsrv/publish/ILdapPluginImpl.java
+ com/netscape/certsrv/publish/ILdapRule.java
+ com/netscape/certsrv/publish/IPublisherProcessor.java
+ com/netscape/certsrv/publish/LdapCertMapResult.java
+ com/netscape/certsrv/publish/IPublishRuleSet.java
+ com/netscape/certsrv/publish/ILdapExpression.java
+ com/netscape/certsrv/publish/ILdapCertMapper.java
+ com/netscape/certsrv/publish/ILdapMapper.java
+ com/netscape/certsrv/publish/PublisherPlugin.java
+ com/netscape/certsrv/publish/ERulePluginNotFound.java
+ com/netscape/certsrv/publish/MapperProxy.java
+ com/netscape/certsrv/publish/ILdapCrlMapper.java
+ com/netscape/certsrv/util/IStatsSubsystem.java
+ com/netscape/certsrv/util/HttpInput.java
+ com/netscape/certsrv/util/StatsEvent.java
+ com/netscape/certsrv/policy/IGeneralNameUtil.java
+ com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java
+ com/netscape/certsrv/policy/IExpression.java
+ com/netscape/certsrv/policy/EPolicyException.java
+ com/netscape/certsrv/policy/PolicyResources.java
+ com/netscape/certsrv/policy/IGeneralNamesConfig.java
+ com/netscape/certsrv/policy/IPolicySet.java
+ com/netscape/certsrv/policy/IPolicyProcessor.java
+ com/netscape/certsrv/policy/IKeyRecoveryPolicy.java
+ com/netscape/certsrv/policy/IGeneralNameConfig.java
+ com/netscape/certsrv/policy/IPolicyPredicateParser.java
+ com/netscape/certsrv/policy/IKeyArchivalPolicy.java
+ com/netscape/certsrv/policy/IRevocationPolicy.java
+ com/netscape/certsrv/policy/ISubjAltNameConfig.java
+ com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java
+ com/netscape/certsrv/policy/IEnrollmentPolicy.java
+ com/netscape/certsrv/policy/IRenewalPolicy.java
+ com/netscape/certsrv/policy/IPolicyRule.java
+ com/netscape/certsrv/acls/IACL.java
+ com/netscape/certsrv/acls/ACLsResources.java
+ com/netscape/certsrv/acls/EACLsException.java
+ com/netscape/certsrv/acls/ACL.java
+ com/netscape/certsrv/acls/IACLEntry.java
+ com/netscape/certsrv/acls/ACLEntry.java
+ com/netscape/certsrv/cert/ICrossCertPairSubsystem.java
+ com/netscape/certsrv/registry/IPluginInfo.java
+ com/netscape/certsrv/registry/ERegistryException.java
+ com/netscape/certsrv/registry/IPluginRegistry.java
+ com/netscape/certsrv/base/EPropertyNotDefined.java
+ com/netscape/certsrv/base/MessageFormatter.java
+ com/netscape/certsrv/base/MetaInfo.java
+ com/netscape/certsrv/base/ITimeSource.java
+ com/netscape/certsrv/base/AttributeNameHelper.java
+ com/netscape/certsrv/base/ISourceConfigStore.java
+ com/netscape/certsrv/base/PasswordResources.java
+ com/netscape/certsrv/base/ASubsystem.java
+ com/netscape/certsrv/base/IArgBlock.java
+ com/netscape/certsrv/base/SessionContext.java
+ com/netscape/certsrv/base/IExtPrettyPrint.java
+ com/netscape/certsrv/base/IConfigStoreEventListener.java
+ com/netscape/certsrv/base/Plugin.java
+ com/netscape/certsrv/base/IConfigStore.java
+ com/netscape/certsrv/base/EPropertyNotFound.java
+ com/netscape/certsrv/base/ISubsystem.java
+ com/netscape/certsrv/base/ISubsystemSource.java
+ com/netscape/certsrv/base/IPrettyPrintFormat.java
+ com/netscape/certsrv/base/MetaAttributeDef.java
+ com/netscape/certsrv/base/IAuthInfo.java
+ com/netscape/certsrv/base/ExtendedPluginInfo.java
+ com/netscape/certsrv/base/EBaseException.java
+ com/netscape/certsrv/base/Nonces.java
+ com/netscape/certsrv/base/ISecurityDomainSessionTable.java
+ com/netscape/certsrv/base/IExtendedPluginInfo.java
+ com/netscape/certsrv/base/KeyGenInfo.java
+ com/netscape/certsrv/base/BaseResources.java
+ com/netscape/certsrv/base/IPluginImpl.java
+ com/netscape/certsrv/base/IAttrSet.java
+ com/netscape/certsrv/base/ICRLPrettyPrint.java
+ com/netscape/certsrv/base/ICertPrettyPrint.java
+ com/netscape/certsrv/dbs/IDBRegistry.java
+ com/netscape/certsrv/dbs/IDBAttrMapper.java
+ com/netscape/certsrv/dbs/IElementProcessor.java
+ com/netscape/certsrv/dbs/Modification.java
+ com/netscape/certsrv/dbs/EDBNotAvailException.java
+ com/netscape/certsrv/dbs/IDBVirtualList.java
+ com/netscape/certsrv/dbs/keydb/KeyState.java
+ com/netscape/certsrv/dbs/keydb/IKeyRecord.java
+ com/netscape/certsrv/dbs/keydb/IKeyRecordList.java
+ com/netscape/certsrv/dbs/keydb/IKeyRepository.java
+ com/netscape/certsrv/dbs/crldb/ICRLRepository.java
+ com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java
+ com/netscape/certsrv/dbs/EDBException.java
+ com/netscape/certsrv/dbs/certdb/ICertRecordList.java
+ com/netscape/certsrv/dbs/certdb/ICertificateRepository.java
+ com/netscape/certsrv/dbs/certdb/IRevocationInfo.java
+ com/netscape/certsrv/dbs/certdb/ICertRecord.java
+ com/netscape/certsrv/dbs/DBResources.java
+ com/netscape/certsrv/dbs/IDBSearchResults.java
+ com/netscape/certsrv/dbs/IFilterConverter.java
+ com/netscape/certsrv/dbs/ModificationSet.java
+ com/netscape/certsrv/dbs/IDBDynAttrMapper.java
+ com/netscape/certsrv/dbs/IDBSubsystem.java
+ com/netscape/certsrv/dbs/repository/IRepository.java
+ com/netscape/certsrv/dbs/repository/IRepositoryRecord.java
+ com/netscape/certsrv/dbs/IDBObj.java
+ com/netscape/certsrv/dbs/EDBRecordNotFoundException.java
+ com/netscape/certsrv/dbs/IDBSSession.java
+ com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java
+ com/netscape/certsrv/kra/IShare.java
+ com/netscape/certsrv/kra/EKRAException.java
+ com/netscape/certsrv/kra/ProofOfArchival.java
+ com/netscape/certsrv/kra/IKeyService.java
+ com/netscape/certsrv/kra/IJoinShares.java
+ com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
+ com/netscape/certsrv/kra/IProofOfArchival.java
+ com/netscape/certsrv/kra/KRAResources.java
+ com/netscape/certsrv/authentication/ISharedToken.java
+ com/netscape/certsrv/authentication/AuthMgrPlugin.java
+ com/netscape/certsrv/authentication/EInvalidCredentials.java
+ com/netscape/certsrv/authentication/EAuthMgrNotFound.java
+ com/netscape/certsrv/authentication/ECompSyntaxErr.java
+ com/netscape/certsrv/authentication/EAuthUserError.java
+ com/netscape/certsrv/authentication/IAuthToken.java
+ com/netscape/certsrv/authentication/EAuthInternalError.java
+ com/netscape/certsrv/authentication/IAuthManager.java
+ com/netscape/certsrv/authentication/AuthManagerProxy.java
+ com/netscape/certsrv/authentication/AuthToken.java
+ com/netscape/certsrv/authentication/AuthCredentials.java
+ com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java
+ com/netscape/certsrv/authentication/ISSLClientCertProvider.java
+ com/netscape/certsrv/authentication/EMissingCredential.java
+ com/netscape/certsrv/authentication/EAuthException.java
+ com/netscape/certsrv/authentication/IAuthSubsystem.java
+ com/netscape/certsrv/authentication/IAuthCredentials.java
+ com/netscape/certsrv/authentication/AuthResources.java
+ com/netscape/certsrv/authentication/EFormSubjectDN.java
+ com/netscape/certsrv/authorization/AuthzManagerProxy.java
+ com/netscape/certsrv/authorization/IAuthzManager.java
+ com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java
+ com/netscape/certsrv/authorization/AuthzMgrPlugin.java
+ com/netscape/certsrv/authorization/AuthzToken.java
+ com/netscape/certsrv/authorization/IAuthzSubsystem.java
+ com/netscape/certsrv/authorization/AuthzResources.java
+ com/netscape/certsrv/authorization/EAuthzUnknownOperation.java
+ com/netscape/certsrv/authorization/EAuthzAccessDenied.java
+ com/netscape/certsrv/authorization/EAuthzException.java
+ com/netscape/certsrv/authorization/EAuthzMgrNotFound.java
+ com/netscape/certsrv/authorization/EAuthzInternalError.java
+ com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java
+ com/netscape/certsrv/extensions/ICMSExtension.java
+ com/netscape/certsrv/extensions/ExtensionsResources.java
+ com/netscape/certsrv/extensions/EExtensionsException.java
+ com/netscape/certsrv/authority/ICertAuthority.java
+ com/netscape/certsrv/authority/IAuthority.java
+ com/netscape/certsrv/template/IArgValue.java
+ com/netscape/certsrv/template/ArgString.java
+ com/netscape/certsrv/template/ArgSet.java
+ com/netscape/certsrv/template/ArgList.java
+ com/netscape/certsrv/ra/IRAService.java
+ com/netscape/certsrv/ra/IRegistrationAuthority.java
+ com/netscape/certsrv/password/IPasswordCheck.java
+ com/netscape/certsrv/password/IConfigPasswordCheck.java
+ com/netscape/certsrv/password/EPasswordCheckException.java
+ com/netscape/certsrv/jobs/JobPlugin.java
+ com/netscape/certsrv/jobs/IJob.java
+ com/netscape/certsrv/jobs/EJobsException.java
+ com/netscape/certsrv/jobs/IJobCron.java
+ com/netscape/certsrv/jobs/JobsResources.java
+ com/netscape/certsrv/jobs/IJobsScheduler.java
+ com/netscape/certsrv/selftests/ESelfTestException.java
+ com/netscape/certsrv/selftests/EMissingSelfTestException.java
+ com/netscape/certsrv/selftests/EInvalidSelfTestException.java
+ com/netscape/certsrv/selftests/ISelfTest.java
+ com/netscape/certsrv/selftests/SelfTestResources.java
+ com/netscape/certsrv/selftests/ISelfTestSubsystem.java
+ com/netscape/certsrv/selftests/EDuplicateSelfTestException.java
+ com/netscape/certsrv/request/ldap/IRequestMod.java
+ com/netscape/certsrv/request/IRequestNotifier.java
+ com/netscape/certsrv/request/IRequestSubsystem.java
+ com/netscape/certsrv/request/PolicyResult.java
+ com/netscape/certsrv/request/INotify.java
+ com/netscape/certsrv/request/IRequestList.java
+ com/netscape/certsrv/request/IEnrollmentRequest.java
+ com/netscape/certsrv/request/AgentApprovals.java
+ com/netscape/certsrv/request/IRequestRecord.java
+ com/netscape/certsrv/request/RequestId.java
+ com/netscape/certsrv/request/IService.java
+ com/netscape/certsrv/request/IRequestListener.java
+ com/netscape/certsrv/request/AgentApproval.java
+ com/netscape/certsrv/request/RequestStatus.java
+ com/netscape/certsrv/request/IRequestScheduler.java
+ com/netscape/certsrv/request/IRequest.java
+ com/netscape/certsrv/request/IRequestQueue.java
+ com/netscape/certsrv/request/ARequestNotifier.java
+ com/netscape/certsrv/request/PolicyMessage.java
+ com/netscape/certsrv/request/IPolicy.java
+ com/netscape/certsrv/request/IRequestVirtualList.java
+ com/netscape/certsrv/evaluators/IAccessEvaluator.java
+ com/netscape/certsrv/tks/ITKSAuthority.java
+ com/netscape/certsrv/property/EPropertyException.java
+ com/netscape/certsrv/property/PropertySet.java
+ com/netscape/certsrv/property/IConfigTemplate.java
+ com/netscape/certsrv/property/IDescriptor.java
+ com/netscape/certsrv/property/Descriptor.java
+ com/netscape/certsrv/logging/LogResources.java
+ com/netscape/certsrv/logging/ConsoleError.java
+ com/netscape/certsrv/logging/ILogEventFactory.java
+ com/netscape/certsrv/logging/SignedAuditEvent.java
+ com/netscape/certsrv/logging/SystemEvent.java
+ com/netscape/certsrv/logging/AuditFormat.java
+ com/netscape/certsrv/logging/AuditEvent.java
+ com/netscape/certsrv/logging/ELogNotFound.java
+ com/netscape/certsrv/logging/ILogEvent.java
+ com/netscape/certsrv/logging/ELogException.java
+ com/netscape/certsrv/logging/ConsoleLog.java
+ com/netscape/certsrv/logging/LogPlugin.java
+ com/netscape/certsrv/logging/ILogSubsystem.java
+ com/netscape/certsrv/logging/IBundleLogEvent.java
+ com/netscape/certsrv/logging/ELogPluginNotFound.java
+ com/netscape/certsrv/logging/ILogger.java
+ com/netscape/certsrv/logging/ILogQueue.java
+ com/netscape/certsrv/logging/ILogEventListener.java
+ com/netscape/certsrv/ca/ICMSCRLExtensions.java
+ com/netscape/certsrv/ca/ICertificateAuthority.java
+ com/netscape/certsrv/ca/EErrorPublishCRL.java
+ com/netscape/certsrv/ca/ICAService.java
+ com/netscape/certsrv/ca/ECAException.java
+ com/netscape/certsrv/ca/ICMSCRLExtension.java
+ com/netscape/certsrv/ca/ICRLIssuingPoint.java
+ com/netscape/certsrv/ca/CAResources.java
+ com/netscape/certsrv/connector/IConnector.java
+ com/netscape/certsrv/connector/IHttpConnFactory.java
+ com/netscape/certsrv/connector/IPKIMessage.java
+ com/netscape/certsrv/connector/IRequestEncoder.java
+ com/netscape/certsrv/connector/IResender.java
+ com/netscape/certsrv/connector/IHttpPKIMessage.java
+ com/netscape/certsrv/connector/IHttpConnection.java
+ com/netscape/certsrv/connector/IRemoteAuthority.java
+ com/netscape/certsrv/security/IStorageKeyUnit.java
+ com/netscape/certsrv/security/IEncryptionUnit.java
+ com/netscape/certsrv/security/KeyCertData.java
+ com/netscape/certsrv/security/ICryptoSubsystem.java
+ com/netscape/certsrv/security/ITransportKeyUnit.java
+ com/netscape/certsrv/security/IToken.java
+ com/netscape/certsrv/security/ISigningUnit.java
+ com/netscape/certsrv/security/Credential.java
+ com/netscape/certsrv/client/connection/IAuthenticator.java
+ com/netscape/certsrv/client/connection/IConnectionFactory.java
+ com/netscape/certsrv/client/connection/IConnection.java
+ com/netscape/certsrv/client/IDataProcessor.java
+ com/netscape/certsrv/ocsp/IOCSPService.java
+ com/netscape/certsrv/ocsp/IOCSPStore.java
+ com/netscape/certsrv/ocsp/IDefStore.java
+ com/netscape/certsrv/ocsp/IOCSPAuthority.java
+ com/netscape/certsrv/notification/IEmailFormProcessor.java
+ com/netscape/certsrv/notification/IMailNotification.java
+ com/netscape/certsrv/notification/IEmailTemplate.java
+ com/netscape/certsrv/notification/IEmailResolver.java
+ com/netscape/certsrv/notification/IEmailResolverKeys.java
+ com/netscape/certsrv/notification/ENotificationException.java
+ com/netscape/certsrv/notification/NotificationResources.java
+ com/netscape/certsrv/profile/IProfileEx.java
+ com/netscape/certsrv/profile/ERejectException.java
+ com/netscape/certsrv/profile/ICertInfoPolicyDefault.java
+ com/netscape/certsrv/profile/IPolicyConstraint.java
+ com/netscape/certsrv/profile/IProfileInput.java
+ com/netscape/certsrv/profile/IProfileAuthenticator.java
+ com/netscape/certsrv/profile/IProfile.java
+ com/netscape/certsrv/profile/IProfileOutput.java
+ com/netscape/certsrv/profile/IProfileContext.java
+ com/netscape/certsrv/profile/EDeferException.java
+ com/netscape/certsrv/profile/EProfileException.java
+ com/netscape/certsrv/profile/CertInfoProfile.java
+ com/netscape/certsrv/profile/IPolicyDefault.java
+ com/netscape/certsrv/profile/IEnrollProfile.java
+ com/netscape/certsrv/profile/IProfileSubsystem.java
+ com/netscape/certsrv/profile/IProfileUpdater.java
+ com/netscape/certsrv/profile/IProfilePolicy.java
+)
+
+set(pki-cms_java_SRCS
+ com/netscape/cms/listeners/PinRemovalListener.java
+ com/netscape/cms/listeners/RequestInQListener.java
+ com/netscape/cms/listeners/CertificateIssuedListener.java
+ com/netscape/cms/listeners/CertificateRevokedListener.java
+ com/netscape/cms/publish/mappers/LdapCertSubjMap.java
+ com/netscape/cms/publish/mappers/MapRDNPattern.java
+ com/netscape/cms/publish/mappers/NoMap.java
+ com/netscape/cms/publish/mappers/LdapEnhancedMap.java
+ com/netscape/cms/publish/mappers/MapDNPattern.java
+ com/netscape/cms/publish/mappers/LdapCertCompsMap.java
+ com/netscape/cms/publish/mappers/AVAPattern.java
+ com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
+ com/netscape/cms/publish/mappers/LdapCertExactMap.java
+ com/netscape/cms/publish/mappers/MapAVAPattern.java
+ com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java
+ com/netscape/cms/publish/mappers/LdapDNCompsMap.java
+ com/netscape/cms/publish/mappers/LdapSimpleMap.java
+ com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java
+ com/netscape/cms/publish/publishers/LdapUserCertPublisher.java
+ com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
+ com/netscape/cms/publish/publishers/FileBasedPublisher.java
+ com/netscape/cms/publish/publishers/LdapCrlPublisher.java
+ com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
+ com/netscape/cms/publish/publishers/Utils.java
+ com/netscape/cms/publish/publishers/OCSPPublisher.java
+ com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java
+ com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
+ com/netscape/cms/policy/constraints/AgentPolicy.java
+ com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
+ com/netscape/cms/policy/constraints/IssuerConstraints.java
+ com/netscape/cms/policy/constraints/RevocationConstraints.java
+ com/netscape/cms/policy/constraints/DefaultRevocation.java
+ com/netscape/cms/policy/constraints/RSAKeyConstraints.java
+ com/netscape/cms/policy/constraints/DSAKeyConstraints.java
+ com/netscape/cms/policy/constraints/UniqueSubjectName.java
+ com/netscape/cms/policy/constraints/ManualAuthentication.java
+ com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
+ com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
+ com/netscape/cms/policy/constraints/AttributePresentConstraints.java
+ com/netscape/cms/policy/constraints/ValidityConstraints.java
+ com/netscape/cms/policy/constraints/RenewalConstraints.java
+ com/netscape/cms/policy/constraints/SubCANameConstraints.java
+ com/netscape/cms/policy/APolicyRule.java
+ com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
+ com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
+ com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
+ com/netscape/cms/policy/extensions/SubjAltNameExt.java
+ com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
+ com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
+ com/netscape/cms/policy/extensions/GenericASN1Ext.java
+ com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
+ com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
+ com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
+ com/netscape/cms/policy/extensions/NameConstraintsExt.java
+ com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
+ com/netscape/cms/policy/extensions/PresenceExt.java
+ com/netscape/cms/policy/extensions/NSCCommentExt.java
+ com/netscape/cms/policy/extensions/BasicConstraintsExt.java
+ com/netscape/cms/policy/extensions/IssuerAltNameExt.java
+ com/netscape/cms/policy/extensions/PolicyMappingsExt.java
+ com/netscape/cms/policy/extensions/SubjectAltNameExt.java
+ com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
+ com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
+ com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
+ com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
+ com/netscape/cms/policy/extensions/KeyUsageExt.java
+ com/netscape/cms/policy/extensions/NSCertTypeExt.java
+ com/netscape/cms/servlet/filter/AdminRequestFilter.java
+ com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java
+ com/netscape/cms/servlet/filter/EERequestFilter.java
+ com/netscape/cms/servlet/filter/AgentRequestFilter.java
+ com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java
+ com/netscape/cms/servlet/common/ICMSTemplateFiller.java
+ com/netscape/cms/servlet/common/IndexTemplateFiller.java
+ com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java
+ com/netscape/cms/servlet/common/ECMSGWException.java
+ com/netscape/cms/servlet/common/CMSTemplate.java
+ com/netscape/cms/servlet/common/GenErrorTemplateFiller.java
+ com/netscape/cms/servlet/common/AuthCredentials.java
+ com/netscape/cms/servlet/common/CMSLoadTemplate.java
+ com/netscape/cms/servlet/common/CMSFileLoader.java
+ com/netscape/cms/servlet/common/RawJS.java
+ com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java
+ com/netscape/cms/servlet/common/CMSTemplateParams.java
+ com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java
+ com/netscape/cms/servlet/common/CMCOutputTemplate.java
+ com/netscape/cms/servlet/common/CMSGateway.java
+ com/netscape/cms/servlet/common/CMSRequest.java
+ com/netscape/cms/servlet/common/CMSFile.java
+ com/netscape/cms/servlet/common/IRawJS.java
+ com/netscape/cms/servlet/common/Utils.java
+ com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
+ com/netscape/cms/servlet/common/CMSGWResources.java
+ com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java
+ com/netscape/cms/servlet/cert/UpdateCRL.java
+ com/netscape/cms/servlet/cert/GetInfo.java
+ com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
+ com/netscape/cms/servlet/cert/DoUnrevoke.java
+ com/netscape/cms/servlet/cert/DisplayBySerial.java
+ com/netscape/cms/servlet/cert/GetCertFromRequest.java
+ com/netscape/cms/servlet/cert/HashEnrollServlet.java
+ com/netscape/cms/servlet/cert/UpdateDir.java
+ com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
+ com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
+ com/netscape/cms/servlet/cert/scep/ChallengePassword.java
+ com/netscape/cms/servlet/cert/EnrollServlet.java
+ com/netscape/cms/servlet/cert/DisableEnrollResult.java
+ com/netscape/cms/servlet/cert/GetEnableStatus.java
+ com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
+ com/netscape/cms/servlet/cert/DoRevoke.java
+ com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
+ com/netscape/cms/servlet/cert/CloneRedirect.java
+ com/netscape/cms/servlet/cert/EnableEnrollResult.java
+ com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
+ com/netscape/cms/servlet/cert/GetCAChain.java
+ com/netscape/cms/servlet/cert/SrchCerts.java
+ com/netscape/cms/servlet/cert/Monitor.java
+ com/netscape/cms/servlet/cert/GetCRL.java
+ com/netscape/cms/servlet/cert/ReasonToRevoke.java
+ com/netscape/cms/servlet/cert/ListCerts.java
+ com/netscape/cms/servlet/cert/RenewalServlet.java
+ com/netscape/cms/servlet/cert/DoRevokeTPS.java
+ com/netscape/cms/servlet/cert/DirAuthServlet.java
+ com/netscape/cms/servlet/cert/RemoteAuthConfig.java
+ com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
+ com/netscape/cms/servlet/cert/RevocationServlet.java
+ com/netscape/cms/servlet/cert/CMCRevReqServlet.java
+ com/netscape/cms/servlet/cert/GetBySerial.java
+ com/netscape/cms/servlet/cert/DisplayCRL.java
+ com/netscape/cms/servlet/admin/OCSPAdminServlet.java
+ com/netscape/cms/servlet/admin/CMSAdminServlet.java
+ com/netscape/cms/servlet/admin/JobsAdminServlet.java
+ com/netscape/cms/servlet/admin/PublisherAdminServlet.java
+ com/netscape/cms/servlet/admin/ProfileAdminServlet.java
+ com/netscape/cms/servlet/admin/ACLAdminServlet.java
+ com/netscape/cms/servlet/admin/AuthCredentials.java
+ com/netscape/cms/servlet/admin/CAAdminServlet.java
+ com/netscape/cms/servlet/admin/PolicyAdminServlet.java
+ com/netscape/cms/servlet/admin/RegistryAdminServlet.java
+ com/netscape/cms/servlet/admin/AuthAdminServlet.java
+ com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java
+ com/netscape/cms/servlet/admin/AdminServlet.java
+ com/netscape/cms/servlet/admin/KRAAdminServlet.java
+ com/netscape/cms/servlet/admin/LogAdminServlet.java
+ com/netscape/cms/servlet/admin/RAAdminServlet.java
+ com/netscape/cms/servlet/admin/AdminResources.java
+ com/netscape/cms/servlet/key/DisplayBySerial.java
+ com/netscape/cms/servlet/key/SrchKey.java
+ com/netscape/cms/servlet/key/DisplayTransport.java
+ com/netscape/cms/servlet/key/GrantRecovery.java
+ com/netscape/cms/servlet/key/SrchKeyForRecovery.java
+ com/netscape/cms/servlet/key/GrantAsyncRecovery.java
+ com/netscape/cms/servlet/key/GetApprovalStatus.java
+ com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java
+ com/netscape/cms/servlet/key/ExamineRecovery.java
+ com/netscape/cms/servlet/key/GetPk12.java
+ com/netscape/cms/servlet/key/GetAsyncPk12.java
+ com/netscape/cms/servlet/key/RecoverBySerial.java
+ com/netscape/cms/servlet/key/KeyRecordParser.java
+ com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
+ com/netscape/cms/servlet/base/IndexServlet.java
+ com/netscape/cms/servlet/base/UserInfo.java
+ com/netscape/cms/servlet/base/PortsServlet.java
+ com/netscape/cms/servlet/base/CMSServlet.java
+ com/netscape/cms/servlet/base/CMSStartServlet.java
+ com/netscape/cms/servlet/base/ProxyServlet.java
+ com/netscape/cms/servlet/base/DynamicVariablesServlet.java
+ com/netscape/cms/servlet/base/GetStats.java
+ com/netscape/cms/servlet/base/SystemInfoServlet.java
+ com/netscape/cms/servlet/base/DisplayHtmlServlet.java
+ com/netscape/cms/servlet/csadmin/BaseServlet.java
+ com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java
+ com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java
+ com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
+ com/netscape/cms/servlet/csadmin/SizePanel.java
+ com/netscape/cms/servlet/csadmin/Cert.java
+ com/netscape/cms/servlet/csadmin/UpdateConnector.java
+ com/netscape/cms/servlet/csadmin/DonePanel.java
+ com/netscape/cms/servlet/csadmin/GetTokenInfo.java
+ com/netscape/cms/servlet/csadmin/WizardPanelBase.java
+ com/netscape/cms/servlet/csadmin/CheckIdentity.java
+ com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
+ com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java
+ com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java
+ com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java
+ com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java
+ com/netscape/cms/servlet/csadmin/AuthenticatePanel.java
+ com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java
+ com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java
+ com/netscape/cms/servlet/csadmin/DisplayServlet.java
+ com/netscape/cms/servlet/csadmin/DatabasePanel.java
+ com/netscape/cms/servlet/csadmin/WelcomePanel.java
+ com/netscape/cms/servlet/csadmin/DatabaseServlet.java
+ com/netscape/cms/servlet/csadmin/CAInfoPanel.java
+ com/netscape/cms/servlet/csadmin/GetTransportCert.java
+ com/netscape/cms/servlet/csadmin/ImportTransportCert.java
+ com/netscape/cms/servlet/csadmin/SessionTimer.java
+ com/netscape/cms/servlet/csadmin/ModulePanel.java
+ com/netscape/cms/servlet/csadmin/GetConfigEntries.java
+ com/netscape/cms/servlet/csadmin/UpdateDomainXML.java
+ com/netscape/cms/servlet/csadmin/GetStatus.java
+ com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java
+ com/netscape/cms/servlet/csadmin/TokenAuthenticate.java
+ com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java
+ com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java
+ com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java
+ com/netscape/cms/servlet/csadmin/CertUtil.java
+ com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java
+ com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java
+ com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java
+ com/netscape/cms/servlet/csadmin/GetCertChain.java
+ com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java
+ com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java
+ com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java
+ com/netscape/cms/servlet/csadmin/GetDomainXML.java
+ com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java
+ com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java
+ com/netscape/cms/servlet/csadmin/ModuleServlet.java
+ com/netscape/cms/servlet/csadmin/GetCookie.java
+ com/netscape/cms/servlet/csadmin/CertRequestPanel.java
+ com/netscape/cms/servlet/csadmin/RegisterUser.java
+ com/netscape/cms/servlet/csadmin/GetSubsystemCert.java
+ com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java
+ com/netscape/cms/servlet/csadmin/WelcomeServlet.java
+ com/netscape/cms/servlet/csadmin/LoginServlet.java
+ com/netscape/cms/servlet/csadmin/AdminPanel.java
+ com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
+ com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java
+ com/netscape/cms/servlet/csadmin/MainPageServlet.java
+ com/netscape/cms/servlet/csadmin/HierarchyPanel.java
+ com/netscape/cms/servlet/csadmin/DownloadPKCS12.java
+ com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java
+ com/netscape/cms/servlet/csadmin/NamePanel.java
+ com/netscape/cms/servlet/wizard/WizardServlet.java
+ com/netscape/cms/servlet/wizard/IWizardPanel.java
+ com/netscape/cms/servlet/processors/PKCS10Processor.java
+ com/netscape/cms/servlet/processors/PKIProcessor.java
+ com/netscape/cms/servlet/processors/KeyGenProcessor.java
+ com/netscape/cms/servlet/processors/CRMFProcessor.java
+ com/netscape/cms/servlet/processors/IPKIProcessor.java
+ com/netscape/cms/servlet/processors/CMCProcessor.java
+ com/netscape/cms/servlet/request/ProcessReq.java
+ com/netscape/cms/servlet/request/CheckRequest.java
+ com/netscape/cms/servlet/request/IReqParser.java
+ com/netscape/cms/servlet/request/ReqParser.java
+ com/netscape/cms/servlet/request/QueryReq.java
+ com/netscape/cms/servlet/request/SearchReqs.java
+ com/netscape/cms/servlet/request/ProcessCertReq.java
+ com/netscape/cms/servlet/request/CertReqParser.java
+ com/netscape/cms/servlet/request/KeyReqParser.java
+ com/netscape/cms/servlet/tks/TokenServlet.java
+ com/netscape/cms/servlet/connector/CloneServlet.java
+ com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java
+ com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
+ com/netscape/cms/servlet/connector/ConnectorServlet.java
+ com/netscape/cms/servlet/ocsp/OCSPServlet.java
+ com/netscape/cms/servlet/ocsp/ListCAServlet.java
+ com/netscape/cms/servlet/ocsp/AddCRLServlet.java
+ com/netscape/cms/servlet/ocsp/CheckCertServlet.java
+ com/netscape/cms/servlet/ocsp/RemoveCAServlet.java
+ com/netscape/cms/servlet/ocsp/GetOCSPInfo.java
+ com/netscape/cms/servlet/ocsp/AddCAServlet.java
+ com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
+ com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
+ com/netscape/cms/servlet/profile/ProfileSelectServlet.java
+ com/netscape/cms/servlet/profile/ProfileProcessServlet.java
+ com/netscape/cms/servlet/profile/ProfileListServlet.java
+ com/netscape/cms/servlet/profile/ProfileApproveServlet.java
+ com/netscape/cms/servlet/profile/ProfileReviewServlet.java
+ com/netscape/cms/servlet/profile/SSLClientCertProvider.java
+ com/netscape/cms/servlet/profile/ProfileServlet.java
+ com/netscape/cms/authentication/AgentCertAuthentication.java
+ com/netscape/cms/authentication/PortalEnroll.java
+ com/netscape/cms/authentication/UdnPwdDirAuthentication.java
+ com/netscape/cms/authentication/TokenAuthentication.java
+ com/netscape/cms/authentication/Crypt.java
+ com/netscape/cms/authentication/CMCAuth.java
+ com/netscape/cms/authentication/HashAuthData.java
+ com/netscape/cms/authentication/SharedSecret.java
+ com/netscape/cms/authentication/FlatFileAuth.java
+ com/netscape/cms/authentication/AVAPattern.java
+ com/netscape/cms/authentication/RDNPattern.java
+ com/netscape/cms/authentication/DNPattern.java
+ com/netscape/cms/authentication/DirBasedAuthentication.java
+ com/netscape/cms/authentication/HashAuthentication.java
+ com/netscape/cms/authentication/UidPwdPinDirAuthentication.java
+ com/netscape/cms/authentication/SSLclientCertAuthentication.java
+ com/netscape/cms/authentication/UidPwdDirAuthentication.java
+ com/netscape/cms/authorization/BasicAclAuthz.java
+ com/netscape/cms/authorization/AAclAuthz.java
+ com/netscape/cms/authorization/DirAclAuthz.java
+ com/netscape/cms/shares/OldJoinShares.java
+ com/netscape/cms/shares/OldShare.java
+ com/netscape/cms/password/PasswordChecker.java
+ com/netscape/cms/jobs/UnpublishExpiredJob.java
+ com/netscape/cms/jobs/RenewalNotificationJob.java
+ com/netscape/cms/jobs/RequestInQueueJob.java
+ com/netscape/cms/jobs/AJobBase.java
+ com/netscape/cms/jobs/PublishCertsJob.java
+ com/netscape/cms/selftests/ASelfTest.java
+ com/netscape/cms/selftests/kra/KRAPresence.java
+ com/netscape/cms/selftests/ra/RAPresence.java
+ com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
+ com/netscape/cms/selftests/ca/CAPresence.java
+ com/netscape/cms/selftests/ca/CAValidity.java
+ com/netscape/cms/selftests/common/SystemCertsVerification.java
+ com/netscape/cms/selftests/ocsp/OCSPValidity.java
+ com/netscape/cms/selftests/ocsp/OCSPPresence.java
+ com/netscape/cms/request/RequestScheduler.java
+ com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java
+ com/netscape/cms/crl/CMSAuthInfoAccessExtension.java
+ com/netscape/cms/crl/CMSCRLReasonExtension.java
+ com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java
+ com/netscape/cms/crl/CMSCertificateIssuerExtension.java
+ com/netscape/cms/crl/CMSHoldInstructionExtension.java
+ com/netscape/cms/crl/CMSCRLNumberExtension.java
+ com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java
+ com/netscape/cms/crl/CMSFreshestCRLExtension.java
+ com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java
+ com/netscape/cms/crl/CMSInvalidityDateExtension.java
+ com/netscape/cms/evaluators/IPAddressAccessEvaluator.java
+ com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java
+ com/netscape/cms/evaluators/GroupAccessEvaluator.java
+ com/netscape/cms/evaluators/UserAccessEvaluator.java
+ com/netscape/cms/logging/LogEntry.java
+ com/netscape/cms/logging/LogFile.java
+ com/netscape/cms/logging/RollingLogFile.java
+ com/netscape/cms/ocsp/DefStore.java
+ com/netscape/cms/ocsp/LDAPStore.java
+ com/netscape/cms/notification/MailNotification.java
+ com/netscape/cms/profile/common/CACertCAEnrollProfile.java
+ com/netscape/cms/profile/common/ProfilePolicy.java
+ com/netscape/cms/profile/common/EnrollProfile.java
+ com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java
+ com/netscape/cms/profile/common/CAEnrollProfile.java
+ com/netscape/cms/profile/common/RAEnrollProfile.java
+ com/netscape/cms/profile/common/ProfileContext.java
+ com/netscape/cms/profile/common/EnrollProfileContext.java
+ com/netscape/cms/profile/common/BasicProfile.java
+ com/netscape/cms/profile/common/UserCertCAEnrollProfile.java
+ com/netscape/cms/profile/def/UserSubjectNameDefault.java
+ com/netscape/cms/profile/def/AutoAssignDefault.java
+ com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java
+ com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java
+ com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
+ com/netscape/cms/profile/def/IssuerAltNameExtDefault.java
+ com/netscape/cms/profile/def/CAEnrollDefault.java
+ com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java
+ com/netscape/cms/profile/def/SubjectNameDefault.java
+ com/netscape/cms/profile/def/NoDefault.java
+ com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java
+ com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java
+ com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java
+ com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java
+ com/netscape/cms/profile/def/EnrollDefault.java
+ com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java
+ com/netscape/cms/profile/def/BasicConstraintsExtDefault.java
+ com/netscape/cms/profile/def/SigningAlgDefault.java
+ com/netscape/cms/profile/def/GenericExtDefault.java
+ com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java
+ com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
+ com/netscape/cms/profile/def/UserKeyDefault.java
+ com/netscape/cms/profile/def/NSCCommentExtDefault.java
+ com/netscape/cms/profile/def/CertificateVersionDefault.java
+ com/netscape/cms/profile/def/ValidityDefault.java
+ com/netscape/cms/profile/def/ImageDefault.java
+ com/netscape/cms/profile/def/PolicyMappingsExtDefault.java
+ com/netscape/cms/profile/def/NSCertTypeExtDefault.java
+ com/netscape/cms/profile/def/CAValidityDefault.java
+ com/netscape/cms/profile/def/UserSigningAlgDefault.java
+ com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java
+ com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java
+ com/netscape/cms/profile/def/UserValidityDefault.java
+ com/netscape/cms/profile/def/EnrollExtDefault.java
+ com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java
+ com/netscape/cms/profile/def/KeyUsageExtDefault.java
+ com/netscape/cms/profile/def/FreshestCRLExtDefault.java
+ com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
+ com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java
+ com/netscape/cms/profile/def/UserExtensionDefault.java
+ com/netscape/cms/profile/def/NameConstraintsExtDefault.java
+ com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
+ com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java
+ com/netscape/cms/profile/input/SubjectDNInput.java
+ com/netscape/cms/profile/input/SerialNumRenewInput.java
+ com/netscape/cms/profile/input/SubjectNameInput.java
+ com/netscape/cms/profile/input/KeyGenInput.java
+ com/netscape/cms/profile/input/ImageInput.java
+ com/netscape/cms/profile/input/EnrollInput.java
+ com/netscape/cms/profile/input/nsNKeyCertReqInput.java
+ com/netscape/cms/profile/input/FileSigningInput.java
+ com/netscape/cms/profile/input/nsHKeyCertReqInput.java
+ com/netscape/cms/profile/input/CertReqInput.java
+ com/netscape/cms/profile/input/SubmitterInfoInput.java
+ com/netscape/cms/profile/input/GenericInput.java
+ com/netscape/cms/profile/input/DualKeyGenInput.java
+ com/netscape/cms/profile/input/CMCCertReqInput.java
+ com/netscape/cms/profile/constraint/KeyConstraint.java
+ com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java
+ com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java
+ com/netscape/cms/profile/constraint/EnrollConstraint.java
+ com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
+ com/netscape/cms/profile/constraint/ExtensionConstraint.java
+ com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java
+ com/netscape/cms/profile/constraint/NoConstraint.java
+ com/netscape/cms/profile/constraint/SubjectNameConstraint.java
+ com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java
+ com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java
+ com/netscape/cms/profile/constraint/CAEnrollConstraint.java
+ com/netscape/cms/profile/constraint/SigningAlgConstraint.java
+ com/netscape/cms/profile/constraint/ValidityConstraint.java
+ com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
+ com/netscape/cms/profile/constraint/CAValidityConstraint.java
+ com/netscape/cms/profile/updater/SubsystemGroupUpdater.java
+ com/netscape/cms/profile/output/CertOutput.java
+ com/netscape/cms/profile/output/EnrollOutput.java
+ com/netscape/cms/profile/output/nsNKeyOutput.java
+ com/netscape/cms/profile/output/PKCS7Output.java
+ com/netscape/cms/profile/output/CMMFOutput.java
+)
+
+set(pki-cmscore_java_SRCS
+ com/netscape/cmscore/apps/PKIServerEvent.java
+ com/netscape/cmscore/apps/Upgrade.java
+ com/netscape/cmscore/apps/PKIServerListener.java
+ com/netscape/cmscore/apps/CommandQueue.java
+ com/netscape/cmscore/apps/CMSEngine.java
+ com/netscape/cmscore/apps/Setup.java
+ com/netscape/cmscore/ldap/LdapSimpleExpression.java
+ com/netscape/cmscore/ldap/LdapAndExpression.java
+ com/netscape/cmscore/ldap/LdapPublishModule.java
+ com/netscape/cmscore/ldap/LdapPredicateParser.java
+ com/netscape/cmscore/ldap/LdapRequestListener.java
+ com/netscape/cmscore/ldap/LdapConnModule.java
+ com/netscape/cmscore/ldap/LdapOrExpression.java
+ com/netscape/cmscore/ldap/PublishObject.java
+ com/netscape/cmscore/ldap/PublisherProcessor.java
+ com/netscape/cmscore/ldap/LdapRule.java
+ com/netscape/cmscore/listeners/ListenerPlugin.java
+ com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java
+ com/netscape/cmscore/usrgrp/Group.java
+ com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java
+ com/netscape/cmscore/usrgrp/UGSubsystem.java
+ com/netscape/cmscore/usrgrp/User.java
+ com/netscape/cmscore/crmf/CRMFParser.java
+ com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java
+ com/netscape/cmscore/util/AssertionException.java
+ com/netscape/cmscore/util/ProfileSubsystem.java
+ com/netscape/cmscore/util/FileAsString.java
+ com/netscape/cmscore/util/Assert.java
+ com/netscape/cmscore/util/UtilMessage.java
+ com/netscape/cmscore/util/PFXUtils.java
+ com/netscape/cmscore/util/ExceptionFormatter.java
+ com/netscape/cmscore/util/StatsSubsystem.java
+ com/netscape/cmscore/util/FileDialogFilter.java
+ com/netscape/cmscore/util/OsSubsystem.java
+ com/netscape/cmscore/util/Debug.java
+ com/netscape/cmscore/util/UtilResources.java
+ com/netscape/cmscore/policy/JavaScriptRequestProxy.java
+ com/netscape/cmscore/policy/SimpleExpression.java
+ com/netscape/cmscore/policy/GeneralNameUtil.java
+ com/netscape/cmscore/policy/PolicyPredicateParser.java
+ com/netscape/cmscore/policy/AndExpression.java
+ com/netscape/cmscore/policy/PolicySet.java
+ com/netscape/cmscore/policy/GenericPolicyProcessor.java
+ com/netscape/cmscore/policy/OrExpression.java
+ com/netscape/cmscore/cert/CertificatePair.java
+ com/netscape/cmscore/cert/X500NameSubsystem.java
+ com/netscape/cmscore/cert/CertUtils.java
+ com/netscape/cmscore/cert/ExtPrettyPrint.java
+ com/netscape/cmscore/cert/OidLoaderSubsystem.java
+ com/netscape/cmscore/cert/CrlPrettyPrint.java
+ com/netscape/cmscore/cert/CertPrettyPrint.java
+ com/netscape/cmscore/cert/PrettyPrintResources.java
+ com/netscape/cmscore/cert/PrettyPrintFormat.java
+ com/netscape/cmscore/cert/CrossCertPairSubsystem.java
+ com/netscape/cmscore/cert/CertDateCompare.java
+ com/netscape/cmscore/cert/PubKeyPrettyPrint.java
+ com/netscape/cmscore/cert/CrlCachePrettyPrint.java
+ com/netscape/cmscore/registry/PluginInfo.java
+ com/netscape/cmscore/registry/PluginRegistry.java
+ com/netscape/cmscore/base/ArgBlock.java
+ com/netscape/cmscore/base/FileConfigStore.java
+ com/netscape/cmscore/base/SimpleProperties.java
+ com/netscape/cmscore/base/SourceConfigStore.java
+ com/netscape/cmscore/base/PropConfigStore.java
+ com/netscape/cmscore/base/JDialogPasswordCallback.java
+ com/netscape/cmscore/base/SubsystemRegistry.java
+ com/netscape/cmscore/base/SubsystemLoader.java
+ com/netscape/cmscore/dbs/CRLRepository.java
+ com/netscape/cmscore/dbs/CertRecord.java
+ com/netscape/cmscore/dbs/RevocationInfoMapper.java
+ com/netscape/cmscore/dbs/BigIntegerMapper.java
+ com/netscape/cmscore/dbs/X509CertImplMapper.java
+ com/netscape/cmscore/dbs/KeyRecord.java
+ com/netscape/cmscore/dbs/KeyStateMapper.java
+ com/netscape/cmscore/dbs/StringVectorMapper.java
+ com/netscape/cmscore/dbs/DBSSession.java
+ com/netscape/cmscore/dbs/DBSubsystem.java
+ com/netscape/cmscore/dbs/StringMapper.java
+ com/netscape/cmscore/dbs/LongMapper.java
+ com/netscape/cmscore/dbs/CertRecordList.java
+ com/netscape/cmscore/dbs/MetaInfoMapper.java
+ com/netscape/cmscore/dbs/RepositorySchema.java
+ com/netscape/cmscore/dbs/PublicKeyMapper.java
+ com/netscape/cmscore/dbs/KeyDBSchema.java
+ com/netscape/cmscore/dbs/LdapFilterConverter.java
+ com/netscape/cmscore/dbs/ObjectStreamMapper.java
+ com/netscape/cmscore/dbs/Repository.java
+ com/netscape/cmscore/dbs/CertificateRepository.java
+ com/netscape/cmscore/dbs/DBVirtualList.java
+ com/netscape/cmscore/dbs/KeyRecordList.java
+ com/netscape/cmscore/dbs/RepositoryRecord.java
+ com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
+ com/netscape/cmscore/dbs/DBRegistry.java
+ com/netscape/cmscore/dbs/CRLDBSchema.java
+ com/netscape/cmscore/dbs/CertDBSchema.java
+ com/netscape/cmscore/dbs/DateMapper.java
+ com/netscape/cmscore/dbs/ByteArrayMapper.java
+ com/netscape/cmscore/dbs/CertRecordMapper.java
+ com/netscape/cmscore/dbs/DBSearchResults.java
+ com/netscape/cmscore/dbs/IntegerMapper.java
+ com/netscape/cmscore/dbs/RevocationInfo.java
+ com/netscape/cmscore/dbs/DBSUtil.java
+ com/netscape/cmscore/dbs/X500NameMapper.java
+ com/netscape/cmscore/dbs/KeyRepository.java
+ com/netscape/cmscore/dbs/ReplicaIDRepository.java
+ com/netscape/cmscore/dbs/DateArrayMapper.java
+ com/netscape/cmscore/dbs/KeyRecordMapper.java
+ com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java
+ com/netscape/cmscore/authentication/NullAuthentication.java
+ com/netscape/cmscore/authentication/SSLClientCertAuthentication.java
+ com/netscape/cmscore/authentication/AuthSubsystem.java
+ com/netscape/cmscore/authentication/CertUserDBAuthentication.java
+ com/netscape/cmscore/authentication/VerifiedCert.java
+ com/netscape/cmscore/authentication/VerifiedCerts.java
+ com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java
+ com/netscape/cmscore/authorization/AuthzSubsystem.java
+ com/netscape/cmscore/extensions/CMSExtensionsMap.java
+ com/netscape/cmscore/extensions/KeyUsage.java
+ com/netscape/cmscore/jobs/CronRange.java
+ com/netscape/cmscore/jobs/JobsScheduler.java
+ com/netscape/cmscore/jobs/CronItem.java
+ com/netscape/cmscore/jobs/JobCron.java
+ com/netscape/cmscore/selftests/SelfTestOrderedInstance.java
+ com/netscape/cmscore/selftests/SelfTestSubsystem.java
+ com/netscape/cmscore/request/ExtDataHashtable.java
+ com/netscape/cmscore/request/RequestAttr.java
+ com/netscape/cmscore/request/RequestQueue.java
+ com/netscape/cmscore/request/Schema.java
+ com/netscape/cmscore/request/RequestRepository.java
+ com/netscape/cmscore/request/ARequestRecord.java
+ com/netscape/cmscore/request/ARequestQueue.java
+ com/netscape/cmscore/request/CertRequestConstants.java
+ com/netscape/cmscore/request/RequestRecord.java
+ com/netscape/cmscore/request/RequestSubsystem.java
+ com/netscape/cmscore/ldapconn/LdapBoundConnection.java
+ com/netscape/cmscore/ldapconn/LdapConnInfo.java
+ com/netscape/cmscore/ldapconn/LdapAuthInfo.java
+ com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java
+ com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java
+ com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java
+ com/netscape/cmscore/ldapconn/LdapAnonConnection.java
+ com/netscape/cmscore/logging/AuditEventFactory.java
+ com/netscape/cmscore/logging/LogQueue.java
+ com/netscape/cmscore/logging/LogSubsystem.java
+ com/netscape/cmscore/logging/AuditFormat.java
+ com/netscape/cmscore/logging/Logger.java
+ com/netscape/cmscore/logging/SignedAuditEventFactory.java
+ com/netscape/cmscore/logging/SignedAuditLogger.java
+ com/netscape/cmscore/logging/SystemEventFactory.java
+ com/netscape/cmscore/connector/LocalConnector.java
+ com/netscape/cmscore/connector/HttpConnection.java
+ com/netscape/cmscore/connector/RequestTransfer.java
+ com/netscape/cmscore/connector/RemoteAuthority.java
+ com/netscape/cmscore/connector/HttpPKIMessage.java
+ com/netscape/cmscore/connector/HttpConnector.java
+ com/netscape/cmscore/connector/HttpConnFactory.java
+ com/netscape/cmscore/connector/HttpRequestEncoder.java
+ com/netscape/cmscore/connector/Resender.java
+ com/netscape/cmscore/security/OCSPSigningCert.java
+ com/netscape/cmscore/security/Provider.java
+ com/netscape/cmscore/security/KeyCertUtil.java
+ com/netscape/cmscore/security/KRATransportCert.java
+ com/netscape/cmscore/security/SSLCert.java
+ com/netscape/cmscore/security/SSLSelfSignedCert.java
+ com/netscape/cmscore/security/JssSubsystem.java
+ com/netscape/cmscore/security/SubsystemCert.java
+ com/netscape/cmscore/security/PWsdrCache.java
+ com/netscape/cmscore/security/CertificateInfo.java
+ com/netscape/cmscore/security/PWCBsdr.java
+ com/netscape/cmscore/security/PWUtil.java
+ com/netscape/cmscore/security/CASigningCert.java
+ com/netscape/cmscore/security/RASigningCert.java
+ com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java
+ com/netscape/cmscore/notification/EmailResolverKeys.java
+ com/netscape/cmscore/notification/EmailTemplate.java
+ com/netscape/cmscore/notification/EmailFormProcessor.java
+ com/netscape/cmscore/notification/ReqCertEmailResolver.java
+ com/netscape/cmscore/profile/ProfileSubsystem.java
+ com/netscape/cmscore/time/SimpleTimeSource.java
+)
+
+set(pki-cmsbundle_RCS
+ LogMessages.properties
+ UserMessages.properties
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR} ${XALAN_JAR} ${XERCES_JAR}
+ ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR})
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build pki-certsrv
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape/certsrv)
+add_jar(pki-certsrv ${pki-certsrv_java_SRCS})
+add_dependencies(pki-certsrv osutil pki-nsutil pki-cmsutil)
+install_jar(pki-certsrv ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CERTSRV_JAR ${pki-certsrv_JAR_FILE} CACHE INTERNAL "pki-certsrv jar file")
+
+# build pki-cms
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape/cms)
+add_jar(pki-cms ${pki-cms_java_SRCS})
+add_dependencies(pki-cms osutil pki-nsutil pki-cmsutil pki-certsrv)
+install_jar(pki-cms ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CMS_JAR ${pki-cms_JAR_FILE} CACHE INTERNAL "pki-cms jar file")
+
+create_javadoc(pki-common-${APPLICATION_VERSION}
+ FILES ${pki-cms_java_SRCS} ${pki-certsrv_java_SRCS}
+ CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} ${pki-certsrv_JAR_FILE}
+ WINDOWTITLE "pki-common"
+ DOCTITLE "<h1>pki-common</h1>"
+ AUTHOR TRUE
+ USE TRUE
+ VERSION TRUE
+)
+add_dependencies(pki-common-${APPLICATION_VERSION}_javadoc pki-cms pki-certsrv)
+
+# build pki-cmscore
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape/cmscore)
+add_jar(pki-cmscore ${pki-cmscore_java_SRCS})
+add_dependencies(pki-cmscore osutil pki-nsutil pki-cmsutil pki-certsrv pki-cms)
+install_jar(pki-cmscore ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CMSCORE_JAR ${pki-cmscore_JAR_FILE} CACHE INTERNAL "pki-cmscore jar file")
+
+# build pki-cmsbundle
+add_jar(pki-cmsbundle ${pki-cmsbundle_RCS})
+add_dependencies(pki-cmsbundle osutil pki-nsutil pki-cmsutil pki-certsrv pki-cms pki-cmscore)
+install_jar(pki-cmsbundle ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CMSBUNDLE_JAR ${pki-cmsbundle_JAR_FILE} CACHE INTERNAL "pki-cmsbundle jar file")
diff --git a/pki/base/common/src/LogMessages.properties b/pki/base/common/src/LogMessages.properties
new file mode 100644
index 000000000..7a31e66d8
--- /dev/null
+++ b/pki/base/common/src/LogMessages.properties
@@ -0,0 +1,2456 @@
+#
+# Log Messages for CS Administrators, not for end-users
+#
+##################################################################
+# General Common Errors
+##################################################################
+SERVER_STARTUP=Server is started.
+SERVER_SHUTDOWN=Shutting down.
+SERVER_STARTUP_WARNING=CS Warning: {0}
+SERVER_SHUTDOWN_ERROR=Error Starting CS: {0}
+INVALID_HOST=Invalid Host - {0}
+INVALID_PORT=Invalid Port - {0}
+INVALID_LDAP_HOST=Invalid LDAP Host - {0}
+INVALID_LDAP_PORT=Invalid LDAP Port - {0}
+CANNOT_CONNECT_LDAP=Couldn't get LDAP connection - {0}
+INVALID_ATTR=Invalid Attribute
+INVALID_DN=Invalid DN
+LDAP_ERROR=LDAP Error - {0}
+ENTRY_ALREADY_EXIST=Entry already exists - {0}
+LDAP_SERVER_DOWN=LDAP Server is Down
+OPERATION_ERROR=Operation Error - {0}
+READ_FILE_ERROR=Error reading file {0} - {1}
+RENAME_FILE_ERROR=Error renaming file {0} to {1}
+FILE_ERROR=File operation error: {0}
+USER_NOT_EXIST=User {0} does not exist
+INIT_DONE={0} initialization done.
+##################################################################
+# For com.netscape.cmscore.apps
+##################################################################
+CMSCORE_SDR_ADD_ERROR=sdr PWsdrCache addEntry failed
+##################################################################
+# For com.netscape.cms.authentication
+##################################################################
+CMS_AUTH_INIT_DONE=Initialization Done
+CMS_AUTH_SHUTDOWN_ERROR=Shutdown Error - {0}
+CMS_AUTH_NO_ATTR_ERROR=Could not get LDAP attributes. No entry or attributes returned.
+CMS_AUTH_NO_DN_ERROR=Could not form DN - {0}
+CMS_AUTH_NO_AUTH_ATTR_ERROR=Cannot get auth attributes. LDAP server is down.
+CMS_AUTH_NO_USER_ENTRY_ERROR=User Entry {0} no longer exists in the directory.
+CMS_AUTH_CREATE_SUBJECT_ERROR=Could not create subject name for {0}. Error - {1}
+CMS_AUTH_CREATE_CERTINFO_ERROR=Could not create certinfo for {0}. Error - {1}
+CMS_AUTH_READ_ENTRIES=Read entries from password file - {0}
+CMS_AUTH_USER_NOT_FOUND=User not found in password file.
+CMS_AUTH_INVALID_FINGER_PRINT=Invalid fingerprint.
+CMS_AUTH_INVALID_NIS_SERVER=Invalid NIS Server - {0}
+CMS_AUTH_INVALID_NIS_SERVER_NAME=Invalid NIS Server Name - {0}
+CMS_AUTH_INVALID_DOMAIN=Invalid Domain Name - {0}
+CMS_AUTH_EMPTY_PASSWORD=UID {0} attempted a login with an empty password.
+CMS_AUTH_EMPTY_PIN=UID {0} attempted a login with an empty pin.
+CMS_AUTH_BAD_PASSWORD=UID {0} attempted a login with a bad password.
+CMS_AUTH_AUTHENTICATED=UID {0} authenticated.
+CMS_AUTH_USER_NOT_EXIST=UID {0} does not exist in the LDAP server.
+CMS_AUTH_PORTAL_INIT=my portal enroll initialization is done
+CMS_AUTH_ADD_USER_ERROR=User cannot be added to LDAP server host {0} and port {1}
+CMS_AUTH_MAKE_DN_ERROR=Couldn't make DN. Error - {0}
+CMS_AUTH_REGISTRATION_DONE=Registration Done.
+CMS_AUTH_CANT_GET_OBJECTCLASS=Couldn't get object class.
+CMS_AUTH_NO_ENTRY_RETURNED=UID {0} search for entry {1} returned no entries.
+CMS_AUTH_NO_PIN_FOUND=UID {0} does not have a PIN attribute in the LDAP server.
+CMS_AUTH_CANT_REMOVE_PIN=could not remove pin for {0}
+CMS_AUTH_UKNOWN_ENCODING_TYPE={0} has an unknown encoding type (first byte is not 0 (sha1) or 1 (md5) or '-' (none). It is {1} for user: {2}
+CMS_AUTH_LENGTH_NOT_MATCHED=UID {0} Pin authentication: Hashed pin lengths do not match.
+##################################################################
+# For com.netscape.cmscore.authentication
+##################################################################
+CMSCORE_AUTH_INIT_AUTH=Auth manager {0} initialized.
+CMSCORE_AUTH_MISSING_UID=missing UID in authCred for authenticate()
+CMSCORE_AUTH_ADMIN_EMPTY_PW=Admin login attempted with UID {0} and a null pwd.
+CMSCORE_AUTH_ADMIN_NULL_PW=Admin login attempted with UID {0} and an empty pwd.
+CMSCORE_AUTH_ADMIN_NOT_FOUND=Admin login attempted with UID {0} UID not found
+CMSCORE_AUTH_AUTH_FAILED=Failed to authenticate as admin UID={0}. Error: {1}
+CMSCORE_AUTH_UID_NOT_FOUND=UID {0} is not a user in the internal usr/grp database. Error {1}
+CMSCORE_AUTH_MISSING_CERT=Agent authentication missing certificate credential.
+CMSCORE_AUTH_NO_CERT=No Client Certificate Found
+CMSCORE_AUTH_REVOKED_CERT=Cannot authenticate agent. Agent certificate has been revoked.
+CMSCORE_AUTH_AGENT_AUTH_FAILED=Cannot authenticate agent with certificate Serial 0x{0} Subject DN {1}. Error: {2}
+CMSCORE_AUTH_CANNOT_AGENT_AUTH=Cannot authenticate agent. LDAP Error: {0}
+CMSCORE_AUTH_AGENT_USER_NOT_FOUND=Cannot authenticate agent. Could not find a user for the agent cert. Check errors from UGSubsystem.
+CMSCORE_AUTH_AGENT_CERT_REPO=Agent authentication cannot get access to the certificate repository
+CMSCORE_AUTH_AGENT_REQUEST_QUEUE=Agent authentication cannot get access to the request queue.
+CMSCORE_AUTH_AGENT_REVO_STATUS=Agent authentication cannot evaluate the revocation status.
+CMSCORE_AUTH_AGENT_PROCESS_CHECKING=Agent authentication failed to process the request checking revocation status.
+CMSCORE_AUTH_CANT_FIND_PLUGIN=Can't find auth manager plugin {0}
+CMSCORE_AUTH_ADD_AUTH_INSTANCE=auths manager instance {0} added
+CMSCORE_AUTH_AUTHSUB_ERROR=AuthSubsystem: init() - {0}
+CMSCORE_AUTH_AUTH_INIT_ERROR=auths instance {0} initialization failed and skipped. error={1}
+CMSCORE_AUTH_PLUGIN_NOT_FOUND=Auth Manager plugin {0} not found.
+CMSCORE_AUTH_INSTANCE_NOT_CREATED=Could not create new authenticaiton manager instance {0}
+CMSCORE_AUTH_INSTANCE_SHUTDOWN=Shutting down auths manager instance {0}
+CMSCORE_AUTH_REVO_ATTEMPT=revocation attempted with an empty challenge for certificate serial number {0}
+CMSCORE_AUTH_INCOMPLETE_REQUEST=Failed to complete the request for an authenticating challenge phrase password
+CMSCORE_AUTH_FAILED_GET_QUEUE=Failed to get the queue
+##################################################################
+# For com.netscape.cmscore.authorization
+##################################################################
+CMSCORE_AUTHZ_PLUGIN_NOT_FOUND=Can't find authz manager plugin {0}
+CMSCORE_AUTHZ_PLUGIN_FOUND=Found authz manager plugin {0}
+CMSCORE_AUTHZ_INSTANCE_ADDED=authz manager instance {0} added
+CMSCORE_AUTHZ_PLUGIN_INIT_FAILED=authz instance {0} initialization failed and skipped, error={1}
+CMSCORE_AUTHZ_PLUGIN_NOT_CREATED=Could not create a new authorization manager instance {0}
+##################################################################
+# For com.netscape.cmscore.ca
+##################################################################
+CMSCORE_CA_START_CONNECTOR=starting CLAConnector
+CMSCORE_CA_LOAD_CONNECTOR=failed to load external connector {0} - {1}
+CMSCORE_CA_AUTHORITY_NOT_FOUND=local authority {0} not found.
+CMSCORE_CA_INVALID_REQUEST_TYPE=Unrecognized request type {0}
+CMSCORE_CA_MISSING_ATTR=Certificate Info missing validity, subject, or key in certificate issuing request
+CMSCORE_CA_PAST_VALIDITY=requested Certificate validity is past CA's validity.
+CMSCORE_CA_PAST_NOT_AFTER=requested Certificate validity is past CA's validity. Set notAfter to CA's notAfter
+CMSCORE_CA_BAD_FIELD=Cannot get certain certificate fields {0}
+CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED=signing certificate - algorithm {0} not supported in CA.
+CMSCORE_CA_NULL_SERIAL_NUMBER=Certificate serial number is null for renewal request.
+CMSCORE_CA_NO_ORG_SERIAL=No original serial number in certinfo for renewal request {0}
+CMSCORE_CA_SIGN_SERIAL=CA is going to sign certificate serial number 0x{0}
+CMSCORE_CA_NO_NEXT_SERIAL=Could not get next serial number - {0}
+CMSCORE_CA_SET_SERIAL=Failed Setting serial number. {0}
+CMSCORE_CA_SET_ISSUER=Failed Setting issuer name. {0}
+CMSCORE_CA_SET_SUBJECT=Failed Setting subject name. {0}
+CMSCORE_CA_STORE_SERIAL=CA stored signed certificate serial number 0x{0}
+CMSCORE_CA_MARK_SERIAL=CA marked certificate serial number 0x{0} as renewed with serial number 0x{1}
+CMSCORE_CA_NO_STORE_SERIAL=Could not store certificate serial number 0x{0}
+CMSCORE_CA_CERT_NOT_FOUND=Cannot find certificate serial number 0x{0}
+CMSCORE_CA_CERT_REVOKED=Revoked certificate serial number 0x{0}
+CMSCORE_CA_ERROR_REVOCATION=Error revoking certificate {0}. Error {1}
+CMSCORE_CA_CERT_ON_HOLD=Certificate {0} has to be on-hold.
+CMSCORE_CA_CERT_UNREVOKED=Unrevoked certificate serial number 0x{0}
+CMSCORE_CA_CERT_ERROR_UNREVOKE=Error unrevoking certificate 0x{0}
+CMSCORE_CA_CERT_REQUEST_NOT_FOUND=No certificates found in issuing request ID {0}
+CMSCORE_CA_ISSUE_ERROR=Error issuing certificate {0} in request ID {1}. Error {2}
+CMSCORE_CA_STORE_ERROR=Error storing certificate {0} in request ID {1}. Error {2}
+CMSCORE_CA_DELETE_CERT_ERROR=Could not delete certificate record for {0} after an error was encountered. Ignored Error: {1}
+CMSCORE_CA_ERROR_GET_CERT=Error getting Certificate serial number for renewal request. Error {0}
+CMSCORE_CA_NOT_FROM_CA=renewal certificate serial {0} is not from this CA.
+CMSCORE_CA_RENEW_REVOKED=Cannot renew revoked certificate serial {0}
+CMSCORE_CA_MISSING_RENEWED=Previously renewed certificate serial {0} missing from database.
+CMSCORE_CA_CANNOT_RENEW=Cannot issue {0}th certificate in renewal request {1}
+CMSCORE_CA_NO_RENEW=One or more certificates could not be renewed in request {0}
+CMSCORE_CA_CRL_NOT_FOUND=No CRL entries found in revocation request ID {0}
+CMSCORE_CA_CANNOT_REVOKE=Cannot revoke {0}th certificate in revocation request {1}. Error: {2}
+CMSCORE_CA_CLONE_READ_REVOKED=Clone CA about to read revoked certificates for sending
+CMSCORE_CA_CLONE_READ_ERROR=Clone CA Cannot retrieve revoked certificate for serialID: {0}
+CMSCORE_CA_CLONE_READ_REVOKED_CONNECTOR=Clone CA about to send revoked certificate via CLAConnector
+CMSCORE_CA_UNREVOKE_MISSING_SERIAL=Missing or invalid serial number
+CMSCORE_CA_UNREVOKE_FAILED=Cannot unrevoke certificate {0} in unrevocation request {1}
+CMSCORE_CA_GETCRL_FIND_CRL=Could not find CRL issuing record
+CMSCORE_CA_GETCRL_INST_CRL=Could not instantiate CRL from CRL issuing point {0}
+CMSCORE_CA_GETCRL_NO_ISSUING_REC=Could not find CRL issuing record
+CMSCORE_CA_CERT4CRL_NO_ENTRY=No CRL entries found in cert4crl request ID {0}
+CMSCORE_CA_CERT4CRL_NO_REC=Cannot record {0}th revoked certificate in cert4crl request {1} Error: {2}
+CMSCORE_CA_CRLEXTS_SAVE_CONF=Cannot save changes to the configuration file {0}
+CMSCORE_CA_CRLEXTS_NO_ENABLE=Missing enable property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_UNDEFINE_ENABLE=Undefined enable property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_INVALID_ENABLE=Invalid enable property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_NO_CRITICAL=Missing critical property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_UNDEFINE_CRITICAL=Undefined critical property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_INVALID_CRITICAL=Invalid critical property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_INVALID_EXT=Invalid type property for CRL extension {0} set to {1}
+CMSCORE_CA_CRLEXTS_UNDEFINE_EXT=Undefined type property for CRL extension {0}
+CMSCORE_CA_CRLEXTS_MISSING_EXT=Missing type property for CRL extension {0}
+CMSCORE_CA_CRLEXTS_CLASS_NOT_FOUND=Failed to find CRL extension plugin class {0} Error: {1}
+CMSCORE_CA_CRLEXTS_CLASS_NOT_INST=Failed CRL extension plugin class instantiation {0} Error: {1}
+CMSCORE_CA_CRLEXTS_CLASS_NOT_ACCESS=Failed to access CRL extension plugin class {0} Error: {1}
+CMSCORE_CA_CRLEXTS_CLASS_NOT_DEFINED=Undefined class property for CRL extension {0}
+CMSCORE_CA_CRLEXTS_CLASS_MISSING=Missing class property for CRL extension {0}
+CMSCORE_CA_CRLEXTS_CLASS_INVALID=Invalid class property for CRL extension {0}
+CMSCORE_CA_CRLEXTS_CLASS_ADD=Failed to add extension {0} to CRL. Error: {1}
+CMSCORE_CA_ISSUING_DECODE_CRL=Failed to decode CRL in the DB at CRL init. Error {0}. Creating a new CRL.
+CMSCORE_CA_ISSUING_INST_CRL=Cannot initialize CRL from the internaldb. The internaldb is down. Error {0}
+CMSCORE_CA_ISSUING_CREATE_CRL=Cannot create or store the first CRL in the internaldb. The internaldb could be down. Error {0}
+CMSCORE_CA_ISSUING_START_CRL=started automatic CRL update thread CRLIssuingPoint-{0}
+CMSCORE_CA_ISSUING_CRL=Cannot {0}. Error: {1}
+CMSCORE_CA_ISSUING_STORE_REVOKED_CERT=Failed to store revoked certificate's cache for {0}. Error {1}
+CMSCORE_CA_ISSUING_STORE_UNREVOKED_CERT=Failed to store unrevoked certificate's cache for {0}. Error {1}
+CMSCORE_CA_ISSUING_STORE_EXPIRED_CERT=Failed to store expired certificate's cache for {0}. Error {1}
+CMSCORE_CA_ISSUING_STORE_CRL_CACHE=Cannot store the CRL cache in the internaldb. Error {0}
+CMSCORE_CA_ISSUING_SIGN_OR_STORE_DELTA=Failed to sign or store delta-CRL {0}
+CMSCORE_CA_ISSUING_SIGN_DELTA=Failed to sign delta-CRL {0}
+CMSCORE_CA_ISSUING_SIGN_OR_STORE_CRL=Failed to sign or store CRL {0}
+CMSCORE_CA_ISSUING_SIGN_CRL=Failed to sign CRL {0}
+CMSCORE_CA_ISSUING_PUBLISH_DELTA=Failed to publish delta-CRL #{0}. Error {1}
+CMSCORE_CA_ISSUING_PUBLISH_CRL=Failed to publish CRL #{0}. Error {1}
+CMSCORE_CA_ISSUING_UPDATE_CRL=update CRL returned {0}
+CMSCORE_CA_CA_CRL_UPDATE_STARTED=CRL update started. CRL ID: {0} CRL Number: {1} Delta CRL Enabled: {2} CRL Cache Enabled: {3} Cache Recovery Enabled: {4} Cache Cleared: {5} Cache: {6}
+CMSCORE_CA_CA_CRL_UPDATED=CRL Update completed. CRL ID: {0} CRL Number: {1} last update time: {2} next update time: {3} Number of entries in the CRL: {4} time: {5} CRL time: {6} delta CRL time: {7}
+CMSCORE_CA_CA_DELTA_CRL_UPDATED=Delta-CRL update completed. CRL ID: {0} Delta CRL NUmber: {1} Against CRL Number: {2} last update time: {3} next update time: {4} Number of entries in the delta-CRL: {5} time: {6}
+CMSCORE_CA_CA_NO_PUBLISHER=No publisher enabled {0}
+CMSCORE_CA_CA_SIGN_CRL=Failed to sign CRL {0}:{1}
+CMSCORE_CA_CA_NO_CERTINFO=sign cert, certInfo NULL!
+CMSCORE_CA_CA_SIGN_CERT=Failed to sign certificate {0}:{1}
+CMSCORE_CA_CA_OCSP_SIGNING=Crypto manager not initialized {0}
+CMSCORE_CA_CA_OCSP_CHAIN=Cannot build CA chain. Error {0}
+CMSCORE_CA_CA_PUBLISH=Could not publish CA signing certificate at startup. {0}
+CMSCORE_CA_CA_NO_PUBLISH=No CA Publishing Module configuration found
+CMSCORE_CA_CA_ERROR_PUBLISH_MODULE=CA's Publishing Module failed with {0}
+CMSCORE_CA_CA_ERROR_LISTENER=Can't find listener plugin {0}
+CMSCORE_CA_CA_INIT_LISTENER=failed to initialize listener instance {0} {1}
+CMSCORE_CA_CA_FAILED_LISTENER=Initialization of listener plugins failed {0}
+CMSCORE_CA_CA_REGISTER_LISTENER=Failed to register Certificate Issued Listener {0}
+CMSCORE_CA_CA_REGISTER_REQ_LISTENER=Failed to register Request In Queue Listener {0}
+CMSCORE_CA_CA_NOTIFY_NONE=No CA notification Module configuration found
+CMSCORE_CA_CA_NOTIFY_FAILED=CA notification Module initialization failure
+CMSCORE_CA_CA_QUEUE_FAILED=Cannot create request queue {0}
+CMSCORE_CA_CA_NO_MASTER_CRL=No configuration for Master CRL found.
+CMSCORE_CA_CA_NO_MASTER_CRL_SUBSTORE=No configuration for Master CRL found. Missing substores.
+CMSCORE_CA_CA_NO_FULL_CRL=No configuration for full CRL. Missing CRL issuing point {0}
+CMSCORE_CA_CA_OCSP_REQUEST=request processing failure {0}
+CMSCORE_CA_CA_OCSP_SIGN=sign OCSP response {0}
+CMSCORE_CA_SIGNING_CA_CERT=Cannot convert CA certificate to X509CertImpl {0}
+CMSCORE_CA_SIGNING_TOKEN_INIT=CryptoManager not initialized. Error {0}
+CMSCORE_CA_SIGNING_WRONG_PWD=Incorrect password for CA signing unit. Exception {0}
+CMSCORE_CA_SIGNING_TOKEN_NOT_FOUND=Token {0} Not found. Error {1}
+CMSCORE_CA_SIGNING_CERT_NOT_FOUND=Object certificate not found. Error {0}
+CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED=Signing Algorithm {0} not supported - {1}
+CMSCORE_CA_INVALID_TIME_LIST=Daily updates are DISABLED because time list has invalid format.
+CMSCORE_CA_INVALID_PROFILE_LIST=CRL generation according to profile list is DISABLED because profile list has invalid format.
+##################################################################
+# For com.netscape.cmscore.cert
+##################################################################
+CMSCORE_CERT_DIR_STRING={0} must be a list of DER tag names seperated by commas.
+CMSCORE_CERT_UNKNOWN_TAG={0} unknown DER tag - {1}.
+##################################################################
+# For com.netscape.cmscore.connector
+##################################################################
+CMSCORE_CONNECTOR_REQUEST_NOT_COMPLETED=remote request for {0} not completed. Queing for resend.
+CMSCORE_CONNECTOR_SEND_REQUEST=Could not send request {0} to remote {1} : {2}
+CMSCORE_CONNECTOR_RESENDER_INTERRUPTED=Resender thread was interrupted to resend.
+CMSCORE_CONNECTOR_REQUEST_NOT_FOUND=Resend: Cannot find {0} in request queue
+CMSCORE_CONNECTOR_REQUEST_COMPLETED=resent request {0} completed.
+CMSCORE_CONNECTOR_REQUEST_ERROR=sending request {0} got error {1}
+CMSCORE_CONNECTOR_DOWN=The connection is down. Resend all pending requests later.
+CMSCORE_CONNECTOR_RESEND_ERROR=error in resending request {0} - {1}
+##################################################################
+# For com.netscape.cmscore.dbs
+##################################################################
+CMSCORE_DBS_START_VALID_SEARCH=Start Valid Certificates Search
+CMSCORE_DBS_FINISH_VALID_SEARCH=Finish Valid Certificates Search
+CMSCORE_DBS_START_EXPIRED_SEARCH=Start Expired Certificates Search
+CMSCORE_DBS_FINISH_EXPIRED_SEARCH=Finish Expired Certificates Search
+CMSCORE_DBS_START_REVOKED_EXPIRED_SEARCH=Start Revoked & Expired Certificates Search
+CMSCORE_DBS_FINISH_REVOKED_EXPIRED_SEARCH=Finish Revoked & Expired Certificates Search
+CMSCORE_DBS_TRANSIT_INVALID_TO_VALID=Transit Certificate #{0} from INVALID to VALID status
+CMSCORE_DBS_TRANSIT_INCONSISTENCY=Inconsistency Detected: Transit Certificate #{0} ({1}) from INVALID to VALID status at - {2}
+CMSCORE_DBS_TRANSIT_VALID_TO_EXPIRED=Transit Certificate #{0} from INVALID to VALID status
+CMSCORE_DBS_TRANSIT_INCONSISTENCY_VALID_TO_EXPIRED=Inconsistency Detected: Transit Certificate #{0} ({1}) from VALID to EXPIRED status at - {2}
+CMSCORE_DBS_TRANSIT_REVOKED_TO_REVOKED_EXPIRED=Transit Certificate #{0} from REVOKED to REVOKED_EXPIRED status
+CMSCORE_DBS_TRANSIT_INCONSISTENCY_REVOKED_TO_REVOKED_EXPIRED=Inconsistency Detected: Transit Certificate #{0} ({1}) from REVOKED to REVOKED EXPIRED status at - {2}
+CMSCORE_DBS_ATTR_NOT_REGISTER=attribute {0} is not registered
+CMSCORE_DBS_CONN_ERROR=Failed to get a connection to the LDAP server. Error {0}
+CMSCORE_DBS_SCHEMA_ERROR=Failed to add a schema entry. Error {0}
+CMSCORE_DBS_CONF_ERROR=Failed to retrieve configuration parameters. Error {0}
+CMSCORE_DBS_VL_ADD=Virtual List Add Element {0}
+CMSCORE_DBS_VL_CORRUPTED_ENTRIES=database with {0} corrupted entries - unrecoverable
+CMSCORE_DBS_VL_NULL_RESPONSE=Null response control
+CMSCORE_DBS_KEYRECORD_MAPPER_ERROR=Key Mapper Error {0}
+CMSCORE_DBS_OBJECTSTREAM_MAPPER_ERROR=Object Stream Mapper Error {0}
+CMSCORE_DBS_PUBLICKEY_MAPPER_ERROR=Public Key Mapper Error {0}
+CMSCORE_DBS_X500NAME_MAPPER_ERROR=X500Name Mapper Error {0}
+##################################################################
+# For com.netscape.cmscore.jobs
+##################################################################
+CMSCORE_JOBS_INVALID_TOKEN={0} invalid format - {1}
+CMSCORE_JOBS_INVALID_RANGE=invalid range - {0}
+CMSCORE_JOBS_INVALID_MIN_MAX_RANGE=invalid range - {0} - {1}
+CMSCORE_JOBS_INVALID_MIN=Invalid minute - {0}
+CMSCORE_JOBS_INVALID_HOUR=Invalid hour - {0}
+CMSCORE_JOBS_INVALID_MONTH=Invalid month of year - {0}
+CMSCORE_JOBS_INVALID_DAY_OF_WEEK=Invalid day of week - {0}
+CMSCORE_JOBS_INVALID_DAY_OF_MONTH=Invalid day of month - {0}
+CMSCORE_JOBS_CLASS_NOT_FOUND=Can't find job plugin {0}
+CMSCORE_JOBS_INIT_ERROR=Initialization Error {0}
+CMSCORE_JOBS_CREATE_NEW=Could not create new job instance {0}
+##################################################################
+# For com.netscape.cmscore.kra
+##################################################################
+CMSCORE_KRA_ENCRYPTION_INTERNAL=EncryptionUnit::encryptInternalPrivate {0}
+CMSCORE_KRA_ENCRYPTION_WRAP=EncryptionUnit::wrap {0}
+CMSCORE_KRA_ENCRYPTION_EXTERNAL=EncryptionUnit::decryptExternalPrivate {0}
+CMSCORE_KRA_ENCRYPTION_UNWRAP=EncryptionUnit::unwrap {0}
+CMSCORE_KRA_ENCRYPTION_DECRYPT=EncryptionUnit::decryptInternalPrivate {0}
+CMSCORE_KRA_UNWRAP_USER_KEY=Unwrap user key failed
+CMSCORE_KRA_PUBLIC_NOT_FOUND=Public Key Not Found
+CMSCORE_KRA_OWNER_NAME_NOT_FOUND=Owner Name Not Found
+CMSCORE_KRA_WRAP_USER_KEY=Wrap user key failed
+CMSCORE_KRA_INVALID_SERIAL_NUMBER=Invalid Serial Number {0}
+CMSCORE_KRA_GET_NEXT_SERIAL=get next serial number failed
+CMSCORE_KRA_GET_PUBLIC_KEY=retrieve x509 public key failed {0}
+CMSCORE_KRA_GET_OWNER_NAME=retrieve owner name failed {0}
+CMSCORE_KRA_REGISTER_LISTENER=Failed to register Request In Queue Listener {0}
+CMSCORE_KRA_NOTIFY_ERROR=KRA notification Module initialization failure {0}
+CMSCORE_KRA_INVALID_RA_NAME=Invalid RA name {0} - {1}
+CMSCORE_KRA_INVALID_RA_SETUP=No properly configured accepted RAs {0}
+CMSCORE_KRA_PUBLIC_KEY_LEN=public key length not matched
+CMSCORE_KRA_PRIVATE_KEY_NOT_FOUND=private key data not found
+CMSCORE_KRA_CONSTRUCT_P12=construct PKCS #12 failed {0}
+CMSCORE_KRA_CREAT_KEY_ID=create key ID failed {0}
+CMSCORE_KRA_CREAT_KEY_BAG=create key bag failed {0}
+CMSCORE_KRA_STORAGE_INIT=initialization failed - {0}
+CMSCORE_KRA_LOCATE_CERT=locate certificate in hardware failed {0}
+CMSCORE_KRA_STORAGE_READ_CERT=read storage certificate failed {0}
+CMSCORE_KRA_STORAGE_IMPORT_CERT=import certificate failed {0}
+CMSCORE_KRA_STORAGE_READ_PRIVATE=read storage private key failed {0}
+CMSCORE_KRA_STORAGE_READ_MN=read MN file failed {0}
+CMSCORE_KRA_STORAGE_LOGIN=login failed {0}
+CMSCORE_KRA_STORAGE_LOGOUT=logout failed {0}
+CMSCORE_KRA_STORAGE_CHANGE_MN=change MN failed {0}
+CMSCORE_KRA_STORAGE_RECONSTRUCT=reconstruct password failed {0}
+CMSCORE_KRA_ENTROPY_COLLECTION_DISABLED=DRM Entropy collection disabled
+CMSCORE_KRA_ENTROPY_COLLECTION_ENABLED=DRM Entropy collection enabled
+CMSCORE_KRA_ENTROPY_BLOCKED_WARNING=DRM Entropy collection blocked for {0}ms. Suggest increasing warning duration (kra.entropy.blockwarnms) or decreasing number of entropy bits collected (kra.entropy.bitsperkeypair)
+CMSCORE_KRA_ENTROPY_ERROR=Error collecting DRM entropy: {0}
+##################################################################
+# For com.netscape.cmscore.ldap
+##################################################################
+CMSCORE_LDAP_FIND_CLASS=Could not find class {0}
+CMSCORE_LDAP_INST_CLASS=could not instantiate class {0} under type {1}
+CMSCORE_LDAP_INSUFFICIENT_CREDENTIALS=insufficient credentials to instantiate class {0} for type {1}
+CMSCORE_LDAP_INIT_ERROR=Failed initialization of type {0}. Error {1}
+CMSCORE_LDAP_PUBLISH_NOT_MATCH=certificate serial 0x{0} subject name {1} does not match any entry in the directory.
+CMSCORE_LDAP_CRL_NOT_MATCH=CRL did not map to any DN
+CMSCORE_LDAP_CERT_NOT_PUBLISH=Could not publish certificate serial number 0x{0}. Error {1}
+CMSCORE_LDAP_CERT_NOT_UNPUBLISH=Could not unpublish certificate serial number 0x{0}. Error {1}
+CMSCORE_LDAP_CERT_NOT_FIND=Could not find certificate to unpublish. serial number 0x{0}. Error {1}
+CMSCORE_LDAP_GET_CERT_RECORD=Error getting certificate record to revoke 0x{0}. Error {1}
+CMSCORE_LDAP_RULE_NOT_FOUND=Can't find publishing rule plugin {0}
+CMSCORE_LDAP_INIT_FAILED=LdapSubsystem::init() - {0}
+CMSCORE_LDAP_RULE_NOT_MATCH=No matched rule for request {0}
+CMSCORE_LDAP_RULE_UNEXPECTED_ERROR=Rule {0} encountered unexpected error {1}
+CMSCORE_LDAP_PLUGIN_NOT_FIND=Can't find publisher plugin {0}
+CMSCORE_LDAP_PUBLISHER_INIT_FAILED=PublisherProcessor::init() - {0}
+CMSCORE_LDAP_SKIP_PUBLISHER=publisher instance {0} initialization failed and skipped. error={1}
+CMSCORE_LDAP_MAPPER_NOT_FIND=Can't find mapper plugin {0}
+CMSCORE_LDAP_SKIP_MAPPER=mapper instance {0} initialization failed and skipped. error={1}
+CMSCORE_LDAP_RULE_NOT_FIND=Can't find rule plugin {0}
+CMSCORE_LDAP_SKIP_RULE=rule instance {0} initialization failed and skipped. error={1}
+CMSCORE_LDAP_NO_NEW_MAPPER=Could not create new mapper instance {0}
+CMSCORE_LDAP_NO_NEW_PUBLISHER=Could not create new publisher instance {0}
+CMSCORE_LDAP_NO_NEW_RULE=Could not create new rule instance {0}
+CMSCORE_LDAP_NO_RULE_FOUND=No rule can be found for publishing: {0}
+CMSCORE_LDAP_NO_UNPUBLISHING_RULE_FOUND=No rule can be found for unpublishing: {0}
+CMSCORE_LDAP_NO_RULE_FOUND_FOR_REQUEST=No rule can be found for publishing: {0} request {1}
+CMSCORE_LDAP_NO_UNPUBLISHING_RULE_FOUND_FOR_REQUEST=No rule can be found for unpublishing: {0} request {1}
+CMSCORE_LDAP_NO_RULE_FOR_CRL=No rule can be found for publishing CRL
+CMSCORE_LDAP_MAPPER_NOT_MAP=mapper {0} did not map to any DN
+##################################################################
+# For com.netscape.cmscore.ldapconn
+##################################################################
+CMSCORE_LDAPCONN_MIN_CONN=The parameter for min connections is not an integer
+CMSCORE_LDAPCONN_MAX_CONN=The parameter for max connections is not an integer
+CMSCORE_LDAPCONN_CONNECT_SERVER=Cannot connect to LDAP server. Error: LDAP Server host {0} port {1} is unavailable
+CMSCORE_LDAPCONN_FAILED_SERVER=Cannot connect to LDAP server. Error: {0}
+CMSCORE_LDAPCONN_CANNOT_RESET=Cannot reset conn factory: {0}
+CMSCORE_LDAPCONN_UNKNOWN_HOST=Unknown Host creating JSS SSL Socket
+CMSCORE_LDAPCONN_IO_ERROR=I/O Error creating JSS SSL Socket {0}
+##################################################################
+# For com.netscape.cmscore.notification
+##################################################################
+CMSCORE_NOTIFY_TEMPLATE_NULL=template null
+CMSCORE_NOTIFY_TOKEN_NULL=Token2vals null
+CMSCORE_NOTIFY_TEMPLATE_NOT_EXIST=Template: {0} does not exist or is invalid
+CMSCORE_NOTIFY_TEMPLATE_NOT_FOUND=Template: {0} not found
+CMSCORE_NOTIFY_TEMPLATE_LOAD_ERROR=Template: Error loading file into string
+CMSCORE_NOTIFY_TEMPLATE_LOADING=Template: Error loading file
+CMSCORE_NOTIFY_NO_EMAIL=no email resolved for {0}
+CMSCORE_NOTIFY_NO_EMAIL_ID=no email resolved for request ID={0}
+CMSCORE_NOTIFY_NO_EMAIL_REQUEST=no email resolved. No request ID or certificate info found
+CMSCORE_NOTIFY_NO_CERTINFO=Error getting certinfo from certificate
+CMSCORE_NOTIFY_GET_EXT=Error getting extensions: {0}
+CMSCORE_NOTIFY_SUBJECTALTNAME=get subjectalternatename extension failed
+##################################################################
+# For com.netscape.cmscore.ocsp
+##################################################################
+CMSCORE_OCSP_SIGNING_UNIT=Signing Unit init() {0}
+CMSCORE_OCSP_CLASSPATH=ClassPath ID={0} {1}
+CMSCORE_OCSP_RETRIEVE_KEY=retrieve public key failure {0}
+CMSCORE_OCSP_SIGNING=Crypto manager not initialized {0}
+CMSCORE_OCSP_CHAIN=Cannot build CA chain. Error {0}
+CMSCORE_OCSP_SIGN_RESPONSE=Sign OCSP Response {0}
+CMSCORE_OCSP_CONVERT_X509=Cannot convert OCSP certificate to X509CertImpl {0}
+CMSCORE_OCSP_INCORRECT_PWD=Incorrect password for OCSP signing unit. Exception {0}
+CMSCORE_OCSP_TOKEN_NOT_FOUND=Token {0} Not found. Error {1}
+CMSCORE_OCSP_OBJECT_NOT_FOUND=Object Not found. Error {0}
+CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED=Signing Algorithm {0} not supported.
+CMSCORE_OCSP_INVALID_ENCODING=Invalid encoding in OCSP signing key.
+##################################################################
+# For com.netscape.cmscore.policy
+##################################################################
+CMSCORE_POLICY_INIT_FAILED=policy {0} initialization failed and skipped. exception={1}
+CMSCORE_POLICY_DEF_CREATE=Cannot create default policy Error {0}
+CMSCORE_POLICY_EVAULATOR_ERROR=Javascript Evaluator error: {0}
+CMSCORE_POLICY_REJECT_RESULT=policy: Request {0} - Result of applying rule: {1} is : rejected
+CMSCORE_POLICY_DEFER_RESULT=policy: Request {0} - Result of applying rule: {1} is : deferred
+CMSCORE_POLICY_ERROR_RESULT=policy: Request {0} - Result of applying rule: {1} has : encountered unexpected error {2}
+##################################################################
+# For com.netscape.cmscore.ra
+##################################################################
+CMSCORE_RA_GET_CA_CERT=Could not get CA certificate chain. Error {0}
+CMSCORE_RA_REGISTER_CERT_LISTENER=Failed to register Certificate Issued Listener {0}
+CMSCORE_RA_REGISTER_REQ_LISTENER=Failed to register Request In Queue Listener {0}
+CMSCORE_RA_NO_NOTIFY=No RA notification Module configuration found
+CMSCORE_RA_NOTIFY_INIT=RA notification Module initialization failure
+CMSCORE_RA_UNREC_REQUEST=Unrecognized request type {0} in RA listener
+CMSCORE_RA_NO_CHAIN=CA Chain listener - no chain from listener!
+CMSCORE_RA_CANNOT_CONVERT=Could not convert CA to X509CertImpl! Error {0}
+CMSCORE_RA_NO_CA=No CA: RA cannot operate without a CA
+CMSCORE_RA_LOAD_CONNECTOR=failed to load external connector {0} {1}
+##################################################################
+# For com.netscape.cmscore.security
+##################################################################
+CMSCORE_SECURITY_INCORRECT_PWD=password incorrect
+CMSCORE_SECURITY_TOKEN_ERROR=token error {0}
+CMSCORE_SECURITY_KEY_DB_ERROR=Key Database Error {0}
+CMSCORE_SECURITY_CERT_DB_ERROR=Certificate Database Error {0}
+CMSCORE_SECURITY_CRYPTO_ERROR=Crypto Initialization Error {0}
+CMSCORE_SECURITY_GENERAL_ERROR=General Security Error {0}
+CMSCORE_SECURITY_INSTALL_PROVIDER=Unable to install CS provider.
+CMSCORE_SECURITY_INVALID_CIPHER=Invalid SSL cipher preferences value {0}
+CMSCORE_SECURITY_TOKEN_LOGGED_IN=Token logged in {0}
+CMSCORE_SECURITY_SUBJECT_NAME=Certificate subject name {0}
+CMSCORE_SECURITY_ALG=Signature Algorithm error {0}
+CMSCORE_SECURITY_KEY_PAIR=Generate Key Pair Error {0}
+CMSCORE_SECURITY_X500_NAME=X500 Name {0}
+CMSCORE_SECURITY_CERT_REQUEST=Certificate Request Error {0}
+CMSCORE_SECURITY_IMPORT_CERT=Import certificate {0}
+CMSCORE_SECURITY_CERT_INFO=Certificate Info {0}
+CMSCORE_SECURITY_GET_ALL_CERT=Get all certificates to manage {0}
+CMSCORE_SECURITY_GET_CA_CERT=Get CA Certificates {0}
+CMSCORE_SECURITY_GET_CA_CERT_FOR=Get CA Certificates for {0} : {1}
+CMSCORE_SECURITY_TRUST_CERT=Trust Certificate {0}
+CMSCORE_SECURITY_DELETE_CA_CERT=Delete CA Certificate {0}
+CMSCORE_SECURITY_DELETE_CERT=Delete Certificate {0}
+CMSCORE_SECURITY_GET_SUBJECT_NAME=Get Subject Name {0}
+CMSCORE_SECURITY_PRINT_CERT=Print CERT {0}
+CMSCORE_SECURITY_SIGN_CERT=Sign Certificate {0}
+CMSCORE_SECURITY_IS_CA_CERT=isCACert {0}
+CMSCORE_SECURITY_GET_EXTENSIONS=Get Extensions {0}
+CMSCORE_SECURITY_GET_CONFIG=failed at CMS.getConfigStore() for pwCache
+CMSCORE_SECURITY_THROW_CALLBACK=throwing PasswordCallback.GiveUpException()
+CMSCORE_SECURITY_PW_FILE=failure for file {0} {1}
+CMSCORE_SECURITY_PW_DECRYPT=password cache decrypt failed {0}
+CMSCORE_SECURITY_PW_ENCRYPT=password cache encrypt failed {0}
+CMSCORE_SECURITY_PW_CACHE=sdrPWcache: Error {0}
+CMSCORE_SECURITY_PW_READ=failed readPWcache() {0}
+CMSCORE_SECURITY_PW_TAG=getEntry did not get password for tag={0}
+CMSCORE_SECURITY_NO_ENTROPY_STREAM=No o/s entropy stream available
+##################################################################
+# For com.netscape.cmscore.selftests
+##################################################################
+CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION=SelfTestSubsystem: Initializing self test plugins:
+CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL=SelfTestSubsystem: the self test property name is null
+CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME=SelfTestSubsystem: the self test property name {0} is a duplicate
+CMSCORE_SELFTESTS_PROPERTY_INVALID_INSTANCE=SelfTestSubsystem: the self test property name {0} with a value of {1} specifies an invalid instance
+CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME=SelfTestSubsystem: the self test property name {0} does not exist
+CMSCORE_SELFTESTS_PROPERTY_MISSING_VALUES=SelfTestSubsystem: the self test property name {0} contained no value(s)
+CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION=SelfTestSubsystem: the self test property name {0} with a value of {1} threw an EBaseException
+CMSCORE_SELFTESTS_PROPERTY_THREW_EXCEPTION=SelfTestSubsystem: the self test property name {0} with a value of {1} threw an Exception
+CMSCORE_SELFTESTS_LOAD_LOGGER_PARAMETERS=SelfTestSubsystem: loading all self test plugin logger parameters
+CMSCORE_SELFTESTS_DONT_LOAD_LOGGER_PARAMETERS=SelfTestSubsystem: there are NO self test plugin logger parameters to load
+CMSCORE_SELFTESTS_LOAD_PLUGINS=SelfTestSubsystem: loading all self test plugin instances
+CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS=SelfTestSubsystem: there are NO self test plugin instances to load
+CMSCORE_SELFTESTS_LOAD_PLUGIN_PARAMETERS=SelfTestSubsystem: loading all self test plugin instance parameters
+CMSCORE_SELFTESTS_PLUGIN_DUPLICATE_PARAMETER=SelfTestSubsystem: the self test plugin instance {0} contains the duplicate parameter {1}
+CMSCORE_SELFTESTS_PLUGIN_MISSING_PARAMETER=SelfTestSubsystem: the self test plugin instance {0} is missing the mandatory parameter {1}
+CMSCORE_SELFTESTS_PLUGIN_INVALID_PARAMETER=SelfTestSubsystem: the self test plugin instance {0} contains the invalid parameter {1}
+CMSCORE_SELFTESTS_LOAD_PLUGINS_ON_DEMAND=SelfTestSubsystem: loading self test plugins in on-demand order
+CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS_ON_DEMAND=SelfTestSubsystem: there are NO self test plugins to load in on-demand order
+CMSCORE_SELFTESTS_MISSING_ON_DEMAND_VALUES=SelfTestSubsystem: self test plugins on-demand order property name {0} contained no values
+CMSCORE_SELFTESTS_LOAD_PLUGINS_AT_STARTUP=SelfTestSubsystem: loading self test plugins in startup order
+CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS_AT_STARTUP=SelfTestSubsystem: there are NO self test plugins to load in startup order
+CMSCORE_SELFTESTS_MISSING_STARTUP_VALUES=SelfTestSubsystem: self test plugins startup order property name {0} contained no values
+CMSCORE_SELFTESTS_PLUGINS_LOADED=SelfTestSubsystem: Self test plugins have been successfully loaded!
+CMSCORE_SELFTESTS_PLUGINS_NONE_LOADED=SelfTestSubsystem: There were NO self test plugins to be loaded!
+CMSCORE_SELFTESTS_RUN_ON_DEMAND=SelfTestSubsystem: Running self test plugins specified to be executed on-demand:
+CMSCORE_SELFTESTS_NOT_RUN_ON_DEMAND=SelfTestSubsystem: There were NO self test plugins specified to be run on-demand!
+CMSCORE_SELFTESTS_RUN_ON_DEMAND_SUCCEEDED=SelfTestSubsystem: All CRITICAL self test plugins ran SUCCESSFULLY on-demand!
+CMSCORE_SELFTESTS_RUN_ON_DEMAND_FAILED=SelfTestSubsystem: The CRITICAL self test plugin called {0} running on-demand FAILED!
+CMSCORE_SELFTESTS_RUN_AT_STARTUP=SelfTestSubsystem: Running self test plugins specified to be executed at startup:
+CMSCORE_SELFTESTS_NOT_RUN_AT_STARTUP=SelfTestSubsystem: There were NO self test plugins specified to be run at startup!
+CMSCORE_SELFTESTS_RUN_AT_STARTUP_SUCCEEDED=SelfTestSubsystem: All CRITICAL self test plugins ran SUCCESSFULLY at startup!
+CMSCORE_SELFTESTS_RUN_AT_STARTUP_FAILED=SelfTestSubsystem: The CRITICAL self test plugin called {0} running at startup FAILED!
+##################################################################
+# For com.netscape.cmscore.usrgrp
+##################################################################
+CMSCORE_USRGRP_LDAP_SHUT=LDAP Shutdown Error {0}
+CMSCORE_USRGRP_GET_USER=Get User Error {0}
+CMSCORE_USRGRP_FIND_USER=Find User Error {0}
+CMSCORE_USRGRP_INTERNAL_DB=find User: Could not get connection to internaldb. Error {0}
+CMSCORE_USRGRP_FIND_USER_BY_CERT=Find User By Certificate Error {0}
+CMSCORE_USRGRP_FIND_USERS=Find Users Error {0}
+CMSCORE_USRGRP_LIST_USERS=List Users Error {0}
+CMSCORE_USRGRP_BUILD_USER=DN not found
+CMSCORE_USRGRP_ADD_USER=add User: Could not get connection to internaldb. Error {0}
+CMSCORE_USRGRP_ADD_USER_CERT=add User Certificate {0}
+CMSCORE_USRGRP_REMOVE_USER=remove User {0}
+CMSCORE_USRGRP_REMOVE_USER_FROM_GROUP=remove User From Group {0}
+CMSCORE_USRGRP_FIND_GROUPS=Find Group {0}
+CMSCORE_USRGRP_LIST_GROUPS=List Group {0}
+CMSCORE_USRGRP_BUILD_GROUP=Build Group {0}
+CMSCORE_USRGRP_BAD_GROUP_MEMBER=Build Group Error: {0} group did not accept malformed uniquemember attribute: {1}
+CMSCORE_USRGRP_GET_GROUP=Get Group {0}
+CMSCORE_USRGRP_IS_GROUP_PRESENT=Is Group Present {0}
+CMSCORE_USRGRP_ADD_GROUP=Add Group {0}
+CMSCORE_USRGRP_REMOVE_GROUP=Remove Group {0}
+CMSCORE_USRGRP_MODIFY_GROUP=Modify Group {0}
+CMSCORE_USRGRP_CONVERT_UID=ConvertUID To DN {0}
+##################################################################
+# For com.netscape.certsetup.base
+##################################################################
+CERTSETUP_CREATE_DB_FAILED=Failed to create internal database
+CERTSETUP_RESTART_DB_FAILED=Failed to restart internal database
+CERTSETUP_DELETE_FILE_FAILED=Failed to delete file: {0}
+CERTSETUP_INSTALL_DB_FAILED=Failed to install internal database
+CERTSETUP_CONNECT_DB_FAILED=Failed to connect to internal database
+CERTSETUP_ADD_ENTRY_FAILED=Failed to add entry to database: {0}
+CERTSETUP_CREATE_ENTRY_FAILED=Failed to create entry to database. Please check if appropriate suffix is setup in the directory server: {0}.
+CERTSETUP_PORT_USED=Port {0} has already been used
+CERTSETUP_INSTANCE_EXISTED=Internal database already exists
+CERTSETUP_INSTANCE_NAME_USED=Instance name {0} has been used. Re-enter another name
+CERTSETUP_INVALID_PARAMS=Invalid parameters - {0}
+CERTSETUP_INTERRUPTED=The process was interrupted
+CERTSETUP_INVALID_PARAMS=Invalid parameters - {0}
+CERTSETUP_GENERATE_PQG_FAILED=Failed to generate PQG parameters
+CERTSETUP_INCORRECT_SIE_SETUP=The SIE is not setup correctly
+CERTSETUP_MISSING_O_ATTR=Missing O (organization) attribute
+CERTSETUP_MISSING_C_ATTR=Missing C (country) attribute
+CERTSETUP_INVALID_C_ATTR=Invalid C (country) attribute value which should not contain more than 2 characters
+CERTSETUP_INVALID_CREDENTIALS=Invalid Credentials
+CERTSETUP_RSA_NOT_SUPPORTED=RSA is not supported
+CERTSETUP_DSA_NOT_SUPPORTED=DSA is not supported
+CERTSETUP_KEY_LENGTH_NOT_SUPPORTED=Key length {0} is not supported
+CERTSETUP_INCORRECT_PASSWORD=Incorrect password
+CERTSETUP_INVALID_NOT_AFTER=End date should not go beyond the end date of the CA signing certificate
+CERTSETUP_INVALID_FILE_PATH=Invalid file pathname
+CERTSETUP_TOKEN_ERROR=Token Error
+CERTSETUP_CERT_NOT_FOUND=Certificate not found
+CERTSETUP_USERCERT_CONFLICT=User certificate has conflict
+CERTSETUP_NICKNAME_CONFLICT=Nickname conflict
+CERTSETUP_CERT_ENCODE_ERROR=Certificate encoding error
+CERTSETUP_NOT_TOKEN_CERT=Not a token certificate
+CERTSETUP_NO_SUCH_TOKEN=No such token
+CERTSETUP_INCORRECT_TOKEN_PASSWD=Incorrect token password
+CERTSETUP_CERT_ALREADY_EXISTED=A certificate with the given nickname ({0}) already resides on the token. You need to clean up the token before proceeding.
+CERTSETUP_CHMOD_FAILED=Failed to change file permissions.
+CERTSETUP_CREATE_WEBSERVER_FAILED=Failed to create a web server instance.
+##################################################################
+# For com.netscape.certsrv.acls
+##################################################################
+ACLS_FAILED_TO_CONNECT_LDAP_1=Failed to connect to LDAP server: {0}
+ACLS_FAIL_CLASS_LOAD_1=Failed to load class: {0}
+ACLS_SRVLT_NO_CLASS=class not found
+ACLS_NO_PERMISSION_2={0} does not have permission to {1}
+ACLS_NO_PERMISSION=no permission
+ACLS_SRVLT_RESOURCE_NOT_FOUND=ACLs resource not found
+ACLS_SRVLT_FAIL_RS_UPDATE=failed to update resource ACLs
+ACLS_FAIL_ACL_UPDATE=failed to update ACLs on LDAP
+ACLS_ACL_METHOD_NOT_IMPLD=ACL method not implemented
+ACLS_SRVLT_ILL_CLASS=class must extend IAccessEvaluator
+ACLS_SRVLT_FAIL_COMMIT=Failed to save changes to the configuration file
+ACLS_FAIL_ACL_PARSE=failed to parse ACLs
+ACLS_SRVLT_EVAL_NOT_FOUND=evaluator not found
+ACLS_SRVLT_FAIL_INST_CLASS=failed to instantiate class
+ACLS_ACL_NULL_VALUE_1={0} value can not be null
+ACLS_ACL_PARSING_ERROR_2=ACL parsing error for {0}: {1}
+##################################################################
+# For com.netscape.certsrv.authentication
+##################################################################
+AUTH_INVALID_CREDENTIALS=Invalid Credentials
+AUTH_MISSING_CREDENTIAL_1=Missing required credential {0}
+AUTH_FAIL_LOAD_CLASS_1=Could not load authentication manager class {0}
+AUTH_AUTH_MGR_NOT_FOUND_1=Authentication {0} not found
+AUTH_AUTH_MGR_PLUGIN_NOT_FOUND_1=Authentication manager plugin name {0} not found
+AUTH_MISSING_REQUIRED_AUTHMGR_1=Missing system required auth manager instance of {0}
+AUTH_AUTH_INTERNAL_ERROR=Authentication subsystem encountered an internal error
+AUTH_AUTH_INTERNAL_ERROR_1=Authentication encountered an internal error. Detailed msg: {0}
+AUTH_ERROR_FORM_SUBJECTDN=Error formulating the Subject Name. See logs for more details.
+AUTH_NO_LDAP_ATTRS_FOUND=no LDAP Attributes found.
+AUTH_NO_LDAP_ATTRS_FOUND=no LDAP Attributes found.
+AUTH_COMPONENT_SYNTAX_1=DN pattern syntax error: {0}
+AUTH_INVALID_VALUE=Invalid attribute error: {0}
+AUTH_SRVLT_ILL_MGR_PLUGIN_ID=Another Auth manager plugin ID already exists
+AUTH_SRVLT_NULL_CLASS=Authentication manager plugin classname is null
+AUTH_SRVLT_NO_CLASS=Authentication manager plugin class not found
+AUTH_SRVLT_ILL_CLASS=Auth manager plugin class is not an instance of IAuthManager
+AUTH_SRVLT_ILL_MGR_INST_ID=An Authentication Instance with this ID already exists. Please choose a different ID.
+AUTH_SRVLT_CANNOT_FIND_MGR_IMPL=Cannot modify auth manager plugin. Cannot locate Auth Manager Implementation.
+AUTH_SRVLT_ADD_MISSING_PARAMS=Auth manager instance is missing an implementation parameter
+AUTH_SRVLT_FAIL_AUTH_MGRI_INIT=Authentication manager initialization Failed. Error {0}
+AUTH_SRVLT_MGR_IN_USE=An auth manager of this implementation is still in use.
+AUTH_EMPTY_DN_FORMED_1=Empty DN formed in Authentication Manager {0}.
+##################################################################
+# For com.netscape.certsrv.authorization
+##################################################################
+AUTHZ_INVALID_CREDENTIALS=Invalid Credentials
+AUTHZ_MISSING_CREDENTIAL_1=Missing required credential {0}
+AUTHZ_FAIL_LOAD_CLASS_1=Could not load authorization manager class {0}
+AUTHZ_AUTHZ_MGR_NOT_FOUND_1=Authorization {0} not found
+AUTHZ_AUTHZ_MGR_PLUGIN_NOT_FOUND_1=Authorization manager plugin name {0} not found
+AUTHZ_MISSING_REQUIRED_AUTHZMGR_1=Missing system required authz manager instance of {0}
+AUTHZ_AUTHZ_INTERNAL_ERROR=Authorization subsystem encountered an internal error
+AUTHZ_AUTHZ_INTERNAL_ERROR_1=Authorization encountered an internal error. Detailed msg: {0}
+AUTHZ_AUTHZ_ACCESS_DENIED_2=authorization failed on resource: {0}, operation: {1}
+AUTHZ_UNKNOWN_PROTECTED_RESOURCE_1=unknown protected resource specified: {0}
+AUTHZ_UNKNOWN_OPERATION_1=unknown operation specified: {0}
+AUTHZ_ILLEGAL_FORMAT=Illegal Format
+AUTHZ_SRVLT_ILL_MGR_PLUGIN_ID=Another Authz manager plugin ID already exists
+AUTHZ_SRVLT_NULL_CLASS=Authorization manager plugin classname is null
+AUTHZ_SRVLT_NO_CLASS=Authorization manager plugin class not found
+AUTHZ_SRVLT_ILL_CLASS=Authz manager plugin class is not an instance of IAuthzManager
+AUTHZ_SRVLT_ILL_MGR_INST_ID=An Authorization Instance with this ID already exists. Please choose a different ID.
+AUTHZ_SRVLT_CANNOT_FIND_MGR_IMPL=Cannot modify authz manager plugin. Cannot locate Authz Manager Implementation.
+AUTHZ_SRVLT_ADD_MISSING_PARAMS=Authz manager instance is missing an implementation parameter
+AUTHZ_SRVLT_FAIL_AUTHZ_MGRI_INIT=Authorization manager initialization Failed. Error {0}
+AUTHZ_SRVLT_MGR_IN_USE=An authz manager of this implementation is still in use.
+AUTHZ_EMPTY_DN_FORMED_1=Empty DN formed in Authorization Manager {0}.
+##################################################################
+# For com.netscape.certsrv.base
+##################################################################
+BASE_UNKNOWN_HOST_1=invalid host name {0}
+BASE_INVALID_REQUEST_TYPE_1=invalid request type {0}
+BASE_PID_EXIST=logs/pid exist, server may already be running.
+BASE_AUTHENTICATE_FAILED_1=Failed to Authenticate - {0}
+BASE_INTERNAL_ERROR_1=Internal Error: {0}
+BASE_MUST_USE_SSL=Must use SSL
+BASE_INVALID_OPERATION=Invalid operation
+BASE_NO_CONFIG_FILE=Cannot find config file: {0}
+BASE_BAD_PERMISSION_FORMAT=Bad permissions format
+BASE_CREATE_SERVICE_FAILED_2=Failed to create {0} service: {1}
+BASE_GET_PROPERTY_FAILED_1=Property {0} missing value
+BASE_GET_PROPERTY_NOVALUE_1=Property {0} missing value
+BASE_INVALID_PROPERTY_1=Cannot convert property {0}
+BASE_INVALID_PROPERTY_3=Cannot convert value of property {0} to a {1}. Expected format is {2}
+BASE_CREATE_LOG_FAILED_1=Failed to create log: {0}
+BASE_LOAD_FAILED_1=Failed to load {0}
+BASE_LOAD_FAILED_2=Failed to load {0}. Error {1}
+BASE_PERMISSION_DENIED=Permission denied
+BASE_PRINCIPAL_ALREADY_EXISTS_1=Principal {0} already exists
+BASE_UNKNOWN_PRINCIPAL_1=Unknown principal {0}
+BASE_SYSTEM_EXCEPTION_1=Caught system exception {0}
+BASE_INVALID_ATTRIBUTE_1=Invalid attribute {0}
+BASE_REQUEST_IN_BAD_STATE=Request is in a bad state
+BASE_ATTRIBUTE_NAME_CAN_NOT_BE_RESOLVED=Attribute name can not be resolved : {0}
+BASE_ARGUMENT_TYPE_MISMATCH=Attribute [{0}] with values of type [{1}] can not be assigned values of type [{2}]
+BASE_BAD_THREAD_SHUTDOWN_1=Forced shutdown of thread: {0}
+BASE_INVALID_PROTOCOL=Invalid Protocol
+BASE_INVALID_RESOURCE_PATH=Invalid Resource Path: {0}
+BASE_ERROR_READING_FILE=Error Reading File: {0}
+BASE_NO_TEMPLATE_TAG=No template tag in file: {0}
+BASE_NO_DOC_ROOT=No Document Root specified
+BASE_INVALID_UI_INFO=Invalid information from UI
+BASE_UTF8_NOT_SUPPORTED=Internal Error: UTF8 encoding not supported. Check your classpath or installation.
+BASE_INVALID_UI_INFO=Invalid information from UI
+BASE_BASE64DECODE_ERROR_1=Error decoding the value as a base-64 encoded blob. System error: {0}.
+BASE_INVALID_UI_INFO=Invalid information from UI
+BASE_INVALID_NUMBER_FORMAT=Invalid number format.
+BASE_INVALID_NUMBER_FORMAT_1=Invalid number format: {0}
+BASE_INVALID_KEYSIZE_PARAMS_1=The key size {0} is outside the bounds described by the DSA key pair generation algorithm.
+BASE_PQG_GEN_FAILED=Failed to generate the PQG parameters
+BASE_ALG_NOT_SUPPORTED_1=The {0} is not supported
+BASE_ALG_NOT_ALLOWED_1=The {0} is not allowed
+BASE_KEY_GEN_FAILED=Failed to generate the key pair
+BASE_TOKEN_NOT_FOUND_1={0} token not found
+BASE_INVALID_X500_NAME_1={0} does not conform to X500
+BASE_ALG_NOT_SUPPORTED=The algorithm is not supported
+BASE_PROVIDER_NOT_SUPPORTED=The provider is not supported
+BASE_PROVIDER_NOT_SUPPORTED_1=The crypto provider is not supported: {0}
+BASE_INVALID_KEY=Invalid key
+BASE_CERT_REQ_FAILED=Failed to generate certificate request
+BASE_INVALID_CERT=Invalid certificate information: {0}
+BASE_INVALID_SIGNATURE=Invalid signature
+BASE_DECODE_CERT_FAILED=Failed to decode certificate
+BASE_DECODE_CERT_FAILED_1=Failed to decode certificate. Error {0}
+BASE_CRYPTOMANAGER_UNINITIALIZED=Crypto manager has not been initialized
+BASE_TOKEN_NOT_FOUND=Token was not found
+BASE_USERCERT_CONFLICT=Certificate conflict with an existing certificate on token. If this is a Subject DN conflict, go back to the Subject Name panel to re-enter the DN. If this is a clone CA, make sure its serial number range begins with a number greater than that of all the certificates existing on the master's DB.
+BASE_NICKNAME_CONFLICT=Nickname has conflict
+BASE_ITEM_NOT_FOUND_ON_TOKEN=Item was not found on token
+BASE_GET_SERIALNO_FAILED=Failed to get certificate serial number
+BASE_LDAP_ERROR=LDAP Error: {0}
+BASE_SIGNED_FAILED=Signed Error: {0}
+BASE_ALG_NOT_SUPPORTED_2=Algorithm not supported: {0}
+BASE_TOKEN_ERROR=Token Error: {0}
+BASE_SIGNED_FAILED=Signed Failed: {0}
+BASE_INVALID_KEY_1=Invalid key: {0}
+BASE_CERT_ERROR=Certificate Error: {0}
+BASE_DB_FAILED=Internal database operation failed
+BASE_ENCODE_CERT_FAILED=Encode certificate failed
+BASE_CA_SIGNINGCERT_NOT_FOUND=CA signing certificate not found
+BASE_CERT_NOT_FOUND=Certificate not found
+BASE_INVALID_PASSWORD_1=Invalid Password -
+BASE_INVALID_CREDENTIALS=Invalid Credentials
+BASE_CREDENTIALS_EXIST=Credentials Exist
+BASE_ATTRIBUTE_NOT_FOUND_1=Attribute Not Found {0}
+BASE_INVALID_ATTR_TYPE_2=Invalid type for attribute {0}, error: {1}
+BASE_INVALID_ATTR_VALUE_2=Invalid value for attribute {0}, error: {1}
+BASE_MISSING_PKCS10_HEADER=Missing PKCS #10 header
+BASE_MISSING_PKCS10_TRAILER=Missing PKCS #10 trailer
+BASE_UNKNOWN_ERROR=Unknown Error
+BASE_LOGIN_ALREADY=Already logged in to the token
+BASE_LOGIN_FAILED=Failed to login to the token: incorrect password
+BASE_CONN_FAILED_1=connection failed {0}
+BASE_RSA_NOT_SUPPORTED=RSA is not supported
+BASE_DSA_NOT_SUPPORTED=DSA is not supported
+BASE_KEY_LENGTH_NOT_SUPPORTED=Key length {0} is not supported
+BASE_MUST_BE_POSITIVE_NUMBER_1={0} must be a positive number greater than 0.
+BASE_MUST_BE_ZEROPOSITIVE_NUMBER_1={0} must be a positive number greater than or equal to 0.
+BASE_A_GREATER_THAN_B_2={0} must be greater than {1}.
+BASE_A_GREATER_THAN_EQUAL_B_2={0} must be greater than or equal to {1}.
+BASE_REMOTE_AUTHORITY_ERROR=Backend server rejected or cancelled the request.
+BASE_INVALID_CERT_EXTENSION=Invalid certificate extension.
+BASE_EXTENSION_ERROR=Extension error encountered. Error {0}.
+BASE_NO_EMPTY_CIPHERPREFS=Blank cipher preferences are not allowed
+BASE_NOT_TOKEN_CERT=The certificate being deleted is not a token certificate
+BASE_INVALID_CERT_FORMAT=Invalid certificate content
+BASE_TOKEN_ERROR_0=Token Error
+BASE_FILE_NOT_FOUND=File not found
+BASE_OPEN_FILE_FAILED=Failed to open file
+BASE_INVALID_FILE_PATH=Invalid file path
+BASE_REVOCATION_CHALLENGE_QUEUE=Failed to get the queue for challenge phrase authentication
+BASE_REQUIRED_PARAMETER={0} is a required parameter
+BASE_FAIL_LOAD_CLASS_2=Failed to load class {0}. Error: {1}
+BASE_INVALID_VALUE_FOR_TYPE_2=Invalid value for type {0}. Error: {1}
+BASE_BAD_REQUEST_VERSION_2=Cannot process request from a previous version of CS (version {0}). Expected version is {1}.
+BASE_NOT_CA_CERT=The selected certificate for the Certificate Manager CA Signing Certificate is not a CA signing certificate.
+BASE_INVALID_IP_ADDR_1=Invalid IP Address {0}.
+BASE_NO_USER_CERT=Client did not present an SSL client cert.
+BASE_FAIL_IMPORT_CERT=import certificate failed
+BASE_IO_ERROR=I/O error encountered. Error {0}.
+BASE_UNKNOWN_EXCEPTION=Unknown Exception encountered. {0}.
+##################################################################
+# For com.netscape.certsrv.base
+##################################################################
+PASSWORD_EMPTY_PASSWORD=The password is empty
+PASSWORD_INVALID_LEN_1=The password must be at least {0} characters
+PASSWORD_NON_ALPHANUMERIC=The password contains non-alphanumeric characters
+PASSWORD_MISSING_NUMERIC_1=The password requires at least {0} numeric digit(s)
+PASSWORD_MISSING_UPPER_CASE_1=The password requires at least {0} upper case letter(s)
+PASSWORD_MISSING_LOWER_CASE_1=The password requires at least {0} lower case letter(s)
+##################################################################
+# For com.netscape.certsrv.ca
+##################################################################
+CA_SYSTEM_EXCEPTION_ADMIN=System exception occurred : {0}
+CA_SYSTEM_EXCEPTION_USER=System exception occurred while processing request, contact your administrator
+CA_ADD_CERT_FAILED=failed to add certificate
+CA_CONNECT_DIR_FAILED=failed to connect directory server
+CA_CREATE_SESSION_FAILED=failed to create session
+CA_GET_NAME_FAILED_1=failed to get name {0}
+CA_GET_ISSUER_NAME_FAILED=failed to get issuer name
+CA_GET_ATTRIBUTE_FAILED=failed to get attribute
+CA_CREATE_CERT_FAILED=failed to create certificate
+CA_NO_SUCH_ATTRIBUTE=no such attribute
+CA_REQUEST_IN_BAD_STATE=request is in a bad state
+CA_REQUEST_STARTED=request started
+CA_REQUEST_AFTER_VALIDATION=request after validation
+CA_REQUEST_COMPLETED=request completed
+CA_ATTRIBUTE_NAME_CAN_NOT_BE_RESOLVED=attribute name can not be resolved : {0}
+CA_ARGUMENT_TYPE_MISMATCH=attribute [{0}] with values of type [{1}] can not be assigned values of type [{2}]
+CA_GET_CA_CERT_FAILED=error reading CA certificate
+CA_RULE_INITIALIZATION_FAILURE=rule [{0}] failed to initialize : {1}
+CA_BAD_POLICY_RESULT_ADMIN=policy rule [{0}] returned invalid state : {1}
+CA_BAD_POLICY_RESULT_USER=policy rule returned invalid result
+CA_INCONSISTENT_CERTIFICATE_VERSION=certificate version requested is inconsistent with certificate content
+CA_POLICY_DID_NOT_SET_STATE_ADMIN=policy rule [{0}] did not set state
+CA_NO_CERTIFICATE_FOUND_1=certificate #{0} was not found
+CA_CERTIFICATE_ALREADY_EXPIRED_1=certificate #{0} has already expired
+CA_CERTIFICATE_ALREADY_REVOKED_1=certificate #{0} has already been revoked
+CA_FAILED_CONSTRUCTING_CRL_1=failed constructing CRL : {0} initialization of CRL issuing point {1} failed : {2} Contains Port number currently being used by other server.
+FAILED_REMOVING_CRL_IP=Failed removing CRL issuing point {0}: {1}.
+CA_SEND_KRA_REQUEST=Sending DRM request failed
+CA_SEND_CLA_REQUEST=Sending CLA request failed
+CA_NUMBER_FORMAT_ERROR=Non-numeric data in numeric field
+CA_CRL_FREQ_RANGE_ERROR=CRL publishing frequency must between 1 and 7 days
+CA_CRL_SIGNING_ALG_MISCONFIG_1=CRL signing algorithm configuration error : {0}
+CA_SIGNING_ALGOR_NOT_SUPPORTED_1=Signing Algorithm {0} is not supported for the CA signing token.
+CA_INIT_PUBLISH_MODULE_FAILED=Failed initializing publishing module.
+CA_INIT_LDAP_PUBLISH_MODULE_FAILED=Failed initializing LDAP publishing module.
+CA_INVALID_CERT_IN_REQUEST_1=Invalid CertInfo in issuing request {0}.
+CA_COULD_NOT_FORMULATE_CRL_EXT_1=Could not formulate CRL Extension for serial number {0}
+CA_CERT_ALREADY_REVOKED_1=Certificate Serial Number {0} is already revoked
+CA_MISSING_SERIALNO_ON_REVOKE=Missing Serial Number in revocation request
+CA_MISSING_REQD_FIELDS_IN_CERTISSUE=Missing required fields in certificate info of certificate issuing request
+CA_NO_CERTINFO_IN_ISSUE_REQUEST=Missing certificate info in certificate issuing request
+CA_UNRECOGNIZED_REQUEST_TYPE_1=Unrecogized request type {0}
+CA_ERROR_GETTING_FIELDS_IN_ISSUE=Error Getting certificate info fields in issuing request.
+CA_CRL_ISSUEPT_NOT_FOUND_1=CRL Issue Point {0} not found in CRL repository.
+CA_CRL_ISSUEPT_NOGOOD_1=CRL in CRL Issue Point {0} is malformed. Cannot instantiate CRL.
+CA_CRL_ISSUEPT_EXT_NOGOOD_1=CRL in CRL Issue Point {0} has malformed extensions. Cannot instantiate CRL.
+CA_FAILED_SET_CERTFIELDS=Error setting Certificate serial number or issuer name.
+CA_FAILED_SET_CERTFIELDS_1= Error setting certain Certificate Fields. {0}
+CA_FAILED_SET_ISSUER=Request {0} was completed with errors.\nError setting Certificate issuer name.
+CA_FAILED_SET_SERIALNO=Request {0} was completed with errors.\nError setting Certificate Serial number.
+CA_FAILED_NOSERIALNO=Request {0} was completed with errors.\nCA has exausted all available serial numbers.
+CA_FAILED_SIGNING_CRL_1=Failed signing CRL. Error {0}
+CA_FAILED_SIGNING_CERT_1=Failed signing certificate. Error {0}
+CA_MISSING_INFO_IN_ISSUEREQ=Missing certificate info in issuing request
+CA_MISSING_INFO_IN_RENEWREQ=Missing certificate info in renewal request.
+CA_MISSING_INFO_IN_RENEWREQ_1=Missing certificate info in renewal request. {0}.
+CA_MISSING_INFO_IN_REVREQ=Missing revocation info in revocation request
+CA_MISSING_INFO_IN_CLAREQ=Missing CLA certificate info in cert4CRL request
+CA_REVOKE_FAILED=One or more certificates could not be revoked
+CA_CERT4CRL_FAILED=One or more revoked certificates could not be recorded by CLA
+CA_UNCERT4CRL_FAILED=One or more revoked certificates could not be removed by CLA
+CA_RENEW_FAILED=One or more certificates could not be renewed
+CA_CANT_FIND_CERT_SERIAL_1=Cannot find certificate with serial number {0}
+CA_NO_CONFIG_FOR_MASTER_CRL=Configuration for Master CRL not found.
+CA_TOKEN_NOT_FOUND_1=Token {0} not found.
+CA_CERT_OBJECT_NOT_FOUND=Certificate object not found.
+CA_INVALID_PASSWORD=Invalid Password.
+CA_TOKEN_ERROR=Token Error.
+CA_CRYPTO_NOT_INITIALIZED=Crypto Layer has not been initialized.
+CA_SIGNING_ALGOR_NOT_SUPPORTED_FOR_KEY_1=Algorithm {0} is not supported for the signing token and key.
+CA_CANNOT_BUILD_CA_CHAIN_1=Could not get or build CA chain. Error {0}
+CA_NO_PUBLISH_CONFIG_FOUND=No Publishing configuration found.
+CA_NO_LDAP_PUBLISH_CONFIG_FOUND=No LDAP Publishing configuration found.
+CA_X509CERT_VERSION_NOT_SUPPORTED=Certificate Version in the configuration is not supported.
+CA_CERT_BEGIN_AFTER_CA_VALIDITY=Certificate validity cannot begin past the CA certificate's validity.
+CA_EXPORT_POLICY_VIOLATION=Signature Algorithm {0} is not allowed by export policy.
+CA_MISSING_SERIAL_NUMBER=Missing or invalid serial number
+CA_UNREVOKE_FAILED=One or more certificates could not be unrevoked
+CA_IS_NOT_ON_HOLD=Certificate {0} has to be on-hold to perform this operation.
+CA_CRL_PERIODIC_UPDATE=The CRL is updated periodically.
+CA_CANNOT_RENEW_REVOKED_CERT_1=Certificate serial number {0} to be renewed is revoked. Cannot renew a revoked certificate.
+CA_ERROR_GETTING_RENEWED_CERT_2=Error getting renewed certificate {0} for certificate {1}.
+CA_CRL_DECODE_FAILED_1=Could not decode CRL {0} in the internaldb.
+CA_ERROR_PUBLISH_CRL_2=Error publishing CRL {0}: {1}.
+CA_CANT_FIND_MANAGER=Can't find Certificate Manager.
+CA_UNKNOWN_ALT_KEY_ID_TYPE=Unknown alternate CA Key ID type. {0}.
+CA_CERT_INFO_ERROR=Certificate Info Error encountered. {0}.
+CA_UNKNOWN_NAME_TYPE=Unknown name type {0}.
+CA_UNKNOWN_REASON=Unknown reason {0}.
+##################################################################
+# For com.netscape.certsrv.dbs
+##################################################################
+DB_FAILED_TO_CONNECT_LDAP_1=Failed to connect LDAP server {0}
+DB_FAILED_TO_SERIALIZE_1=Failed to serialize attribute {0}
+DB_FAILED_TO_DESERIALIZE_1=Failed to de-serialize attribute {0}
+DB_INVALID_ATTRS=Invalid attributes
+DB_INVALID_CLASS_NAME_1=Invalid class name {0}
+DB_INVALID_FILTER_ITEM_1=Invalid filter item {0}
+DB_LDAP_OP_FAILURE_1=LDAP operation failure - {0}
+DB_NO_MAPPER_FOUND_1=No mapper found for {0}
+DB_INTERNAL_DIR_UNAVAILABLE=Internal database is unavailable.
+DB_INTERNAL_DIR_ERROR=Internal Database Error encountered: {0}.
+DB_ADD_ENTRY_FAILED=Failed to add the schema entry.
+DB_INIT_CACHE_1=Init serial number cache failed: {0}.
+DB_LIMIT_REACHED_1=All serial numbers are used.
+DB_SETBACK_SERIAL_1=The serial number is already in use.\n
+DB_SETBACK_MAXSERIAL_1=The serial number is already in use.\n
+##################################################################
+# For com.netscape.certsrv.extensions
+##################################################################
+EXTENSIONS_CLASS_NOT_FOUND_1=Class {0} was not found.
+EXTENSIONS_ERROR_INSTANTIATE_2=Could not create an instance of {0}. Error {1}.
+EXTENSIONS_INVALID_IMPL_1=Class {0} does not implement the ICMSTemplate interface.
+EXTENSIONS_INCORRECT_IMPL_1=Class {0} must return non-null for the extension name and OID.
+EXTENSIONS_ERROR_CREATING_EXT_1=Error creating a {0} extension.
+##################################################################
+# For com.netscape.certsrv.jobs
+##################################################################
+JOBS_FAIL_LOAD_CLASS_1=Could not load Job class {0} for the Jobs Scheduler
+JOBS_PLUGIN_NOT_FOUND_1=Could not find plugin {0} for the Jobs Scheduler
+JOBS_SRVLT_ILL_JOB_PLUGIN_ID=Another job plugin ID already exists
+JOBS_SRVLT_JOB_PLUGIN_NOT_FOUND_1=job plugin {0} not found
+JOBS_SRVLT_JOB_NOT_FOUND_1=job {0} not found
+JOBS_SRVLT_NULL_CLASS=job plugin classname is null
+JOBS_SRVLT_NO_CLASS=job plugin class not found
+JOBS_SRVLT_ILL_CLASS=job plugin class is not an instance of IJob
+JOBS_SRVLT_ILL_JOB_INST_ID=job plugin ID already exists
+JOBS_SRVLT_ADD_MISSING_PARAMS=job instance is missing an implementation parameter
+JOBS_SRVLT_MISSING_INST_PARAM_VAL_1=job instance missing value for parameter: {0}
+JOBS_SRVLT_FAIL_JOBI_INIT=job initialization Failed. Error {0}
+JOBS_SRVLT_JOB_IN_USE=A job of this implementation is still in use.
+##################################################################
+# For com.netscape.certsrv.kra
+##################################################################
+KRA_PUBLIC_KEY_NOT_MATCHED=Public Key does not match
+KRA_INVALID_KEYRECORD=Invalid Key record
+KRA_INVALID_OWNER_NAME=Invalid Owner Name
+KRA_INVALID_PUBLIC_KEY=Invalid Public Key
+KRA_INVALID_PRIVATE_KEY=Invalid Private Key
+KRA_INVALID_STATE=Invalid State
+KRA_INVALID_M=Invalid M
+KRA_INVALID_N=Invalid N
+KRA_INVALID_PASSWORD=Invalid Password
+KRA_POA_DECODE_FAILED_1=Failed to decode Proof-of-Archival {0}
+KRA_POA_ENCODE_FAILED_1=Failed to encode Proof-of-Archival {0}
+KRA_INVALID_KRA_NAME=Invalid KRA Name
+KRA_RECOVERY_FAILED_1=Recovery Failed {0}
+KRA_PKCS12_FAILED_1=PKCS #12 Creation Failed {0}
+KRA_KEYID_FAILED_1=Key Identifier Creation Failed {0}
+KRA_KEYBAG_FAILED_1=Key Bag Creation Failed {0}
+KRA_UNKNOWN_KEY_ID_TYPE=Unknown Key Identifier type. {0}.
+##################################################################
+# For com.netscape.certsrv.ldap
+##################################################################
+LDAP_BAD_LDAP_EXPRESSION=Malformed publishing rule predicate expression: {0} publishing subsystem encountered an internal error publishing. Detailed msg: {0} Error formulating the Subject Name. See logs for more details. No LDAP Attributes found. DN pattern syntax error: {0} Failed to publish using rule: {0} Failed to unpublish using rule: {0} Attribute: {0} is not supported in dnPatternAnother plugin ID already exists. Plugin classname is null. Plugin class not found. Plugin class is not an instance of {0}. Plugin instance ID already exists. Instance missing implementation parameter. Instance initialization Failed. Error {0}. An instance of this implementation is still in use.
+LDAP_INIT_LDAP_PUBLISH_MODULE_FAILED=Failed initializing LDAP publishing module.
+LDAP_NO_LDAP_PUBLISH_CONFIG_FOUND=No LDAP Publishing configuration found.
+LDAP_INVALID_DN_OR_PASSWORD=Invalid DN or Password
+LDAP_NOT_YET_IMPLEMENTED=This feature is not yet implemented
+LDAP_NON_UNIQUE_LDAP_ENTRY_FOUND=Could not find a unique match in the LDAP server for the certificate or CRL
+LDAP_CONNECT_TO_LDAP_SERVER_FAILED_3=Could not connect to the LDAP server host {0} port {1} Error {2}
+LDAP_UNKNOWN_ATTR_IN_DN_FILTER_COMPS=Unrecognized attribute {0} in DN or Filter comps
+LDAP_MISSING_DN_OR_FILTER_COMPS_IN_CONFIG=Missing DN or filter components in the configuration
+LDAP_GET_ISSUER_FROM_CRL_FAILED=Cannot get the Issuer name from the CRL {0}
+LDAP_GET_LDAP_DN_STRING_FAILED=Cannot get the LDAP DN String from the subject DN {0}
+LDAP_GET_CERT_SUBJECT_DN_FAILED=Cannot get the Subject DN from the Certificate {0}
+LDAP_NO_COMPONENTS_IN_DN=No components in the subject name {0} to form the LDAP DN
+LDAP_DECODING_CERT_FAILED=Could not parse a DER encoded certificate from the LDAP server. {0}
+LDAP_GET_DER_ENCODED_CERT_FAILED=Error getting the DER encoding of the certificate for {0}
+LDAP_GET_DER_ENCODED_CRL_FAILED=Error getting the DER encoding of the CRL. {0}
+LDAP_ERROR_PUBLISH_CACERT=Error publishing CA Certificate {0}
+LDAP_ERROR_PUBLISH_CACERT_1=Error publishing CA Certificate {0}. Error {1}.
+LDAP_ERROR_PUBLISH_CRL=Error publishing CRL {0}
+LDAP_ERROR_UNPUBLISH_CRL=Error unpublishing CRL {0}
+LDAP_ERROR_PUBLISH_USERCERT=Error publishing User Certificate {0}
+LDAP_ERROR_UNPUBLISH_USERCERT=Error unpublishing User Certificate {0}
+LDAP_ERROR_UNPUBLISH_CACERT=Error unpublishing CA Certificate {0}
+LDAP_ERROR_UNPUBLISH_CERT=Error unpublishing Certificate {0}. Error {1}.
+LDAP_NO_MATCH_FOUND=Cannot find a match in the LDAP server for the certificate. {0}
+LDAP_OTHER_LDAP_EXCEPTION=LDAPException caught from the operation. {0}
+LDAP_GET_OID_FOR_ATTR_FAILED=Cannot get OID for attr {0} {1}
+LDAP_LDAP_SERVER_DOWN=Cannot publish to the LDAP server, the server is down. {0}
+LDAP_LDAP_MODIFY_FAILED=Cannot modify entry {0} in the LDAP server. {1}
+LDAP_NO_DN_MATCH_1=No DN matched for {0}
+LDAP_NO_DN_AND_FILTER_COMPS=No components to form the DN or the filter for {0}
+LDAP_NO_DN_COMPS_AND_BASEDN=No base DN and no components to form the DN for {0}
+LDAP_MORE_THAN_ONE_ENTRY=Certificate {0} mapped to more than one entry
+LDAP_CANNOT_RESET_CONNFAC=Cannot reset the LDAP connection factory because some connections are still outstanding.
+LDAP_MAPPER_PLUGIN_NOT_FOUND_1=Mapper plugin not found named: {0}
+LDAP_NO_MAPPER_INSTANCE=No Mapper instance can be found.
+LDAP_NO_MAPPER_MATCHED_1=No Mapper instance is matched for request {0}.
+LDAP_PUBLISHER_PLUGIN_NOT_FOUND_1=Publisher plugin not found named: {0}
+LDAP_NO_PUBLISHER_INSTANCE=No Publisher instance can be found.
+LDAP_NO_PUBLISHER_MATCHED_1=No Publisher instance is matched for request {0}.
+LDAP_RULE_PLUGIN_NOT_FOUND_1=Rule plugin not found named: {0}
+LDAP_NO_RULE_INSTANCE=No Rule instance can be found.
+LDAP_NO_RULE_MATCHED_1=No Rule instance is matched for request {0}.
+LDAP_CLASS_NOT_FOUND_1=Class not found for {0}
+LDAP_FAIL_LOAD_CLASS_1=Failed to load class {0}
+LDAP_FAILURE_INSTANTIATING_CLASS_1=Cannot instantiate class {0}
+LDAP_INSUFFICIENT_CREDENTIALS_1=Insufficient credentials to instantiate the class for {0}
+LDAP_NO_MATCH_1=certificate or CRL {0} did not map to an entry in the directory
+LDAP_FORM_DN_COMPS_FAILED=Failed to form DN components from the subject name
+LDAP_LDAP_SERVER_UNAVAILABLE_2=The LDAP server on host {0} port {1} is unavailable.
+LDAP_UNKNOWN_RETURNED_CONN=the connection returned is not from this factory.
+LDAP_BAD_RETURNED_CONN=the connection returned has already been returned.
+LDAP_UNEXPECTED_LDAP_ERROR_2=Plugin: {0} - Unexpected error: {1}.
+LDAP_INVALID_NUMCONN_PARAMETERS=Invalid value for minConn or maxConn parameters. minConn and maxConn must be greater than 0 and minConn must be less than maxConn.
+LDAP_ALREADY_PUBLISHED_1=certificate {0} is already published.
+LDAP_ALREADY_UNPUBLISHED_1=certificate {0} is already unpublished.
+LDAP_NO_REQUEST_2=No request associated with the cert. Can not get request {0} to form LDAP DN component {1}.
+LDAP_FAIL_CREATE_CA_1=Failed to create the CA entry with the DN: {0}. There may be entries in the directory hierarchy which do not exist. Please create them manually.
+LDAP_FAIL_CREATE_ENTRY_1=Failed to create an entry with the DN: {0}. There may be entries in the directory hierarchy which do not exist. Please create them manually.
+##################################################################
+# For com.netscape.certsrv.logging
+##################################################################
+LOG_DEBUG_STRING_1={0}
+LOG_LOGSUBSYSTEM_INIT_0=LogSubsystem already initialized!
+LOG_LOG_THREAD_INTERRUPT_1=log {0} thread interupted
+LOG_ROTATE_LOG_FAILED_2=failed to rotate log \"{0}\", error: {1}
+LOG_WRITE_FAILED_3=failed to write in file: \"{0}\", entry: {1}, error: {2}
+LOG_FLUSH_LOG_FAILED_2=failed to flush log \"{0}\", error: {1}
+LOG_EXPIRE_LOG_FAILED_1=can't expire log files, error: {0}
+LOG_LOG_EVENT_FAILED_2=failed to log event \"{0}\", error: {1}
+LOG_LOGFILE_CLOSED_2=attempt to log message \"{0}\" to closed log file {1}
+LOG_EXPIRATION_TIME_ZERO=log expiration time must be greater than 0
+LOG_DIRECTORY_LIST_FAILED_2=unable to list directory {0} with filter {1}
+LOG_NO_SUCH_ALGORITHM_1=can't find MessageDigest algorithm for {0}. Tamper evident log disabled
+LOG_NO_SUCH_ALGORITHM_0=can't find algorithm. Tamper evident log disabled
+LOG_DIGEST_NOT_CLONABLE_1=MessageDigest algorithm for {0} is not clonable. Tamper evident log disabled
+LOG_DIGEST_IOERROR_1=caught {0} while writing digest. Tamper evident log disabled
+LOG_INVALID_FILE_NAME_1=attempt to initialize log with an invalid filename: \"{0}\"
+LOG_UNEXPECTED_EXCEPTION_1=caught unexpected exception: {0}
+LOG_UNEXPECTED_EXCEPTION_0=caught unexpected exception
+LOG_ILLEGALARGUMENT_1=illegal argument when opening: {0}
+LOG_CLOSE_FAILED_2=failed to close file \"{0}\", error: {1}
+LOG_INVALID_LOG_TYPE_1=attempt to initialize log with an invalid log type: \"{0}\"
+LOG_INVALID_LOG_LEVEL_1=log level: {0} is invalid, should be 0-6
+LOG_LOG_NOT_FOUND_1=Log instance not found named: {0}
+LOG_LOG_PLUGIN_NOT_FOUND_1=Log plugin not found named: {0}
+LOG_FAIL_LOAD_CLASS_1=Failed to load class {0}
+LOG_SIGNED_AUDIT_EXCEPTION_1=caught signed audit log exception: {0}
+LOG_SIGNING_OP_FAILED=signature operation failed
+LOG_SIGNING_CERT_NOT_FOUND=log-signing certificate not found
+##################################################################
+# For com.netscape.certsrv.notification
+##################################################################
+NOTIFICATION_SMTP_SEND_FAILED_1=Failed to send mail to {0}
+NOTIFICATION_EMAIL_RESOLVE_FAILED_1=Failed to resolve email for {0}
+NOTIFICATION_NO_SMTP_SENDER=email sender not found
+NOTIFICATION_NO_SMTP_RECEIVER=email receiver not found
+##################################################################
+# For com.netscape.certsrv.policy
+##################################################################
+POLICY_NO_SUBJECT_NAME_1=Policy Rule: {0} - Internal Error: No Subject Name Found.
+POLICY_SUBJECT_NAME_EXIST_1=Policy Rule: {0} - Subject Name Exist.
+POLICY_NO_CERT_INFO=Policy Rule: {0} - Internal Error: No Certificate info set on the request.
+POLICY_NO_OLD_CERT=Policy Rule: {0} - Internal Error: The certificate(s) being renewed are not set on the request.
+POLICY_LONG_RENEWAL_LEAD_TIME=Policy Rule: {0} - Certificate(s) can be renewed only within {1} days before expiry.
+POLICY_MISMATCHED_CERTINFO=Policy Rule: {0} - Internal Error: The number of certificates input for renewal are incorrect.
+POLICY_NO_PIN_AUTH=Policy Rule: {0} - OTP (or Pin) authentication is required. Please use the correct enrollment form.
+POLICY_NO_DIR_AUTH=Policy Rule: {0} - Directory authentication is required. Please use the correct enrollment form.
+POLICY_MORE_THAN_ONE_CERT=Policy Rule: {0} - Internal Error: Legacy enrollment is for one certificate only.
+POLICY_KEY_SIZE_VIOLATION=Policy Rule: {0} - Key Size Violation occurred: Actual: {1}, Constraints (Min: {2}, Max: {3}).
+POLICY_KEY_SIZE_VIOLATION_5=Policy Rule: {0} - Key Size Violation occurred: Actual: {1}, Constraints (Min: {2}, Max: {3}, Increment: {4}).
+POLICY_EXPONENT_VIOLATION=Policy Rule: {0} - The given exponent: {1} is not in the configured list: {2}."}, {NO_KEY_PARAMS, "Policy Rule: {0} - Could not parse key parameters in key number {1}.
+POLICY_AUTH_ERROR=Policy Rule: {0} - Authentication failure in: {1}.
+POLICY_KEY_ALG_VIOLATION=Policy Rule: {0} - Key algorithm: {1} is not allowed by the policy.
+POLICY_INVALID_BEGIN_TIME=Policy Rule: {0} - Begin time cannot be after current time.
+POLICY_MORE_THAN_MAX_VALIDITY=Requested validity ({1} day(s)) is longer than the maximum allowed ({2} day(s)) in the {0} policy.
+POLICY_LESS_THAN_MIN_VALIDITY=Requested validity ({1} day(s)) is shorter than the minimum allowed ({2} days) in the {0} policy.
+POLICY_SIGNING_ALG_VIOLATION=Policy Rule: {0} - Signing algorithm: {1} is not allowed by the policy.
+POLICY_MISSING_RDN=Policy Rule: {0} - Subject name constraints violation - component: {1} is not present.
+POLICY_MISMATCHED_RDN=Policy Rule: {0} - Subject name constraints violation - value {1} for {2} does not match the configured value {3}.
+POLICY_NAME_CONSTRAINTS_ERROR=Policy Rule: {0} - Subject name constraints error: {1}.
+POLICY_NO_RDNS=Policy Rule: {0} - No RDNS in request to formulate subject Name.
+POLICY_MIS_MATCHED_PATTERN=Policy Rule: {0} - Mismatched pattern in subject name: given name: {1}, configured pattern: {2}.
+POLICY_EXISTING_CERT_DETAILS=Policy Rule: {0} - Your most recent certificate details are : {1}.
+POLICY_UNEXPECTED_POLICY_ERROR=Policy Rule: {0} - Unexpected error: {1}.
+POLICY_INVALID_ISSUER=Invalid Issuer DN
+POLICY_CLIENT_ISSUER_NOT_FOUND=issuer of client certificate not found
+POLICY_INVALID_POLICY=Invalid Policy. Policy {0} can only be used in a CA.
+POLICY_INVALID_POLICY_CLASS=Policy rule: {0} - Invalid policy class: {1}.
+POLICY_ERROR_LOADING_POLICY=Policy rule: {0} - Error loading policy class: {1}.
+POLICY_UNSUPPORTED_KEY_ALG=Policy rule: {0} - Key algorithm: {1} is not supported.
+POLICY_INVALID_CONFIG_PARAM=Policy rule: {0} - Invalid configuration value: {1} for parameter: {2}.
+POLICY_INVALID_X500NAME_COMPONENT=Policy rule: {0} - {1} is not a supported X500Name component.
+POLICY_MISSING_POLICY_CONFIG=Policy rule: {0} - Missing configuration info.
+POLICY_INVALID_POLICY_CONFIG=Policy rule: {0} - Error in configuration: {1}.
+POLICY_UNSUPPORTED_SIGNING_ALG=Policy rule: {0} - Signing algorithm: {1} is not supported.
+POLICY_PARAM_CONFIG_ERROR=Policy rule: {0} - Unexpected error: {1} in configuring parameter: {2}.
+POLICY_BAD_POLICY_EXPRESSION=Malformed Policy Expression: {0}
+POLICY_INVALID_ATTR_VALUE=Invalid value type: {0} for policy attribute
+POLICY_MISSING_PERSISTENT_RULE=Persistent rule: {0} is missing in the configuration.
+POLICY_PERSISTENT_RULE_INACTIVE=Persistent rule: {0} should not be disabled.
+POLICY_PERSISTENT_RULE_MISCONFIG=Persistent rule: {0} is configured with a different predicate: default: {1}, actual: {2}.
+POLICY_CANT_DELETE_PERSISTENT_POLICY=Persistent rule: {0} can't be deleted.
+POLICY_INVALID_POLICY_OPCODE=Invalid operation code: {0} in predicate
+POLICY_NO_POLICY_CONF=No policy rule configuration for rule: {0}
+POLICY_POLICY_ERROR=Uexpected policy error: {0}
+POLICY_NO_POLICY_IMPL=No policy implementation exists for: {0}
+POLICY_INVALID_POLICY_INSTANCE=No policy instance exists for: {0}
+POLICY_ACTIVE_POLICY_RULES_EXIST=Active policy rule instances exist for implementation: {0}
+POLICY_ACTIVE_POLICY_RULE=Policy instance: {0} is active and can't be deleted
+POLICY_ERROR_DELETING_POLICY=Error deleting policy {0}: {1}
+POLICY_DUPLICATE_IMPL_ID=A Policy implementation with ID: {0} already exists
+POLICY_ERROR_ADDING_POLICY=Error adding policy {0}: {1}
+POLICY_INVALID_POLICY_IMPL=Invalid policy implementation: {0}. Policy class must implement one or more of IEnrollmentPolicy, IRenewalPolicy, IRevocationPolicy, IKeyRecoveryPolicy or IKeyArchivalPolicy.
+POLICY_DUPLICATE_INST_ID=A Policy rule with ID: {0} already exists
+POLICY_POLICY_ORDER_ERROR=Error changing policy ordering: {0}
+POLICY_POLICY_IMPLCHANGE_ERROR=Can't change the implementation while modifying policy instance: {0}
+POLICY_ERROR_MODIFYING_POLICY=Error modifying policy instance: {0}
+POLICY_NO_RULES_CONFIGURED=Configuration Error: No policy rules configured for {0} request.
+POLICY_SYSTEM_POLICY_CONFIG_ERROR=System policy: {0} is not configurable.
+POLICY_INVALID_IMPL_IN_RULE_3=Could not instantiate class {0} for implementation {1} in policy rule {2}.
+POLICY_IMPL_CLASS_NOT_FOUND_3=Class {0} for implementation {1} in policy instance {2} was not found.
+POLICY_IMPL_NOT_FOUND_2=Policy implementation {0} configured for instance {1} was not found.
+POLICY_POLICY_INIT_ERROR_2=Could not initialize policy rule instnace {0}. Error {1}
+POLICY_NO_POLICY_ORDERING=No policy ordering is configured
+POLICY_INVALID_RENEWAL_INTERVAL=Policy Rule: {0} - Renewal interval: {1} days cannot be more than maximum validity: {2} days.
+POLICY_INVALID_RENEWAL_MIN_MAX=Policy Rule: {0} - Renewal minimum validity: {1} days cannot be bigger than maximum validity: {2} days.
+POLICY_MAXPATHLEN_TOO_BIG_3=In policy rule {0}, the subordinate CA basic constraints extension path length ({1}) cannot be greater than or equal to the maxPathLen configuration value ({2}).
+POLICY_INVALID_MAXPATHLEN=Policy Max PathLen is invalid.
+POLICY_MAXPATHLEN_TOO_BIG_4=In policy rule {0}, the maxPathLen configuration value ({1}) cannot be greater than or equal to the maxPathLen of the CA certificate ({2}).
+POLICY_INVALID_MAXPATHLEN_2=In policy rule {0}, the maxPathLen configuration value ({1}) must be 0 if the CA's basic constraints extension path length is 0.
+POLICY_INVALID_MAXPATHLEN_4=In policy rule {0}, the maxPathLen configuration value ({1}) must be greater than or equal to 0 or left empty.
+POLICY_PATHLEN_TOO_BIG_3=In policy rule {0}, the requested basic constraints extension path length ({1}) cannot be greater than the maximum path length allowed ({2}).
+POLICY_PATHLEN_ZERO=The CA's basic constraints path length is 0,indicating that no subordinate CA certificates are allowed under this CA. Be warned that all requests for CA certificates will be rejected by this policy as a result.
+POLICY_ERROR_BASIC_CONSTRAINTS_1=In policy rule {0}, could not create a basic constraints extension for the certificate.
+POLICY_ERROR_BASIC_CONSTRAINTS_2=Could not create a basic constraints extension for the certificate. Error {0}.
+POLICY_INVALID_PATHLEN_FORMAT_2=In policy rule {0}, the requested basic constraints extension path length ({1}) must be an integer.
+POLICY_NO_SUB_CA_CERTS_ALLOWED_1=In policy rule {0}, no subordinate CA certificates are allowed since the CA's basic constraints path length is 0.
+POLICY_ERROR_AUTHORITY_KEY_ID_1=In policy rule {0}, Error encountered while creating Authority Key Identifier for the CA.
+POLICY_MISSING_KEY_1=In policy rule {0}, missing public key in certificate request.
+POLICY_ERROR_SUBJECT_KEY_ID_1=In policy rule {0}, failed to create subject key identifier extension for certificate request.
+POLICY_CANNOT_RENEW_EXPIRED_CERTS_1=In policy rule {0}, one or more certificates to be renewed has expired. Cannot renew an expired certificate.
+POLICY_CANNOT_RENEW_EXPIRED_CERTS_AFTER_ALLOWED_PERIOD=In policy rule {0}, one or more certificates to be renewed has been expired for more than {1} days. Cannot renew an expired certificate.
+POLICY_CANNOT_REVOKE_EXPIRED_CERTS_1=In policy rule {0}, one or more certificates to be revoked has expired. Cannot revoke an expired certificate.
+POLICY_PIN_UNAUTHORIZED=You are not authorized to make this transaction.
+POLICY_ERROR_CERTIFICATE_POLICIES_1=In policy rule {0}, could not create a certificate policies extension for the certificate.
+POLICY_UNKNOWN_SIGNING_ALG_2=In policy rule {0}, signing algorithm {1} is unknown to CS.
+POLICY_SIGNALG_NOT_MATCH_CAKEY_2=In policy rule {0}, signing algorithm {1} does not match the CA's private key.
+POLICY_SIGNALG_NOT_MATCH_CAKEY_1=In policy rule {0}, allowed algorithms do not match the CA's private key. The parameters of this rule need to be updated in the CS.cfg.
+POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET=In policy rule {0}, no extension bits are set.
+POLICY_NO_ON_HOLD_ALLOWED=Policy Rule: {0} - On-Hold is not allowed.
+POLICY_INVALID_OID=Error invalid policy OID {0} for request {1}. Error {2}.
+POLICY_INIT_ERROR=INIT Error encountered:
+POLICY_COMMENT_FILE_NOT_FOUND=Comment Text file not found : {0}.
+POLICY_ERROR_NAME_CONST_EXTENSION=Error processing NameConstraints Extension: {0}.
+POLICY_ERROR_CANT_INIT_POLICY_CONST_EXT=Could not init Policy Constraints Extension. Error: {0}.
+POLICY_ERROR_CANT_PROCESS_POLICY_CONST_EXT=Could not init Policy Constraints Extension. Error: {0}.
+POLICY_ERROR_CREATE_MAP=Error creating Policy Map. {0}.
+POLICY_ERROR_CREATE_CERT_POLICY=Error creating Certificate Policy {0}
+POLICY_ERROR_PROCESS_POLICYMAP_EXT=Error processing PolicyMappings Extension: {0}.
+POLICY_ERROR_CREATE_PRIVATE_KEY_EXT=Error creating Private Key Extension. {0}.
+POLICY_ERROR_GET_KEY_FROM_CERT= Policy {0}. Error getting Key from certificate: {1}.
+##################################################################
+# For com.netscape.certsrv.usrgrp
+##################################################################
+USRGRP_SERVER_ERROR=internal server error
+USRGRP_USR_CERT=user certificate related error
+USRGRP_FAIL_GRP_REMOVE=Failed to remove group
+USRGRP_FAIL_USR_REMOVE=Failed to remove user
+USRGRP_FAIL_GRP_ADD=Failed to add group
+USRGRP_FAIL_USR_FIND=User not found
+USRGRP_FAIL_GRP_MOD=failed to modify group
+USRGRP_ILL_GRP_MOD=Certificate Server administrators group must not be empty
+USRGRP_ILL_GRP_REMOVE=Removal of the Certificate Server administrators group is not allowed
+USRGRP_CERT_NOT_FOUND=Certificate not found
+USRGRP_SRVLT_GROUP_NOT_EXIST=Group Not Found
+USRGRP_SRVLT_USER_NOT_EXIST=User Not Found
+USRGRP_SRVLT_LOCALE=Problem processing Locale
+USRGRP_SRVLT_CERT_ERROR=Certificate exception
+USRGRP_SRVLT_CERT_EXPIRED=Certificate expired
+USRGRP_SRVLT_CERT_NOT_YET_VALID=Certificate not yet valid
+USRGRP_SRVLT_CERT_O_ERROR=Certificate related error
+USRGRP_FAIL_USER_ADD=failed to add user
+USRGRP_FAIL_USER_MOD=failed to modify user
+USRGRP_SRVLT_FAIL_USER_ADD=failed to add user
+USRGRP_SRVLT_FAIL_USER_ADD_NEED_UID=failed to add user: UID required
+USRGRP_SRVLT_FAIL_USER_ADD_GROUP=added user but failed to add to group
+USRGRP_SRVLT_FAIL_USER_CERT_EXISTS=failed to add cert: The certificate you tried to add already exists
+USRGRP_SRVLT_FAIL_USER_MOD=failed to modify user
+USRGRP_SRVLT_FAIL_USER_RMV=failed to remove user
+USRGRP_SRVLT_FAIL_USER_RMV_G=The user you try to delete belongs to one or more groups.\nIf you click yes to continue, then the user will also be deleted \n from all the groups that it belongs to.
+USRGRP_SRVLT_FAIL_GROUP_ADD=failed to add group
+USRGRP_SRVLT_FAIL_GROUP_MOD=failed to modify group
+USRGRP_USR_MOD_ILL_CERT_OP=unknown certificate operation
+USRGRP_SRVLT_FAIL_USER_ADD_1=Failed to add user. Missing \"{0}\".
+USRGRP_SRVLT_FAIL_USER_MOD_1=Failed to modify user. Missing \"{0}\".
+USRGRP_BAD_PASSWD=The given password doesn't pass the password quality checker.
+USRGRP_FAIL_LOAD_CLASS_1=Could not load password checker class {0}
+##################################################################
+# For com.netscape.cms.servlet
+##################################################################
+CMSGW_MISSING_TEMPLATE_TAG_2=Missing template tag {0} in template {1}
+CMSGW_ERROR_LOADING_TEMPLATE=Error encountered while loading output template.
+CMSGW_TEMPLATE_NO_CONTENT_1=Template {0} has no content.
+CMSGW_ERROR_CLOSING_TEMPLATE_2=Failed to close template {0}. Error {1}
+CMSGW_MISSING_KEYGEN_INFO=Missing or malformed KeyGen, PKCS #10 or CRMF request.
+CMSGW_MISSING_CERTINFO=Missing CertInfo in AuthToken of authenticated enroll request.
+CMSGW_MISSING_CERTINFO_ENCRYPT_CERT=Error getting certinfo from encryption certificate
+CMSGW_MISSING_CRL=Missing CRL.
+CMSGW_MISSING_CA_CERT=Missing CA Certificate.
+CMSGW_MISSING_CERT=Missing Certificate.
+CMSGW_MISSING_CERT_HEADER=Missing Certificate Header.
+CMSGW_MISSING_CERT_FOOTER=Missing Certificate Footer.
+CMSGW_MISSING_CRL_HEADER=Missing CRL Header.
+CMSGW_MISSING_CRL_FOOTER=Missing CRL Footer.
+CMSGW_MISSING_KEY_IN_KEYGENINFO=Missing or malformed key in KeyGenInfo.
+CMSGW_FAILED_FORM_X500NAME_1=Error forming X500Name from subject name {0}.
+CMSGW_MISSING_KEY_IN_P10=PKCS #10 request missing subject public key info.
+CMSGW_MISSING_SUBJECT_IN_P10=PKCS #10 request missing subject name.
+CMSGW_UNEXPECTED_REQUEST_STATUS_2=Unexpected resulting request status {0} for request ID {1}
+CMSGW_MISSING_REQUEST=No request was created for this operation.
+CMSGW_FAILED_SET_KEY_FROM_KEYGEN_1=Error setting key into certificate info from KeyGen. Error {0}.
+CMSGW_NOT_A_CA=Feature available only for CA
+CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1=Error setting key into certificate info from certificate based enrollment. Error {0}.
+CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_IO= I/O Error setting key into certificate info from certificate based enrollment. Error {0}.
+CMSGW_INVALID_CERT_TYPE=SSL client certificate presented for this cert-based enrollment is not a signing only cert.
+CMSGW_ENCRYPTION_CERT_NOT_FOUND=Pairing encryption certificate for cert-based dual certificate enrollment not found in the DB
+CMSGW_MISSING_SSL_CLIENT_CERT=Missing SSL Client Certificate for certificate based enrollment
+CMSGW_INVALID_CERTAUTH_ENROLL_TYPE=Invalid certauthEnrollType
+CMSGW_INVALID_CERTAUTH_ENROLL_TYPE_1=Invalid certauthEnrollType {0}.
+CMSGW_MISSING_CERTAUTH_ENROLL_TYPE=Missing certauthEnrollType.
+CMSGW_FAILED_SET_SUBJECT_FROM_P10=Error setting subject name from PKCS #10 into certificate info . Error {0}.
+CMSGW_ERROR_CMC_TO_CERTINFO=An Error was encountered while filling the certificate with the contents of the CMC message.
+CMSGW_ERROR_CMC_TO_CERTINFO_1= An Error was encountered while filling the certificate with the contents of the CMC Message {0}
+CMSGW_ERROR_CRMF_TO_CERTINFO=An Error was encountered while filling the certificate with the contents of the CRMF message.
+CMSGW_ERROR_CRMF_TO_CERTINFO_1=An Error was encountered while filling the certificate with the contents of the CRMF message. For Enrollment {0}.
+CMSGW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN=Missing subject name from authentication.
+CMSGW_FAILED_SET_KEY_FROM_P10=Error setting key from PKCS #10 into certificate info . Error {0}.
+CMSGW_ERROR_DECODING_CRL=Error encountered while decoding CRL.
+CMSGW_ERROR_DECODING_CERT=Error encountered while decoding certificate.
+CMSGW_ERROR_OLD_CRL=CRL Sent is older than the current CRL.
+CMSGW_ERROR_ENCODING_ISSUED_CERT=Error encountered while encoding certificate.
+CMSGW_ERROR_RETURNING_CERT=Error encountered while returning certificate.
+CMSGW_ERROR_RETURNING_RESULT=I/O Error encountered while outputting results.
+CMSGW_ERROR_GET_RENEWED_CERT=Could not get renewed certificate in the certificate database.
+CMSGW_FAILED_FIND_RENEWED_CERT=Could not find renewed certificate in the certificate database.
+CMSGW_ERROR_DISPLAY_TEMPLATE=Error encountered while rendering a response.
+CMSGE_ERROR_DISPLAY_TEMPLATE_1=Error while displaying template {0}. Error {1}.
+CMSGW_UNAUTHORIZED=Request was unauthorized.
+CMSGW_ERROR_SET_SUBJECT_NAME=Cannot convert the subject name from a string to an X500 Name.
+CMSGW_ERROR_SET_SUBJECT_NAME_1=Unexpected Error setting subject for certificate info. Error {0}
+CMSGW_ERROR_SET_SUBJECT_NAME_2=Cannot convert the subject name from a string to an X500 Name. Error {0} Message {1}
+CMSGW_ERROR_SET_VALIDITY=An Error was encountered while setting the validity in the cert.
+CMSGW_ERROR_SET_VALIDITY_1=An Error was encountered while setting the validity in the cert. Error {0}
+CMSGW_ERROR_SET_EXTENSIONS=An Error was encountered while setting the extensions in the cert.
+CMSGW_ERROR_SET_EXTENSIONS_1=An Error was encountered while setting the extensions in the cert. Error {0}
+CMSGW_UNKNOWN_EXTENSION_IN_CRMF_1=Unknown extension in CRMF request. OID {0}
+CMSGW_MISSING_CERTS_RENEW_FROM_AUTHMGR=You have no certificates to be renewed or the certificates are malformed.
+CMSGW_MISSING_CERTS_RENEW_FROM_SSL=You did not select a certificate to renew or the certificate you selected is malformed.
+CMSGW_MISSING_SERIALNO_FOR_RENEW=Missing or malformed serial number of certificate to renew.
+CMSGW_MISSING_SERIALNO_FOR_RENEW_1=Certificate {0} for renewal not found.
+CMSGW_MISSING_SERIALNO_FOR_REVOKE=Missing or malformed serial number of certificate to revoke.
+CMSGW_RENEWAL_CERT_REVOKED=The cerficate you submitted for renewal is revoked. Cannot renew a revoked certificate.
+CMSGW_INVALID_CERT_FOR_RENEWAL=The certificate(s) selected to be renewed is not from this CA.
+CMSGW_INVALID_CERT=The certificate is not from this CA.
+CMSGW_INVALID_CERT_FOR_REVOCATION=Certificate {0} scheduled for revocation was not found.
+CMSGW_ERROR_SETTING_RENEWAL_VALIDITY=An error was encountered while setting the certificate validity.
+CMSGW_ERROR_SETTING_RENEWAL_VALIDITY_1=An error was encountered while setting the certificate validity. Error {0}.
+CMSGW_ERROR_GETTING_RENEWED_CERT=An error was encountered while getting the renewed certificate from the database.
+CMSGW_MISSING_SUBJECT_FROM_FORM=Missing subject name from the form.
+CMSGW_MISSING_CERTS_REVOKE_FROM_AUTHMGR=You have no certificates to be revoked or the certificates are malformed.
+CMSGW_MISSING_CERTS_REVOKE_FROM_SSL=You did not select a certificate to revoke or the certificate you selected is malformed.
+CMSGW_MISSING_SERIALNO_FOR_REVOKE=Missing or malformed serial number of certificate to revoke.
+CMSGW_CERT_ALREADY_REVOKED=The certificate has already been revoked.The certificate(s) selected to be revoked is not from this CA.
+CMSGW_ERROR_SETTING_CRLREASON=An error was encountered while setting the revocation reason.
+CMSGW_NO_OPTIONS_SELECTED=You must select an option from the form.
+CMSGW_INVALID_OPTIONS_SELECTED=The option(s) you selected is invalid. This could indicate a flaw in the form you are using.
+CMSGW_INVALID_OPTIONS_CA_CHAIN=Invalid options selected to get CA Chain.
+CMSGW_ERROR_GETTING_CA_CERT=An error was encountered while getting the CA chain.
+CMSGW_ERROR_GETTING_CACERT_ENCODED=Could not get CA certificates encoded. Error {0}.
+CMSGW_CA_CHAIN_EMPTY=The CA chain is missing or could not be obtained from the remote Certificate Manager or Registration Manager. The remote server could be down.
+CMSGW_ERROR_ENCODING_CA_CHAIN=An error was encountered while encoding the CA chain.
+CMSGW_ERROR_ENCODING_CA_CHAIN_1=An error was encountered while encoding the CA chain. {0}
+CMSGW_CA_CHAIN_NOT_AVAILABLE=The CA chain is missing or could not be obtained from the remote Certificate Manager or Registration Manager. The remote server could be down.
+CMSGW_ERROR_DISPLAYING_CACHAIN=An I/O error was encountered while outputting the CA chain.
+CMSGW_ERROR_DISPLAYING_CACHAIN_1=An I/O error was encountered while outputting the CA chain. {0}
+CMSGW_NO_CRL_SELECTED=You must specify the CRL issuing point.
+CMSGW_NO_CRL_ISSUING_POINT=No CRL issuing point specified.
+CMSGW_NO_CRL_ISSUING_POINT_FOUND=CRL issuing point {0} not found.
+CMSGW_CRL_NOT_FOUND=The CRL you selected for download was not found.
+CMSGW_CRL_NOT_UPDATED=The CRL you selected for download has not been updated.
+CMSGW_CRL_NOT_YET_UPDATED_1=The Certificate Revocation List {0} has not been updated.
+CMSGW_NOT_YET_IMPLEMENTED=The operation you requested has not yet been implemented.
+CMSGW_ERROR_DISPLAYING_CRLINFO=An I/O error was encountered while outputting CRL results.
+CMSGW_REQUEST_ID_NOT_FOUND_1=Request ID {0} was not found in the request queue.
+CMSGW_ERROR_UPDATE_REQUEST_1=Error updating request ID {0} in the database.
+CMSGW_ERROR_FORMING_EXT_1=Error forming a {0} extension.
+CMSGW_INVALID_SERIAL_NUMBER=Certificate Serial number is not set or invalid.
+CMSGW_CERT_SERIAL_NOT_FOUND_1=Certificate serial number {0} not found
+CMSGW_ERROR_FORMING_PKCS7=Error Forming PKCS #7.
+CMSGW_ERROR_FORMING_PKCS7_1= Error Forming PKCS #7 for output {0}.
+CMSGW_ERROR_READING_REQUEST_ID_1=Cannot find Request ID {0} in the database.
+CMSGW_INVALID_REQUEST_ID_1=Invalid Request ID {0}.
+CMSGW_CRL_NOT_YET_UPDATED=The Certificate Revocation List has not been updated.
+CMSGW_FAILED_DECODE_CRL=Failed to DER decode the Certificate Revocation List.
+CMSGW_FAILED_DECODE_CRL_1=Failed to DER decode the Certificate Revocation List. Error {0}
+CMSGW_REVOCATION_ERROR_CERT_NOT_FOUND=Attempt to revoke non-existent certificate(s).
+CMSGW_ERROR_MARKING_CERT_REVOKED=Error encountered while marking certificate revoked.
+CMSGW_ERROR_MARKING_CERT_REVOKED_1=Error encountered while marking certificate revoked . {0}
+CMSGW_NO_RECOVERY_TOKEN_FOUND_1=No Recovery Token Found for recovery reference number {0}.
+CMSGW_INVALID_AGENT_3=Agent: {0} cannot retrieve PKCS #12 for recovery reference number {2}. Agent: {1} initialized the request.
+CMSGW_INVALID_AGENT_ASYNC_3=Agent: {0} cannot retrieve PKCS #12 for recovery request id {2}. Agent: {1} initialized the request.
+CMSGW_ERROR_DISPLAY_FILE=I/O Error encountered while outputting file.
+CMSGW_FILE_NOT_FOUND=File was not found
+CMSGW_NO_CERTS_FROM_CA=Error encountered while issuing certificates.
+CMSGW_ERROR_SETTING_CERT_ATTRIBUTES=Error encountered while setting certificate attributes.
+CMSGW_ERROR_FORMING_PKCS10=Error encountered while forming a PKCS #10 response.
+CMSGW_ERROR_REDIRECTING_ADMINENROLL1=Error encountered while accessing the adminEnroll page.{0}
+CMSGW_ERROR_REDIRECTING_PAGE=Error encountered while accessing the {0} page. Error {1}.
+CMSGW_NO_LDAP_PUB_MODULE=LDAP publishing module is disabled.
+CMSGW_NO_PUB_MODULE=Publishing module is disabled. Make sure valid characters are in the subject name. \nFor example, the email address should only have IA5String characters \nand the country should only have PrintableString characters and have 2 characters exactly.
+CMSGW_ERROR_ADDING_ADMIN_CERT_1=An error was encountered while adding the administrator's certificate to its entry in the user groupdatabase. Error {0}
+CMSGW_ERROR_ADDING_ADMIN=An error was encountered while adding the administrator to the Certificate Manager Agent Group - Group does not exist.
+CMSGW_INSUFFICIENT_PRIVILEGE=You must also be an administrator to grant trusted manager or agent privileges.
+CMSGW_MISSING_GRANT_UID=You must specify a user ID for the trusted manager or agent.
+CMSGW_ERROR_FIND_GROUP_1=Could not grant privileges. Could not find group {0}.
+CMSGW_ERROR_ADDING_USER_1=Could not grant privileges. Error adding user {0}.
+CMSGW_ERROR_ADDING_CERT_1=Could not grant privileges. Error adding certificate to user {0}.
+CMSGW_ERROR_ADDING_MEMBER_2=Could not grant privileges. Error adding user {0} to group {1}.
+CMSGW_ERROR_ADDING_MEMBER_3=Could not grant privileges. Error adding user {0} to group {1} or group {2}.
+CMSGW_REQUEST_HAD_NO_CERTS_1=Request ID {0} had no certificates issued as a result.
+CMSGW_REQUEST_NOT_COMPLETED_1=Request ID {0} is not completed.
+CMSGW_REQUEST_HAD_ERROR_1=Request ID {0} resulted in an error. No certificates were issued.
+CMSGW_REQUEST_NOT_ENROLLMENT_1=Request ID {0} is not a certificate enrollment request.
+CMSGW_NO_REQUEST_ID_PROVIDED=A Request ID must be provided for this operation.
+CMSGW_REQUEST_ID_NOT_FOUND=Request ID {0} not found.
+CMSGW_INVALID_REQ_ID_FORMAT=Invalid request ID format. ID {0}.
+CMSGW_CERT_NOT_FROM_CRMF_REQUEST_1=Certificate serial number {0} was not issued from a CRMF request and therefore cannot be imported through CMMF.
+CMSGW_AUTH_ERROR_2=Error encountered in authentication manager {0}: {1}
+CMSGW_MISSING_AUTH_TOKEN=Cannot authorize client: missing authentication token.
+CMSGW_AUTHORIZATION_FAILED_1=Authorization of client failed. Authorization required: {0}
+CMSGW_NO_PKIDATA=No PKIData in CMC full enrollment request.
+CMSGW_ERROR_PKCS101=Error processing PKCS #10 in CMC full enrollment request: {0}
+CMSGW_NO_CMC_CONTENT=No PKCS #10 nor CRMF in CMC full enrollment request.
+CMSGW_CMC_ERROR1=Unexpected error processing CMC full enrollment request: {0}
+CMSGW_ERROR_POP_VERIFY=Proof-of-Possession not Successfully Verified.
+CMSGW_ERROR_NO_POP=Proof-of-Possession is required and is not present.
+######################
+# begin debug messages
+######################
+CMSGW_PROP_UNAUTHORIZED_TEMPLATE=unauthorizedTemplate
+CMSGW_UNAUTHORIZED_TEMPLATE=/GenUnauthorized.template
+CMSGW_PROP_SUCCESS_TEMPLATE =successTemplate
+CMSGW_SUCCESS_TEMPLATE=GenSuccess.template
+CMSGW_PROP_PENDING_TEMPLATE=pendingTemplate
+CMSGW_PENDING_TEMPLATE=GenPending.template
+CMSGW_PROP_SVC_PENDING_TEMPLATE=svcpendingTemplate
+CMSGW_SVC_PENDING_TEMPLATE=/GenSvcPending.template
+CMSGW_PROP_REJECTED_TEMPLATE=rejectedTemplate
+CMSGW_REJECTED_TEMPLATE=/GenRejected.template
+CMSGW_PROP_ERROR_TEMPLATE=errorTemplate
+CMSGW_ERROR_TEMPLATE=/GenError.template
+CMSGW_PROP_EXCEPTION_TEMPLATE=unexpectedErrorTemplate
+CMSGW_EXCEPTION_TEMPLATE=/GenUnexpectedError.template
+CMSGW_PROP_UNAUTHOR_TEMPLATE_FILLER=unauthorizedTemplateFiller
+CMSGW_PROP_SUCCESS_TEMPLATE_FILLER=successTemplateFiller
+CMSGW_PROP_ERROR_TEMPLATE_FILLER=errorTemplateFiller
+CMSGW_PROP_PENDING_TEMPLATE_FILLER=pendingTemplateFiller
+CMSGW_PROP_SVC_PENDING_TEMPLATE_FILLER=svcpendingTemplateFiller
+CMSGW_PROP_REJECTED_TEMPLATE_FILLER=rejectedTemplateFiller
+CMSGW_PROP_EXCEPTION_TEMPLATE_FILLER=exceptionTemplateFiller
+CMSGW_PROP_DONT_SAVE_HTTP_PARAMS=dontSaveHttpParams
+####################
+# end debug messages
+####################
+CMSGW_TEMP_REND_ERR=Error rendering template {0} Error {1}
+CMSGW_TEMP_REND_ERR_1=Error rendering template {0} : {1}. Returning HTTP INTERNAL ERROR. #1
+CMSGW_TEMP_REND_ERR_2=Error rendering template {0} : {1}. Returning HTTP INTERNAL ERROR. #2
+CMSGW_FILE_ACCESS_DENIED=File access denied: {0}
+CMSGW_ACCESS_DENIED=CGI Access denied: {0}
+CMSGW_SSL_CLIENT_BAD_PORT=Cannot get SSL Client certificate from a non-SSL port.
+###########
+# debugging
+###########
+CMSGW_GETTING=getting {0}
+CMSGW_INDEXING=indexing {0}
+CMSGW_REDIRECTING=redirecting {0} to {1}
+###############
+# end debugging
+###############
+CMSGW_BAD_CONFIG_PARAM=CMSGateway: Failed to get config parameter.
+CMSGW_GETTING_CLIENT_CERT=Getting client certificate.
+CMSGW_GETTING_SSL_CLIENT_CERT=Getting SSL client certificate.
+CMSGW_FAIL_SSL_CLIENT_CERT=Failed to get SSL Client cert. Client did not provide cert.
+CMSGW_AUTH_MAN_EXPECTED=Authentication Manager name expected in Servlet Access.
+CMSGW_BAD_REQ_STATUS=Invalid status to CMSRequest.
+CMSGW_ERR_CONF_TEMP_PARAMS=Unexpected error getting template config params. Error {0}
+###########
+# debugging
+###########
+CMSGW_DO_SSL_AUTH=doSslAuth is {0}.
+CMSGW_GET_SSL_CLIENT_CERT=Getting SSL client certificate as requested in http.
+CMSGW_NO_CLIENT_CERT=Unauthorized client access to servlet {0}. Client failed to provide a cert.
+CMSGW_NO_CLIENT_TOK=Unauthorized client access to servlet {0}. Missing client token.
+CMSGW_AUTH_MGR_CORRUPT=FATAL ERROR *** AuthMgr instance corrupt!!!
+CMSGW_NO_CLIENT_AUTH=Authorization of Client failed in servlet {0}
+CMSGW_ERR_OUT_TEMPLATE=Error outputting template {0} . {1}.
+CMSGW_AUTHING_CLIENT=authenticating client with {0}.
+CMSGW_NO_FIND_AUTH_MGR=Cannot find authentication manager {0}.
+CMSGW_AUTH_MGR_FAIL=Auth manager {0} encountered {1}.
+CMSGW_AUTH_MGR_REJECT=Missing some required credentials for authentication manager {0}.
+CMSGW_AUTH_MGR_REJECT_1=Invalid credentials resulting from {0}.
+CMSGW_AUTH_MGR_UNEXPECT=Unexpected error from authentication manager {0}. Error {1}.
+CMSGW_SSL_NO_INVALIDATE=Cannot invalidate socket session. Socket not SSL.
+CMSGW_SSL_CL_CERT_FAIL=Failed to get SSL Client cert. Client did not provide a cert.
+CMSGW_SSL_CL_CERT_FAIL_ENCODE=Failed encoding SSL Client cert. Error {0}.
+CMSGW_SSL_CL_CERT_FAIL_DECODE=Failed decoding SSL Client cert. Error {0}.
+CMSGW_NO_FIND_TEMPLATE=Cannot locate template {0}.
+CMSGW_NO_CONFIG_VALUE=Impossible Error getting config variable {0}. Ignoring Error {1}.
+CMSGW_NON_CERT_AUTH=Trying to get a certificate from a non-certificate authority.
+CMSGW_CERT_DB_NULL=Certificate DB is null for {0}.
+CMSGW_NO_CERT_REC=Error getting certRecord for serialNo 0x{0}. Error {1}.
+CMSGW_NOT_CERT_AUTH=Cannot get certificate - authority not a CA.
+CMSGW_CANT_LOAD_FILLER=Couldn't load filler class name {0}. Error {1}. Using default.
+CMSGW_IMP_INIT_SERV_ERR=**** FATAL ERROR *** Impossible error {0} encountered while initializing servlet. {1} Ignored.
+CMSGW_RET_CERT_IMPORT_ERR=Error when returning certificate to import. {0}.
+CMSGW_NO_ENCODED_IMP_CERT=Could not get certificate in encoded form for import. {0}.
+CMSGW_ERR_CRL_REASON=Error setting CRL reason {0}. Error {1}.
+CMSGW_BAD_CERT_SER_NUM=certificate serial {0} is not from this CA.
+CMSGW_START_USE_CONFIG=CMS: Starting CS using configuration file {0}.
+CMSGW_CMS_START_CONFIG_ERR=CMS: {0}.
+CMSGW_CANT_LOAD_TEMPLATE=Could not load template {0} error {1}.
+CMSGW_TEMPLATE_EMPTY=template {0} has no content.
+CMSGW_TEMPLATE_MISSING=template {0} missing {1} tag.
+CMSGW_ERR_CLOSE_TEMPL_FILE=Error closing file {0} : {1}.
+CMSGW_FILE_NO_ACCESS=File Access denied: {0}.
+CMSGW_GROUP_AUTH_FAILED=CMSgateway: Group Authorization failed. User {0} is missing or null in the Auth token.
+CMSGW_GRP_AUTH_FAIL_NO_USER="CMSgateway: Group Authorization failed. User {0} was not found in user group database.
+CMSGW_GRP_AUTH_FAIL_NO_MEM_GRP=CMSgateway: Group Authorization failed. User {0} is not a member of group {1}.
+CMSGW_GRP_AUTH_SUCCESS=CMSgateway: Group Authorization success. User {0} is a member of group {1}.
+CMSGW_GRP_AUTH_FAIL_NO_GRP=CMSgateway: Group Authorization failed. User {0} is not a member of any group in {1}.
+CMSGW_GRP_AUTH_FAIL_USER_GRP_ERR=CMSgateway: Group Authorization failed. User group error {0}.
+CMSGW_FAIL_REDIRECT_ADMIN_ENROLL=Failed to redirect to admin enroll page. Error {0}.
+CMSGW_FAIL_REDIRECT_PAGE=Failed to redirect html page {0}. Error {1}.
+CMSGW_FAIL_RENDER_TEMPLATE=Failed to render template {0}. Error {1}.
+CMSGW_ERR_BAD_SERV_OUT_STREAM=Error getting servlet output stream when rendering {0} template. Error {1}.
+CMSGW_ERR_DISP_BY_SERIAL=Error encountered in DisplayBySerial. Error {0}.
+CMSGW_ERROR_PARSING_EXTENS=Error certificate parsing extensions. Error {0}.
+CMSGW_ERR_DIGESTING_CERT=Error digesting certificate. Error {0}.
+CMSGW_ERR_ENCODE_CERT=Error encoding certificate. Error {0}.
+CMSGW_ERR_DECODE_CRL=Failed to decode CRL. Error {0}.
+CMSGW_ERR_UPDATE_CRL=Error updating CRL. Error {0}.
+CMSGW_ERR_NO_DELTA_CRL=Delta CRL is not available for {0} issuing point.
+CMSGW_ERR_NO_DELTA_CRL_1=Delta CRL is not available.
+CMSGW_ERR_DECODE_DELTA_CRL=Failed to decode Delta CRL. Error {0}.
+CMSGW_ERR_PUBLISH_DELTA_CRL=Failed to publish Delta CRL. Error {0}.
+CMSGW_ERR_OUT_STREAM_TEMPLATE=Error getting servlet output stream for rendering template. Error {0}.
+CMSGW_REQ_AUTH_REVOKED_CERT=Revocation request was authenticated by a revoked certificate.
+CMSGW_REV_CERTS_ZERO=number of revocation certificates is zero.
+CMSGW_INVALID_SERIAL_NUM_FORMAT=Invalid Serial number format.
+CMSGW_CA_FROM_RA_NOT_IMP=getting a CRL from the RA is not implemented yet.
+CMSGW_ERR_GET_TEMPLATE=Error getting template {0} Error {1}.
+CMSGW_ERR_GET_TEMPLATE_1=Error getting template. Missing template name.
+CMSGW_ERR_GET_TEMPLATE_2=Error getting template. Missing template name. Error {0}.
+CMSGW_ERR_STREAM_TEMPLATE=Error getting servlet output stream for rendering template. Error {0}.
+CMSGW_ERR_PROCESS_ENROLL_NO_AUTH=Could not process enrollment request. Bulk-generated certificate auth failed authentication.
+CMSGW_CANT_PROCESS_ENROLL_REQ=Could not process enrollment request.
+CMSGW_CANT_GET_CERT_SUBJ_AUDITING=failed to retrieve certificate subject for auditing {0}.
+CMSGW_REQ_ILLEGAL_CHARACTERS=Check to make sure request has no illegal characters, e. g. - email is an IA5String and Country is a Printable String.
+CMSGW_ERROR_LISTCERTS=Error in listCerts. Error {0}.
+CMSGW_INVALID_RECORD_COUNT_FORMAT=Invalid total record count format.
+CMSGW_ERR_GET_CRL_RECORD=Error getting CRL record. Error {0}.
+CMSGW_FAIL_GET_ICERT_RECORD=Failed getting ICertRecord.ATTR_META_INFO for certificate serial number {0}. It may be a certificate added at installation time.
+CMSGW_FAIL_PUBLISH_CERT=Failed to publish Certificate {0}.
+CMSGW_CANT_FIND_AUTHORITY=Cannot find authority {0}.
+CMSGW_ERROR_SENDING_DER_ENCODE_CERT=Failed sending DER encoded cert: {0}.
+CMSGW_ERROR_CREATE_ENTRY_FROM_CEP=Tried to create an entry from the CEP servlet, but cannot because Publishing is not running.
+CMSGW_FAIL_CREAT_ENTRY_EXISTS=Failed creating entry for : {0} : Entry already exists?
+CMSGW_ENROLL_FAIL_NO_AUTH=Enrollment failed: user failed to authenticate.
+CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME=CRS enrollment - Could not create subjectAltName. Error {0}.
+CMSGW_ENROLL_FAIL_DUP_TRANS_ID=Enrollment failed: user used duplicate transaction ID.
+CMSGW_ENROLL_FAIL_NO_DECRYPT_PKCS10=CRS enrollment failed: Could not decrypt PKCS #10 request. Error {0}.
+CMSGW_ERNOLL_FAIL_NO_NEW_REQUEST_POSTED=CRS enrollment failed: Could not post new request. Error {0}.
+#####
+# new
+#####
+CMSGW_HAS_NO_CLIENT_CERT=Remote Authority has no client certificate.
+CMSGW_NOT_TRUSTED_REMOTE_RA=Remote Authority {0} not authorized as a trusted RA.
+CMSGW_IO_ERROR_REMOTE_REQUEST=I/O Error processing remote request. Error {0}.
+CMSGW_REMOTE_AUTHORITY_AUTH_FAILURE=Remote Authority auth failure. {0}.
+CMSGW_ERROR_PROCESS_NETSCAPE_EXTENSION=Error while processing Netscape Certificate Type extension {0}.
+CMSGW_ERROR_PROCESS_CONSTRAINTS_EXTENSION=Error while processing Basic Constraints extension. {0}.
+CMSGW_ERROR_DISPLAY_TEMPLATE=Error encountered while rendering a response.
+##################################################################
+# For com.netscape.cms.servlet.admin
+##################################################################
+ADMIN_SRVLT_FAIL_AUTHS=Authentication failed
+ADMIN_SRVLT_FAIL_AUTHZ=AUTHZ permission check failed
+ADMIN_SRVLT_INVALID_OP_TYPE_1=Invalid OP_TYPE {0}
+ADMIN_SRVLT_INVALID_OP_SCOPE=Invalid OP_SCOPE
+ADMIN_SRVLT_INVALID_PROTOCOL=Invalid protocol: OP_TYPE must be specified
+ADMIN_SRVLT_INVALID_PARAM=Invalid parameter
+ADMIN_SRVLT_INVALID_PATH=Invalid Content Template path
+ADMIN_SRVLT_NULL_RS_ID=Resource ID (RS_ID) can not be null
+ADMIN_SRVLT_RS_ID_BS=Resource ID (RS_ID) can not contain backslashes
+ADMIN_SRVLT_SPECIAL_ID=Not allowed to create this special user: {0}
+ADMIN_SRVLT_FAIL_COMMIT=Failed to save changes to the configuration file
+ADMIN_SRVLT_FAIL_PERFORM_1=Failed to perform 1
+ADMIN_SRVLT_FAIL_PERFORM_2=Failed to perform 2
+ADMIN_SRVLT_FAIL_PERFORM_3=Failed to perform 3
+ADMIN_SRVLT_FAIL_COMMIT=Failed to save changes to the configuration file
+#######
+# debug
+#######
+ADMIN_SRVLT_SERVICE_DENIED=service(): service denied.
+ADMIN_SRVLT_REP_EXIST_TYPE=replacing existing type {0}.
+ADMIN_SRVLT_CLASS_NOT_FOUND=class {0} not found.
+ADMIN_SRVLT_CLASS_NOT_EVAL=class is not com.netscape.certsrv.acls.IAccessEvaluator {0}.
+ADMIN_SRVLT_EVAL_NOT_FOUND=Evaluator attempted to be removed was not found.
+ADMIN_SRVLT_FAIL_SRC_TYPE=Failed on getting authz.sourceType, assuming authz info will be LDAP based.
+#######
+# debug
+#######
+ADMIN_SRVLT_AUTHZ_INITED=authz is to be initialized for servlet: {0} from XML
+ADMIN_SRVLT_AUTHZ_MGR_INIT_FAIL=AuthzMgrAccessInit failed.
+#######
+# debug
+#######
+ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE=authzmgrAccessInit for servlet: {0} from XML done
+ADMIN_SRVLT_PROP_ACL_NOT_SPEC={0} not specified in XML for servlet: {1}, use default authz mgr: {2}.
+ADMIN_SRVLT_AUTH_LDAP_NOT_XML=according to ccMode, authorization for servlet: {0} is LDAP based, not XML {1}, use default authz mgr: {2}.
+#######
+# debug
+#######
+ADMIN_SRVLT_ABOUT_AUTH=about authenticate() for servlet: {0}.
+ADMIN_SRVLT_AUTH_FOR_SRVLT=authenticated for servlet: {0}.
+ADMIN_SRVLT_AUTH_FAIL=authenticate(): {0} {1} {2}.
+ADMIN_SRVLT_NO_AUTH_TOKEN=AdminServlet: authenticate: User {0} is missing or null in the Auth token.
+ADMIN_SRVLT_USER_NOT_FOUND=AdminServlet: User {0} not found in user group database.
+ADMIN_SRVLT_USR_GRP_ERR=AdminServlet: User group error {0}.
+ADMIN_SRVLT_ERROR=AdminServlet: error {0}.
+#######
+# debug
+#######
+ADMIN_SRVLT_CHECK_AUTHZ_AUTH=About to check AuthzSubsystem authorization for servlet: {0}.
+ADMIN_SRVLT_AUTH_SUCCEED=authorization succeeded for servlet: {0}
+ADMIN_SRVLT_AUTH_FAILURE=Failed to authorize: {0}.
+ADMIN_SRVLT_GRP_AUTHZ_FAIL=CMSgateway: Group Authorization failed. User {0} was missing or null in the Auth token.
+ADMIN_SRVLT_USER_NOT_IN_DB=CMSgateway: Group Authorization failed. User {0} was not found in the user group database.
+ADMIN_SRVLT_USER_NOT_IN_GRP=CMSgateway: Group Authorization failed. User {0} was not a member of group {1}.
+ADMIN_SRVLT_GRP_AUTH_SUCC_USER=Group Authorization success. User {0} is a member of group {1}.
+ADMIN_SRVLT_USER_NOT_ANY_GRP="CMSgateway: Group Authorization failed. User {0} was not a member of any group in {1}.
+#######
+# debug
+#######
+ADMIN_SRVLT_PLUGIN_ADD=authManager plugin {0} added through console.
+ADMIN_SRVLT_AUTH_MGR_ADD=authManager instance {0} added through console.
+ADMIN_SRVLT_AUTH_MGR_REPL=authManager instance {0} replaced through console.
+ADMIN_SRVLT_BASIC_CONSTRAIN_NULL=MSAdminServlet: basic constraints extension is null.
+ADMIN_SRVLT_CERT_NO_EXT=CMSAdminServlet: This certificate doesn't have extensions.
+ADMIN_SRVLT_JS_PLUGIN_ADD=Job Scheduler plugin {0} added through console.
+ADMIN_SRVLT_JOB_INST_ADD=job instance {0} added through console.
+ADMIN_SRVLT_JOB_INST_REP=Job Scheduler job instance {0} replaced through console.
+ADMIN_SRVLT_FAIL_RES_LDAP=Failed to restart LDAP publishing: {0}.
+ADMIN_SRVLT_PUB_CA_CERT=Published CA cert.
+ADMIN_SRVLT_NO_PUB_CA_CERT=Could not publish CA's certificate {0}.
+#######
+# debug
+#######
+ADMIN_SRVLT_PUB_CRL=published CRL
+ADMIN_SRVLT_NO_PUB_CRL=Could not publish CRL {0}.
+#######
+# debug
+#######
+ADMIN_SRVLT_MAPPER_ADDED=mapper plugin {0} added through console.
+ADMIN_SRVLT_MAPPER_INST_ADDED=mapper instance {0} added through console.
+ADMIN_SRVLT_MAPPER_REPLACED=mapper {0} replaced through console.
+ADMIN_SRVLT_RULE_PLUG_ADDED=rule plugin {0} added through console.
+ADMIN_SRVLT_RULE_INST_ADDED=rule instance {0} added through console.
+ADMIN_SRVLT_RULE_INST_REP=rule instance {0} replaced through console.
+ADMIN_SRVLT_PUB_PLUG_ADDED=publisher plugin {0} added through console.
+ADMIN_SRVLT_PUB_INST_ADDED=publisher instance {0} added through console.
+ADMIN_SRVLT_PUB_INST_REP=publisher instance {0} replaced through console.
+ADMIN_SRVLT_CHECK_AUTHZ_SUB=about to check AuthzSubsystem authorization.
+ADMIN_SRVLT_AUTH_CALL_FAIL=authorize call: {0}
+ADMIN_SRVLT_ADD_USER_FAIL=addUser() failed {0}
+ADMIN_SRVLT_IS_PK_BLOB=is PKCS #7 blob?
+ADMIN_SRVLT_SINGLE_CERT_IMPORT=single self-signed certificate to import
+ADMIN_SRVLT_CERT_CHAIN_ACEND_ORD=certificate chain is in ascending order
+ADMIN_SRVLT_CERT_CHAIN_DESC_ORD=certificate chain is in descending order
+ADMIN_SRVLT_CERT_BAD_CHAIN=certificate chain is in random order or is an illegal certificate chain
+ADMIN_SRVLT_CHAIN_STORED_DB=user certificate from certificate chain is stored in the internaldb; certificate length={0}
+ADMIN_SRVLT_CERT_IN_CHAIN=certificate in certificate chain: {0} : {1}
+ADMIN_SRVLT_LEAF_CERT_NULL=importCACertPackage returns leaf certificate null
+ADMIN_SRVLT_LEAF_CERT_NON_NULL=got non-null leafCert
+ADMIN_SRVLT_NOT_INTERNAL_CERT=certificate not an instance of InternalCertificate: {0}
+ADMIN_SRVLT_PKS7_IGNORED=PKCS #7? {0} ignored
+ADMIN_SRVLT_BEFORE_VALIDITY=addUserCert(): before checkValidity()
+ADMIN_SRVLT_ADD_CERT_EXPIRED=addUserCert(): certificate expired: {0}.
+ADMIN_SRVLT_AIM_OUTPUT_FAIL=Output failed {0}.
+#######
+# debug
+#######
+ADMIN_SRVLT_AIM_ENROLL=AIMEnroll: process.
+ADMIN_SRVLT_ENROLL_ACCESS_AFTER_SETUP=Attempt to access adminEnroll after already setup.
+ADMIN_SRVLT_FAIL_GET_CERT_CHALL_PWRD=Failed to complete the request for getting certificates based on the challenge phrase password.
+ADMIN_SRVLT_ERR_STREAM_TEMPLATE=Error getting servlet output stream for rendering template. Error {0}.
+#######
+# debug
+#######
+ADMIN_SRVLT_ADDING_HEADER=adding header {0} yes
+ADMIN_SRVLT_ADDING_HEADER_NO=adding header {0} no
+ADMIN_SRVLT_ADD_MASTER_URL=adding masterURL = {0}
+ADMIN_SRVLT_CA_FROM_RA_NOT_IMP=getting a CRL from the RA is not implemented yet.
+ADMIN_SRVLT_ERR_GET_TEMPLATE=Error getting template {0} Error {1}.
+##################################################################
+# For com.netscape.cmscore.cert.prettyprint
+##################################################################
+PRETTYPRINT_TOKEN_CERTIFICATE=Certificate:
+PRETTYPRINT_TOKEN_DATA=Data:
+PRETTYPRINT_TOKEN_VERSION=Version:
+PRETTYPRINT_TOKEN_SERIAL=Serial Number:
+PRETTYPRINT_TOKEN_SIGALG=Signature Algorithm:
+PRETTYPRINT_TOKEN_ISSUER=Issuer:
+PRETTYPRINT_TOKEN_VALIDITY=Validity:
+PRETTYPRINT_TOKEN_NOT_BEFORE=Not Before:
+PRETTYPRINT_TOKEN_NOT_AFTER=Not After:
+PRETTYPRINT_TOKEN_SUBJECT=Subject:
+PRETTYPRINT_TOKEN_SPKI=Subject Public Key Info:
+PRETTYPRINT_TOKEN_ALGORITHM=Algorithm:
+PRETTYPRINT_TOKEN_PUBLIC_KEY=Public Key:
+PRETTYPRINT_TOKEN_PUBLIC_KEY_MODULUS=Public Key Modulus:
+PRETTYPRINT_TOKEN_PUBLIC_KEY_EXPONENT=Exponent:
+PRETTYPRINT_TOKEN_EXTENSIONS=Extensions:
+PRETTYPRINT_TOKEN_SIGNATURE=Signature:
+PRETTYPRINT_TOKEN_YES=yes
+PRETTYPRINT_TOKEN_NO=no
+PRETTYPRINT_TOKEN_IDENTIFIER=Identifier:
+PRETTYPRINT_TOKEN_CRITICAL=Critical:
+PRETTYPRINT_TOKEN_VALUE=Value:
+PRETTYPRINT_TOKEN_KEY_TYPE=Key Type
+PRETTYPRINT_TOKEN_CERT_TYPE=Netscape Certificate Type
+PRETTYPRINT_TOKEN_SKI=Subject Key Identifier
+PRETTYPRINT_TOKEN_AKI=Authority Key Identifier
+PRETTYPRINT_TOKEN_ACCESS_DESC=Access Description:
+PRETTYPRINT_TOKEN_OCSP_NOCHECK=OCSP NoCheck:
+PRETTYPRINT_TOKEN_EXTENDED_KEY_USAGE=Extended Key Usage:
+PRETTYPRINT_TOKEN_PRIVATE_KEY_USAGE=Private Key Usage:
+PRETTYPRINT_TOKEN_PRESENCE_SERVER=Presence Server:
+PRETTYPRINT_TOKEN_AIA=Authority Info Access:
+PRETTYPRINT_TOKEN_KEY_USAGE=Key Usage:
+PRETTYPRINT_TOKEN_CERT_USAGE=Certificate Usage:
+PRETTYPRINT_TOKEN_KEY_ID=Key Identifier:
+PRETTYPRINT_TOKEN_AUTH_NAME=Authority Name:
+PRETTYPRINT_TOKEN_CRL=Certificate Revocation List:
+PRETTYPRINT_TOKEN_THIS_UPDATE=This Update:
+PRETTYPRINT_TOKEN_NEXT_UPDATE=Next Update:
+PRETTYPRINT_TOKEN_REVOKED_CERTIFICATES=Revoked Certificates:
+PRETTYPRINT_TOKEN_REVOCATION_DATE=Revocation Date:
+PRETTYPRINT_TOKEN_REVOCATION_REASON=Revocation Reason
+PRETTYPRINT_TOKEN_REASON=Reason:
+PRETTYPRINT_TOKEN_BASIC_CONSTRAINTS=Basic Constraints
+PRETTYPRINT_TOKEN_NAME_CONSTRAINTS=Name Constraints
+PRETTYPRINT_TOKEN_NSC_COMMENT=Netscape Comment
+PRETTYPRINT_TOKEN_IS_CA=Is CA:
+PRETTYPRINT_TOKEN_PATH_LEN=Path Length Constraint:
+PRETTYPRINT_TOKEN_PATH_LEN_UNLIMITED=UNLIMITED
+PRETTYPRINT_TOKEN_PATH_LEN_UNDEFINED=UNDEFINED
+PRETTYPRINT_TOKEN_PATH_LEN_INVALID=INVALID
+PRETTYPRINT_TOKEN_CRL_NUMBER=CRL Number
+PRETTYPRINT_TOKEN_NUMBER=Number:
+PRETTYPRINT_TOKEN_DELTA_CRL_INDICATOR=Delta CRL Indicator
+PRETTYPRINT_TOKEN_BASE_CRL_NUMBER=Base CRL Number:
+PRETTYPRINT_TOKEN_CERT_SCOPE_OF_USE=Certificate Scope of Use
+PRETTYPRINT_TOKEN_SCOPE_OF_USE=Scope of Use:
+PRETTYPRINT_TOKEN_PORT=Port:
+PRETTYPRINT_TOKEN_ISSUER_ALT_NAME=Issuer Alternative Name
+PRETTYPRINT_TOKEN_ISSUER_NAMES=Issuer Names:
+PRETTYPRINT_TOKEN_SUBJECT_ALT_NAME=Subject Alternative Name
+PRETTYPRINT_TOKEN_DECODING_ERROR=Decoding Error
+PRETTYPRINT_TOKEN_FRESHEST_CRL_EXT=Freshest CRL
+PRETTYPRINT_TOKEN_CRL_DP_EXT=CRL Distribution Points
+PRETTYPRINT_TOKEN_CRLDP_NUMPOINTS=Number of Points:
+PRETTYPRINT_TOKEN_CRLDP_POINTN=Point
+PRETTYPRINT_TOKEN_CRLDP_DISTPOINT=Distribution Point:
+PRETTYPRINT_TOKEN_CRLDP_REASONS=Reason Flags:
+PRETTYPRINT_TOKEN_CRLDP_CRLISSUER=CRL Issuer:
+PRETTYPRINT_TOKEN_ISSUING_DIST_POINT=Issuing Distribution Point
+PRETTYPRINT_TOKEN_DIST_POINT_NAME=Distribution Point:
+PRETTYPRINT_TOKEN_FULL_NAME=Full Name:
+PRETTYPRINT_TOKEN_RELATIVE_NAME=Name Relative To CRL Issuer:
+PRETTYPRINT_TOKEN_ONLY_USER_CERTS=Only Contains User Certificates:
+PRETTYPRINT_TOKEN_ONLY_CA_CERTS=Only Contains CA Certificates:
+PRETTYPRINT_TOKEN_ONLY_SOME_REASONS=Only Some Reasons:
+PRETTYPRINT_TOKEN_INDIRECT_CRL=Indirect CRL:
+PRETTYPRINT_TOKEN_INVALIDITY_DATE=Invalidity Date
+PRETTYPRINT_TOKEN_DATE_OF_INVALIDITY=Invalidity Date:
+PRETTYPRINT_TOKEN_CERTIFICATE_ISSUER=Certificate Issuer
+PRETTYPRINT_TOKEN_HOLD_INSTRUCTION=Hold Instruction Code
+PRETTYPRINT_TOKEN_HOLD_INSTRUCTION_CODE=Hold Instruction Code:
+PRETTYPRINT_TOKEN_POLICY_CONSTRAINTS=Policy Constraints
+PRETTYPRINT_TOKEN_INHIBIT_POLICY_MAPPING=Inhibit Policy Mapping:
+PRETTYPRINT_TOKEN_REQUIRE_EXPLICIT_POLICY=Require Explicit Policy:
+PRETTYPRINT_TOKEN_POLICY_MAPPINGS=Policy Mappings
+PRETTYPRINT_TOKEN_MAPPINGS=Mappings:
+PRETTYPRINT_TOKEN_MAP=Map
+PRETTYPRINT_TOKEN_ISSUER_DOMAIN_POLICY=Issuer Domain Policy:
+PRETTYPRINT_TOKEN_SUBJECT_DOMAIN_POLICY=Subject Domain Policy:
+PRETTYPRINT_TOKEN_SUBJECT_DIR_ATTR=Subject Directory Attributes
+PRETTYPRINT_TOKEN_ATTRIBUTES=Attributes:
+PRETTYPRINT_TOKEN_ATTRIBUTE=Attribute
+PRETTYPRINT_TOKEN_VALUES=Values:
+PRETTYPRINT_TOKEN_NOT_SET=not set
+PRETTYPRINT_TOKEN_NONE=none
+PRETTYPRINT_TOKEN_CACHE_NOT_AVAILABLE=CRL cache is not available
+PRETTYPRINT_KeyUsageExtension.DIGITAL_SIGNATURE=Digital Signature
+PRETTYPRINT_KeyUsageExtension.NON_REPUDIATION=Non-Repudiation
+PRETTYPRINT_KeyUsageExtension.KEY_ENCIPHERMENT=Key Encipherment
+PRETTYPRINT_KeyUsageExtension.DATA_ENCIPHERMENT=Data Encipherment
+PRETTYPRINT_KeyUsageExtension.KEY_AGREEMENT=Key Agreement
+PRETTYPRINT_KeyUsageExtension.KEY_CERTSIGN=Key CertSign
+PRETTYPRINT_KeyUsageExtension.CRL_SIGN=CRL Sign
+PRETTYPRINT_KeyUsageExtension.ENCIPHER_ONLY=Encipher Only
+PRETTYPRINT_KeyUsageExtension.DECIPHER_ONLY=Decipher Only
+PRETTYPRINT_NSCertTypeExtension.SSL_CLIENT=SSL Client
+PRETTYPRINT_NSCertTypeExtension.SSL_SERVER=SSL Server
+PRETTYPRINT_NSCertTypeExtension.EMAIL=Secure Email
+PRETTYPRINT_NSCertTypeExtension.OBJECT_SIGNING=Object Signing
+PRETTYPRINT_NSCertTypeExtension.SSL_CA=SSL CA
+PRETTYPRINT_NSCertTypeExtension.EMAIL_CA=Secure Email CA
+PRETTYPRINT_NSCertTypeExtension.OBJECT_SIGNING_CA=ObjectSigning CA
+##################################################################
+# For com.netscape.cmscore.listeners
+##################################################################
+LISTENERS_NO_NOTIFY_SENDER_EMAIL_CONFIG_FOUND=No notify sender email found in the configuration.
+LISTENERS_NO_NOTIFY_RECVR_EMAIL_CONFIG_FOUND=No notify recipient email found in the configuration.
+##################################################################
+# For com.netscape.cms.util
+##################################################################
+UTIL_HASH_FILE_CHECK_USAGE=usage: HashFileCheck <filename>
+UTIL_BAD_ARG_COUNT=incorrect number of arguments
+UTIL_NO_SUCH_FILE_1=can't find file {0}
+UTIL_FILE_TRUNCATED=Log file has been truncated.
+UTIL_DIGEST_MATCH_1=Hash digest matches log file. {0} OK
+UTIL_DIGEST_DONT_MATCH_1=Hash digest does NOT match log file. {0} and/or hash file is corrupt or the password is incorrect.
+UTIL_EXCEPTION_1=Caught unexpected exception {0}
+UTIL_LOG_PASSWORD=Please enter the log file hash digest password:
+UTIL_NO_USERID=No user ID in config file. Running as {0}
+UTIL_NO_SUCH_USER_2=No such user as {0}. Running as {1}
+UTIL_NO_UID_PERMISSION_2=Can't change process UID to {0}. Running as {1}
+UTIL_SHUTDOWN_SIG=Received shutdown signal
+UTIL_RESTART_SIG=Received restart signal
+##################################################################
+# For com.netscape.cms.authorization
+##################################################################
+AUTHZ_EVALUATOR_NULL=access evaluator {0} is null
+AUTHZ_EVALUATOR_NOT_FOUND=access evaluator {0} not found
+AUTHZ_OP_NOT_SUPPORTED=operator {0} not supported
+AUTHZ_EVALUATOR_ACCESS_DENIED=checkPermission(): permission denied for the resource {0} on operation {1}
+AUTHZ_EVALUATOR_AUTHORIZATION_FAILED=Authorization Failed
+AUTHZ_EVALUATOR_FLUSH_RESOURCES=updateACLs: failed to flushResourceACLs(): {0}
+AUTHZ_EVALUATOR_INIT_ERROR=init() - {0}
+AUTHZ_EVALUATOR_FLUSH_ERROR=Shutdown Flush Error - {0}
+AUTHZ_EVALUATOR_LDAP_ERROR=LDAP Connection Shutdown Error - {0}
+##################################################################
+# For com.netscape.cms.crl
+##################################################################
+CRL_CREATE_AKI_EXT=Cannot create AuthorityKeyIdentifier extension - {0}
+CRL_CERT_PARSING_ERROR=Error parsing certificate - {0}
+CRL_CERT_CERT_EXCEPTION=certificate exception - {0}
+CRL_CREATE_CRL_NUMBER_EXT=Cannot create CRLNumber extension - {0}
+CRL_CREATE_CRL_REASON_EXT=Cannot create CRLReason extension - {0}
+CRL_CREATE_CERT_ISSUER_EXT=Cannot create CertificateIssuer extension - {0}
+CRL_CREATE_INVALID_NUM_NAMES=Invalid numNames property for CRL CertificateIssuer extension - {0}
+CRL_CREATE_UNDEFINED_TYPE=Undefined nameType {0} property for CRL CertificateIssuer extension - {1}
+CRL_CREATE_INVALID_TYPE=Invalid nameType {0} property for CRL CertificateIssuer extension - {1}
+CRL_CREATE_INVALID_500NAME=Invalid X500name - {0}
+CRL_CREATE_INVALID_NAME_TYPE=Invalid nameType {0} property for CertificateIssuer
+CRL_CREATE_DELTA_CRL_EXT=Cannot create DeltaCRLIndicator extension - {0}
+CRL_CREATE_HOLD_INSTR_EXT=Cannot create HoldInstruction extension - {0}
+CRL_CREATE_HOLD_UNDEFINED=Undefined instruction property for CRL HoldInstruction extension set to none - {0}
+CRL_CREATE_HOLD_INVALID=Invalid instruction property for CRL HoldInstruction extension set to none - {0}
+CRL_CREATE_INVALIDITY_DATE_EXT=Cannot create InvalidityDate extension - {0}
+CRL_CREATE_ISSUER_ALT_NAME_EXT=Cannot create IssuerAlternativeName extension - {0}
+CRL_CREATE_ISSUER_INVALID_NUM_NAMES=Invalid numNames property for IssuerAlternativeName extension - {0}
+CRL_CREATE_ISSUER_UNDEFINED_TYPE=Undefined nameType {0} property for CRL IssuerAlternativeName extension - {1}
+CRL_CREATE_ISSUER_INVALID_TYPE=Invalid nameType {0} property for CRL IssuerAlternativeName extension - {1}
+CRL_INVALID_OTHER_NAME=Invalid OtherName - {0}
+CRL_CREATE_DIST_POINT_UNDEFINED=Undefined pointType property for CRL IssuingDistributionPoint extension - {0}
+CRL_CREATE_DIST_POINT_INVALID=Invalid pointType property for CRL IssuingDistributionPoint extension - {0}
+CRL_CREATE_RDN=Error creating RDN - {0}
+CRL_INVALID_POTINT_TYPE=Invalid pointType {0} property for IssuingDistributionPoint
+CRL_CANNOT_SET_NAME=Cannot set general names in IssuingDistributionPoint - {0}
+CRL_INVALID_PROPERTY=Invalid {0} property for IssuingDistributionPoint - {1}
+CRL_CREATE_AIA_INVALID_NUM_ADS=Invalid number of AccessDescriptions in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_AM_UNDEFINED=Undefined accessMethod property in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_AM_INVALID=Invalid accessMethod property in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_ALT_UNDEFINED=Undefined accessLocationType property in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_ALT_INVALID=Invalid accessLocationType property in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_AL_UNDEFINED=Undefined accessLocation property in AuthorityInformationAccess extension - {0}
+CRL_CREATE_AIA_AD_AL_INVALID=Invalid accessLocation property in AuthorityInformationAccess extension - {0}
+##################################################################
+# For com.netscape.cms.evaluator
+##################################################################
+EVALUTOR_UG_NULL=UsrGrp subsystem is null
+EVALUTOR_UID_NULL=evaluate(): GroupAccessEvaluator.evaluate(): UID in authToken is null
+EVALUTOR_UID_IS_NULL=evaluate(): UserAccessEvaluator.evaluate(): UID in authToken is null
+EVALUATOR_IPADDRESS_NULL=evaluate(): IPAddressEvaluator.evaluate(): IPAdress in session context is null
+##################################################################
+# For com.netscape.cms.jobs
+##################################################################
+JOBS_TEMPLATE_INIT_ERROR=template init not successful
+JOBS_SEND_NOTIFICATION=Send Notification Error {0}
+JOBS_FAILED_PROCESS=Failed to process {0}
+JOBS_SUMMARY_CONTENT_NULL=summary content null
+JOBS_EXCEPTION_IN_RUN=Exception caught in run() {0}
+JOBS_GET_CERT_ERROR=failed getting CertRecord.ATTR_META_INFO REQUEST_ID for certificate serial number 0x{0}
+JOBS_META_INFO_ERROR=certificate serial number 0x{0} Error - getting CertRecord.ATTR_META_INFO: {1}
+JOBS_META_REQUEST_ERROR=certificate serial number 0x{0} Error - getting CertRecord.META_REQUEST_ID: {1}
+JOBS_FIND_REQUEST_ERROR=certificate serial number 0x{0} Error - RequestQueue.findRequest(): {1}
+JOBS_UNPUBLISH_ERROR=certificate serial number 0x{0} Error - unpublish(): {1}
+JOBS_PUBLISH_ERROR=certificate serial number 0x{0} Error - publish(): {1}
+##################################################################
+# For com.netscape.cms.listeners
+##################################################################
+LISTENERS_CERT_ISSUED_SET_RESOLVER=Error setting EmailResolverKeys: {0}
+LISTENERS_CERT_ISSUED_EXCEPTION=Exception caught in accept() {0}
+LISTENERS_CERT_ISSUED_NOTIFY_ERROR=failed to resolve email for notification: Serial Number={0}; Request ID={1}
+LISTENERS_CERT_ISSUED_TEMPLATE_ERROR=template null, serial number and requst ID sent to user: Serial Number={0}; Request ID={1}
+LISTENERS_CERT_ISSUED_REJECTION=CertIssued rejection file null
+LISTENERS_CERT_ISSUED_REJECTION_NOTIFICATION=failed to resolve email for rejection notification: Request ID={0}
+LISTENERS_CERT_ISSUED_SET=set(): invalid param name
+LISTENERS_REQUEST_PORT_NOT_FOUND=agent port not found
+LISTENERS_TEMPLATE_NOT_INIT=template init not successful
+LISTENERS_TEMPLATE_NOT_GET=Template not retrievable for Request in Queue notification
+LISTENERS_SEND_FAILED=Send failed: {0}
+##################################################################
+# For com.netscape.cms.logging
+##################################################################
+LOGGING_READ_ERROR=logging: {0}: read error at line {1}
+LOGGING_FILE_NOT_FOUND=logging: {0} not found
+#
+####################### SIGNED AUDIT EVENTS #############################
+# The following are signedAudit events. They are required by CIMC PP.
+# Please consult cfu before adding/deleting/modifying the following events
+#
+# signedAudit messages common fields:
+# Outcome must be "success" or "failure"
+# SubjectID must be the UID of the user responsible for the operation
+# "$System$" if system-initiated operation (e.g. log signing)
+#
+# LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP
+# - used at audit function startup
+#
+LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP_2=<type=AUDIT_LOG_STARTUP>:[AuditEvent=AUDIT_LOG_STARTUP][SubjectID={0}][Outcome={1}] audit function startup
+#
+# LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN
+# - used at audit function shutdown
+#
+LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN_2=<type=AUDIT_LOG_SHUTDOWN>:[AuditEvent=AUDIT_LOG_SHUTDOWN][SubjectID={0}][Outcome={1}] audit function shutdown
+#
+# LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION
+# - used for verifying CIMC system certificates
+# - CertNickName is the cert nickname
+#
+LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION_3=<type=CIMC_CERT_VERIFICATION>:[AuditEvent=CIMC_CERT_VERIFICATION][SubjectID={0}][Outcome={1}][CertNickName={2}] CIMC certificate verification
+#
+# LOGGING_SIGNED_AUDIT_ROLE_ASSUME
+# - used when user assumes a role (in current CS that's when one accesses a
+# role port)
+# Role must be be one of the valid roles, by default: "Administrators",
+# "Certificate Manager Agents", and "Auditors"
+# note that customized role names can be used once configured
+#
+LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3=<type=ROLE_ASSUME>:[AuditEvent=ROLE_ASSUME][SubjectID={0}][Outcome={1}][Role={2}] assume privileged role
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY
+# - used when configuring certificate policy constraints and extensions
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY_3=<type=CONFIG_CERT_POLICY>:[AuditEvent=CONFIG_CERT_POLICY][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] certificate policy constraint or extension configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE
+# - used when configuring certificate profile
+# (general settings and certificate profile)
+# (extensions and constraints policies are to be obsoleted but do it anyway)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE_3=<type=CONFIG_CERT_PROFILE>:[AuditEvent=CONFIG_CERT_PROFILE][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] certificate profile configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE
+# - used when configuring CRL profile
+# (extensions, frequency, CRL format)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE_3=<type=CONFIG_CRL_PROFILE>:[AuditEvent=CONFIG_CRL_PROFILE][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] CRL profile configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE
+# - used when configuring OCSP profile
+# (everything under Online Certificate Status Manager)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE_3=<type=CONFIG_OCSP_PROFILE>:[AuditEvent=CONFIG_OCSP_PROFILE][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] OCSP profile configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_AUTH
+# - used when configuring authentication
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+# --- Password MUST NOT be logged ---
+#
+LOGGING_SIGNED_AUDIT_CONFIG_AUTH_3=<type=CONFIG_AUTH>:[AuditEvent=CONFIG_AUTH][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] authentication configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_ROLE
+# - used when configuring role information (anything under users/groups)
+# add/remove/edit a role, etc)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3=<type=CONFIG_ROLE>:[AuditEvent=CONFIG_ROLE][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] role configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_ACL
+# - used when configuring ACL information
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_ACL_3=<type=CONFIG_ACL>:[AuditEvent=CONFIG_ACL][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] ACL configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT
+# - used when configuring signedAudit
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT_3=<type=CONFIG_SIGNED_AUDIT>:[AuditEvent=CONFIG_SIGNED_AUDIT][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] signed audit configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION
+# - used when configuring encryption (cert settings and SSL cipher preferences)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION_3=<type=CONFIG_ENCRYPTION>:[AuditEvent=CONFIG_ENCRYPTION][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] encryption configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY
+# - used when
+# 1. "Manage Certificate" is used to edit the trustness of certificates
+# and deletion of certificates
+# 2. "Certificate Setup Wizard" is used to import CA certificates into the
+# certificate database (Although CrossCertificatePairs are stored
+# within internaldb, audit them as well)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+#
+LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY_3=<type=CONFIG_TRUSTED_PUBLIC_KEY>:[AuditEvent=CONFIG_TRUSTED_PUBLIC_KEY][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] certificate database configuration
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_DRM
+# - used when configuring DRM
+# (Key recovery scheme, change of any secret component)
+# ParamNameValPairs must be a name;;value pair
+# (where name and value are separated by the delimiter ;;)
+# separated by + (if more than one name;;value pair) of config params changed
+# --- secret component (password) MUST NOT be logged ---
+#
+LOGGING_SIGNED_AUDIT_CONFIG_DRM_3=<type=CONFIG_DRM>:[AuditEvent=CONFIG_DRM][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] DRM configuration parameter(s) change
+#
+# LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION
+# - used when self tests are run
+#
+LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION_2=<type=SELFTESTS_EXECUTION>:[AuditEvent=SELFTESTS_EXECUTION][SubjectID={0}][Outcome={1}] self tests execution (see selftests.log for details)
+#
+# LOGGING_SIGNED_AUDIT_LOG_DELETE
+# - used AFTER audit log gets expired (authz should not allow,
+# but in case authz gets compromised. Make sure it is written
+# AFTER the log expiration happens)
+# LogFile must be the complete name (including the path) of the
+# signedAudit log that is attempted to be deleted
+#
+LOGGING_SIGNED_AUDIT_LOG_DELETE_3=<type=AUDIT_LOG_DELETE>:[AuditEvent=AUDIT_LOG_DELETE][SubjectID={0}][Outcome={1}][LogFile={2}] signedAudit log deletion
+#
+# LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE
+# - used when log file name (including any path changes) for any of
+# audit, system, transaction, or other customized log file
+# change is attempted (authz should not allow, but make sure it's
+# written after the attempt)
+# LogType must be "System", "Transaction", or "SignedAudit"
+# toLogFile must be the name (including any path changes) that the user is
+# attempting to change to
+#
+LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE_4=<type=LOG_PATH_CHANGE>:[AuditEvent=LOG_PATH_CHANGE][SubjectID={0}][Outcome={1}][LogType={2}][toLogFile={3}] log path change attempt
+#
+# LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE
+# - used when log expiration time change is attempted (authz should not
+# allow, but make sure it's written after the attempt)
+# LogType must be "System", "Transaction", or "SignedAudit"
+# ExpirationTime must be the amount of time (in seconds) that is
+# attempted to be changed to
+#
+# -- feature disabled --
+#LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE_4=<type=LOG_EXPIRATION_CHANGE>:[AuditEvent=LOG_EXPIRATION_CHANGE][SubjectID={0}][Outcome={1}][LogType={2}][ExpirationTime={3}] log expiration time change attempt
+#
+# LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST
+# - used when user private key archive request is made
+# this is an option in a certificate enrollment request detected by RA or CA
+# so should be seen logged right following the certificate request, if selected
+# ReqID must be the certificate enrollment request ID associated with the
+# CA archive option (even if the request was originally submitted via
+# an RA) (this field is set to the "EntityID" in caase of server-side key gen)
+# ArchiveID must be the DRM request ID associated with the enrollment ID,
+# ReqID (this field will be "N/A" when logged by the CA)
+#
+LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4=<type=PRIVATE_KEY_ARCHIVE_REQUEST>:[AuditEvent=PRIVATE_KEY_ARCHIVE_REQUEST][SubjectID={0}][Outcome={1}][ReqID={2}][ArchiveID={3}] private key archive request
+#
+# LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED
+# - used when user private key archive request is processed
+# this is when DRM receives and processed the request
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be archived
+#
+LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED_3=<type=PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED>:[AuditEvent=PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][PubKey={2}] private key archive request processed
+#
+# LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS
+# - used when user private key export request is made and processed with success
+# - this is used in case of server-side keygen when keys generated on the server
+# need to be transported back to the client
+# EntityID must be the id that represents the client
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be archived
+#
+LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4=<type=PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][EntityID={2}][PubKey={3}] private key export request processed with success
+#
+# LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE
+# - used when user private key export request is made and processed with failure
+# - this is used in case of server-side keygen when keys generated on the server
+# need to be transported back to the client
+# EntityID must be the id that represents the client
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be archived
+#
+LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4=<type=PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE>:[AuditEvent=PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][EntityID={2}][PubKey={3}] private key export request processed with failure
+#
+# LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST
+# - used when server-side key generation request is made
+# This is for tokenkeys
+# EntityID must be the representation of the subject that will be on the certificate when issued
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_3=<type=SERVER_SIDE_KEYGEN_REQUEST>:[AuditEvent=SERVER_SIDE_KEYGEN_REQUEST][SubjectID={0}][Outcome={1}][EntityID={2}] server-side key generation request processed
+#
+# LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS
+# - used when server-side key generation request has been processed with success
+# This is for tokenkeys
+# EntityID must be the representation of the subject that will be on the certificate when issued
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be archived
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS_4=<type=SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][EntityID={2}][PubKey={3}] server-side key generation request processed with success
+#
+# LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE
+# - used when server-side key generation request has been processed with failure
+# This is for tokenkeys
+# EntityID must be the representation of the subject that will be on the certificate when issued
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE_3=<type=SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE>:[AuditEvent=SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][EntityID={2}] server-side key generation request processed with failure
+#
+# LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST
+# - used when key recovery request is made
+# RecoveryID must be the recovery request ID
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be recovered
+#
+LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_4=<type=KEY_RECOVERY_REQUEST>:[AuditEvent=KEY_RECOVERY_REQUEST][SubjectID={0}][Outcome={1}][RecoveryID={2}][PubKey={3}] key recovery request made
+#
+# LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC
+# - used when asynchronous key recovery request is made
+# RequestID must be the recovery request ID
+# PubKey must be the base-64 encoded public key associated with
+# the private key to be recovered
+#
+LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC_4=<type=KEY_RECOVERY_REQUEST_ASYNC>:[AuditEvent=KEY_RECOVERY_REQUEST_ASYNC][SubjectID={0}][Outcome={1}][RequestID={2}][PubKey={3}] asynchronous key recovery request made
+#
+# LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN
+# - used when DRM agents login as recovery agents to approve
+# key recovery requests
+# RecoveryID must be the recovery request ID
+# RecoveryAgent must be the recovery agent the DRM agent is
+# logging in with
+#
+LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN_4=<type=KEY_RECOVERY_AGENT_LOGIN>:[AuditEvent=KEY_RECOVERY_AGENT_LOGIN][SubjectID={0}][Outcome={1}][RecoveryID={2}][RecoveryAgent={3}] key recovery agent login
+#
+# LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED
+# - used when key recovery request is processed
+# RecoveryID must be the recovery request ID
+# RecoveryAgents must be a comma-separated list of
+# UIDs of the recovery agents approving this request
+#
+LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_4=<type=KEY_RECOVERY_REQUEST_PROCESSED>:[AuditEvent=KEY_RECOVERY_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][RecoveryID={2}][RecoveryAgents={3}] key recovery request processed
+#
+# LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC
+# - used when key recovery request is processed
+# RequestID must be the recovery request ID
+# RecoveryAgents must be a comma-separated list of
+# UIDs of the recovery agents approving this request
+#
+LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC_4=<type=KEY_RECOVERY_REQUEST_PROCESSED_ASYNC>:[AuditEvent=KEY_RECOVERY_REQUEST_PROCESSED_ASYNC][SubjectID={0}][Outcome={1}][RequestID={2}][RecoveryAgents={3}] asynchronous key recovery request processed
+#
+# LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC
+# - used when asymmetric keys are generated
+# (like when CA certificate requests are generated -
+# e.g. CA certificate change over, renewal with new key, etc.)
+# PubKey must be the base-64 encoded public key material
+#
+LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC_3=<type=KEY_GEN_ASYMMETRIC>:[AuditEvent=KEY_GEN_ASYMMETRIC][SubjectID={0}][Outcome={1}][PubKey={2}] asymmetric key generation
+#
+# LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST
+# - used when a non-profile certificate request is made (before approval process)
+# SubjectID must be the UID of user that triggered this event
+# (if CMC enrollment requests signed by an agent, SubjectID should
+# be that of the agent), while
+# CertSubject must be the certificate subject name of the certificate request
+# ReqID must be the certificate request ID
+# ServiceID must be the identity of the servlet that submitted the original
+# request
+#
+LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5=<type=NON_PROFILE_CERT_REQUEST>:[AuditEvent=NON_PROFILE_CERT_REQUEST][SubjectID={0}][Outcome={1}][ReqID={2}][ServiceID={3}][CertSubject={4}] certificate request made without certificate profiles
+#
+# LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+# - used when a profile certificate request is made (before approval process)
+# SubjectID must be the UID of user that triggered this event
+# (if CMC enrollment requests signed by an agent, SubjectID should
+# be that of the agent), while
+# CertSubject must be the certificate subject name of the certificate request
+# ReqID must be the certificate request ID
+# ProfileID must be one of the certificate profiles defined by the
+# administrator
+#
+LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5=<type=PROFILE_CERT_REQUEST>:[AuditEvent=PROFILE_CERT_REQUEST][SubjectID={0}][Outcome={1}][ReqID={2}][ProfileID={3}][CertSubject={4}] certificate request made with certificate profiles
+#
+# LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED
+# - used when certificate request has just been through the approval process
+# SubjectID must be the UID of the agent who approves, rejects, or cancels
+# the certificate request
+# ReqID must be the request ID
+# InfoName must be value "certificate" (in case of approval), "rejectReason"
+# (in case of reject), or "cancelReason" (in case of cancel)
+# InfoValue must contain the certificate (in case of success), a reject reason in
+# text, or a cancel reason in text
+#
+LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5=<type=CERT_REQUEST_PROCESSED>:[AuditEvent=CERT_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][ReqID={2}][InfoName={3}][InfoValue={4}] certificate request processed
+#
+# LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST
+# - used when a certificate status change request (e.g. revocation)
+# is made (before approval process)
+# ReqID must be the request ID
+# CertSerialNum must be the serial number (in hex) of the certificate to be revoked
+# RequestType must be "revoke", "on-hold", "off-hold"
+#
+LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5=<type=CERT_STATUS_CHANGE_REQUEST>:[AuditEvent=CERT_STATUS_CHANGE_REQUEST][SubjectID={0}][Outcome={1}][ReqID={2}][CertSerialNum={3}][RequestType={4}] certificate revocation/unrevocation request made
+#
+# LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+# - used when certificate status is changed (revoked, expired, on-hold,
+# off-hold)
+# SubjectID must be the UID of the agent that processed the request
+# ReqID must be the request ID
+# RequestType must be "revoke", "on-hold", "off-hold"
+# Approval must be "complete", "rejected", or "canceled"
+# (note that "complete" means "approved")
+# CertSerialNum must be the serial number (in hex)
+# RevokeReasonNum must contain one of the following number:
+# reason number reason
+# --------------------------------------
+# 0 Unspecified
+# 1 Key compromised
+# 2 CA key compromised (should not be used)
+# 3 Affiliation changed
+# 4 Certificate superceded
+# 5 Cessation of operation
+# 6 Certificate is on-hold
+#
+LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7=<type=CERT_STATUS_CHANGE_REQUEST_PROCESSED>:[AuditEvent=CERT_STATUS_CHANGE_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][ReqID={2}][CertSerialNum={3}][RequestType={4}][RevokeReasonNum={5}][Approval={6}] certificate status change request processed
+#
+# LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS
+# - used when authorization is successful
+# Outcome must be success for this event
+# aclResource must be the ACL resource ID as defined in ACL resource list
+# Op must be one of the operations as defined with the ACL statement
+# e.g. "read" for an ACL statement containing "(read,write)"
+#
+LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4=<type=AUTHZ_SUCCESS>:[AuditEvent=AUTHZ_SUCCESS][SubjectID={0}][Outcome={1}][aclResource={2}][Op={3}] authorization success
+#
+# LOGGING_SIGNED_AUDIT_AUTHZ_FAIL
+# - used when authorization has failed
+# Outcome must be failure for this event
+# aclResource must be the ACL resource ID as defined in ACL resource list
+# Op must be one of the operations as defined with the ACL statement
+# e.g. "read" for an ACL statement containing "(read,write)"
+#
+LOGGING_SIGNED_AUDIT_AUTHZ_FAIL_4=<type=AUTHZ_FAIL>:[AuditEvent=AUTHZ_FAIL][SubjectID={0}][Outcome={1}][aclResource={2}][Op={3}] authorization failure
+#
+# LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS
+# - used when inter-CIMC_Boundary data transfer is successful
+# (this is used when data does not need to be captured)
+# ProtectionMethod must be one of the following: "SSL", or "unknown"
+# ReqType must be the request type
+# ReqID must be the request ID
+#
+LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS_5=<type=INTER_BOUNDARY>:[AuditEvent=INTER_BOUNDARY][SubjectID={0}][Outcome={1}][ProtectionMethod={2}][ReqType={3}][ReqID={4}] inter-CIMC_Boundary communication (data exchange) success
+#
+# LOGGING_SIGNED_AUDIT_AUTH_FAIL
+# - used when authentication fails (in case of SSL-client auth,
+# only webserver env can pick up the SSL violation;
+# CS authMgr can pick up certificate mis-match, so this event is used)
+# Outcome should always be "failure" in this event
+# (obviously, if authentication failed, you won't have a valid SubjectID, so
+# in this case, SubjectID should be $Unidentified$)
+# AuthMgr must be the authentication manager instance name that did
+# this authentication
+# AttemptedCred must be the credential attempted and failed
+#
+LOGGING_SIGNED_AUDIT_AUTH_FAIL_4=<type=AUTH_FAIL>:[AuditEvent=AUTH_FAIL][SubjectID={0}][Outcome={1}][AuthMgr={2}][AttemptedCred={3}] authentication failure
+#
+# LOGGING_SIGNED_AUDIT_AUTH_SUCCESS
+# - used when authentication succeeded
+# Outcome should always be "success" in this event
+# AuthMgr must be the authentication manager instance name that did
+# this authentication
+#
+LOGGING_SIGNED_AUDIT_AUTH_SUCCESS_3=<type=AUTH_SUCCESS>:[AuditEvent=AUTH_SUCCESS][SubjectID={0}][Outcome={1}][AuthMgr={2}] authentication success
+#
+# LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL
+# - used when an agent approves/disapproves a certificate profile set by the
+# administrator for automatic approval
+# ProfileID must be one of the profiles defined by the administrator
+# and to be approved by an agent
+# Op must be "approve" or "disapprove"
+#
+LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL_4=<type=CERT_PROFILE_APPROVAL>:[AuditEvent=CERT_PROFILE_APPROVAL][SubjectID={0}][Outcome={1}][ProfileID={2}][Op={3}] certificate approval
+#
+# LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION
+# - used when proof of possession is checked during certificate enrollment
+#
+LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2=<type=PROOF_OF_POSSESSION>:[AuditEvent=PROOF_OF_POSSESSION][SubjectID={0}][Outcome={1}] checking proof of possession
+#
+# LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL
+# - used when CRLs are retrieved by the OCSP Responder
+# Outcome is "success" when CRL is retrieved successfully, "failure" otherwise
+# CRLnum is the CRL number that identifies the CRL
+#
+LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL_3=<type=CRL_RETRIEVAL>:[AuditEvent=CRL_RETRIEVAL][SubjectID={0}][Outcome={1}][CRLnum={2}] CRL retrieval
+#
+# LOGGING_SIGNED_AUDIT_CRL_VALIDATION
+# - used when CRL is retrieved and validation process occurs
+#
+LOGGING_SIGNED_AUDIT_CRL_VALIDATION_2=<type=CRL_VALIDATION>:[AuditEvent=CRL_VALIDATION][SubjectID={0}][Outcome={1}] CRL validation
+#
+# LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST
+# - used when a CA is attempted to be added to the OCSP Responder
+# Outcome is "success" as the request is made
+# CA must be the base-64 encoded PKCS7 certificate (or chain)
+LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_3=<type=OCSP_ADD_CA_REQUEST>:[AuditEvent=OCSP_ADD_CA_REQUEST][SubjectID={0}][Outcome={1}][CA={2}] request to add a CA for OCSP Responder
+#
+# LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED
+# - used when an add CA request to the OCSP Responder is processed
+# Outcome is "success" when CA is added successfully, "failure" otherwise
+# CASubjectDN is the subject DN of the leaf CA cert in the chain
+LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED_3=<type=OCSP_ADD_CA_REQUEST_PROCESSED>:[AuditEvent=OCSP_ADD_CA_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][CASubjectDN={2}] Add CA for OCSP Responder
+#
+# LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST
+# - used when a CA is attempted to be removed from the OCSP Responder
+# Outcome is "success" as the request is made
+# CA must be the DN id of the CA
+LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_3=<type=OCSP_REMOVE_CA_REQUEST>:[AuditEvent=OCSP_REMOVE_CA_REQUEST][SubjectID={0}][Outcome={1}][CA={2}] request to remove a CA from OCSP Responder
+#
+# LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED_SUCCESS
+# - used when a remove CA request to the OCSP Responder is processed successfully
+# Outcome is "success" when CA is removed successfully, "failure" otherwise
+# CASubjectDN is the subject DN of the leaf CA cert in the chain
+LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS_3=<type=OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][CASubjectDN={2}] Remove CA for OCSP Responder is successful
+#
+# LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE
+# - used when a remove CA request to the OCSP Responder is processed and failed
+# Outcome is "failure"
+# CASubjectDN is DN ID of the CA
+LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE_3=<type=OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE>:[AuditEvent=OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][CASubjectDN={2}] Remove CA for OCSP Responder has failed
+#
+# LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY
+# - used when CMC (agent-pre-signed) certificate requests or revocation requests
+# are submitted and signature is verified
+# ReqType must be the request type (enrollment, or revocation)
+# CertSubject must be the certificate subject name of the certificate request
+# SignerInfo must be a unique String representation for the signer
+#
+LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY_5=<type=CMC_SIGNED_REQUEST_SIG_VERIFY>:[AuditEvent=CMC_SIGNED_REQUEST_SIG_VERIFY][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}] agent pre-approved CMC request signature verification
+
+# LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST
+# - used for TPS to TKS to get random challenge data
+# AgentID must be the trusted agent id used to make the request
+LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_2=<type=COMPUTE_RANDOM_DATA_REQUEST>:[AuditEvent=COMPUTE_RANDOM_DATA_REQUEST][Outcome={0}][AgentID={1}] TKS Compute random data request
+
+# LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS
+# - used for TPS to TKS to get random challenge data
+# Outcome is SUCCESS or FAILURE
+# Status is 0 for no error.
+# AgentID must be the trusted agent id used to make the request
+LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS_3=<type=COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS][Outcome={0}][Status={1}][AgentID={2}] TKS Compute random data request processed successfully
+
+# LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE
+# - used for TPS to TKS to get random challenge data
+# Outcome is SUCCESS or FAILURE
+# Status is 0 for no error.
+# Error gives the error message
+# AgentID must be the trusted agent id used to make the request
+LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE_4=<type=COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE>:[AuditEvent=COMPUTE_RANDOM_DATA_REQUEST_PROCCESED_FAILURE][Outcome={0}][Status={1}][AgentID={2}][Error={3}] TKS Compute random data request failed
+
+#
+#
+# LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST
+# - used for TPS to TKS to get a sessoin key for secure channel setup
+# SubjectID must be the CUID of the token establishing the secure channel
+# AgentID must be the trusted agent id used to make the request
+LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_3=<type=COMPUTE_SESSION_KEY_REQUEST>:[AuditEvent=COMPUTE_SESSION_KEY_REQUEST][SubjectID={0}][Outcome={1}][AgentID={2}] TKS Compute session key request
+#
+#
+# LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS
+# - request for TPS to TKS to get a sessoin key for secure channel processed
+# SubjectID must be the CUID of the token establishing the secure channel
+# AgentID must be the trusted agent id used to make the request
+# Outcome is SUCCESS or FAILURE
+# Status is 0 for no error.
+# IsCryptoValidate tells if the card cryptogram is to be validated
+# IsServerSideKeygen tells if the keys are to be generated on server
+# SelectedToken is the cryptographic token performing key operations
+# KeyNickName is the number keyset ex: #01#01
+#
+LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS_8=<type=COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][IsCryptoValidate={4}][IsServerSideKeygen={5}][SelectedToken={6}][KeyNickName={7}] TKS Compute session key request processed successfully
+#
+#
+# LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE
+# - request for TPS to TKS to get a sessoin key for secure channel processed
+# SubjectID must be the CUID of the token establishing the secure channel
+# Outcome is SUCCESS or FAILURE
+# Status is error code or 0 for no error.
+# AgentID must be the trusted agent id used to make the request
+# status is 0 for success, non-zero for various errors
+# IsCryptoValidate tells if the card cryptogram is to be validated
+# IsServerSideKeygen tells if the keys are to be generated on server
+# SelectedToken is the cryptographic token performing key operations
+# KeyNickName is the numeric keyset ex: #01#01
+# Error gives the error message
+LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE_9=<type=COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE>:[AuditEvent=COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][IsCryptoValidate={4}][IsServerSideKeygen={5}][SelectedToken={7}][KeyNickName={7}][Error={8}] TKS Compute session key request failed
+#
+
+# LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST
+# - request for TPS to TKS to do key change over
+# SubjectID must be the CUID of the token requesting key change over
+# AgentID must be the trusted agent id used to make the request
+# status is 0 for success, non-zero for various errors
+# oldMasterKeyName is the old master key name
+# newMasterKeyName is the new master key name
+LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_5=<type=DIVERSIFY_KEY_REQUEST>:[AuditEvent=DIVERSIFY_KEY_REQUEST][SubjectID={0}][Outcome={1}][AgentID={2}][oldMasterKeyName={3}][newMasterKeyName={4}] TKS Key Change Over request
+#
+###########################
+# LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS
+# - request for TPS to TKS to do key change over request processed
+# SubjectID must be the CUID of the token requesting key change over
+# AgentID must be the trusted agent id used to make the request
+# Outcome is SUCCESS or FAILURE
+# status is 0 for success, non-zero for various errors
+# oldMasterKeyName is the old master key name
+# newMasterKeyName is the new master key name
+LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS_6=<type=DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][oldMasterKeyName={4}][newMasterKeyName={5}] TKS Key Change Over request processed successfully
+#
+#
+###########################
+# LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE
+# - request for TPS to TKS to do key change over request processed
+# SubjectID must be the CUID of the token requesting key change over
+# AgentID must be the trusted agent id used to make the request
+# Outcome is SUCCESS or FAILURE
+# status is 0 for success, non-zero for various errors
+# oldMasterKeyName is the old master key name
+# newMasterKeyName is the new master key name
+# Error gives the error message
+LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE_7=<type=DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE>:[AuditEvent=DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][oldMasterKeyName={4}][newMasterKeyName={5}][Error={6}] TKS Key Change Over request failed
+#
+
+# LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST
+# - request from TPS to TKS to encrypt data
+# (or generate random data and encrypt)
+# SubjectID must be the CUID of the token requesting encrypt data
+# AgentID must be the trusted agent id used to make the request
+# status is 0 for success, non-zero for various errors
+# isRandom tells if the data is randomly generated on TKS
+LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_4=<type=ENCRYPT_DATA_REQUEST>:[AuditEvent=ENCRYPT_DATA_REQUEST][SubjectID={0}][status={1}][AgentID={2}][isRandom={3}] TKS encrypt data request
+#
+#
+# LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS
+# - request from TPS to TKS to encrypt data
+# (or generate random data and encrypt)
+# SubjectID must be the CUID of the token requesting encrypt data
+# AgentID must be the trusted agent id used to make the request
+# Outcome is SUCCESS or FAILURE
+# status is 0 for success, non-zero for various errors
+# isRandom tells if the data is randomly generated on TKS
+# SelectedToken is the cryptographic token performing key operations
+# KeyNickName is the numeric keyset ex: #01#01
+LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS_7=<type=ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS>:[AuditEvent=ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][isRandom={4}][SelectedToken={5}][KeyNickName={6}] TKS encrypt data request processed successfully
+#
+#
+# LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE
+# - request from TPS to TKS to encrypt data
+# (or generate random data and encrypt)
+# SubjectID must be the CUID of the token requesting encrypt data
+# AgentID must be the trusted agent id used to make the request
+# Outocme is SUCCESS or FAILURE
+# status is 0 for success, non-zero for various errors
+# isRandom tells if the data is randomly generated on TKS
+# SelectedToken is the cryptographic token performing key operations
+# KeyNickName is the numeric keyset ex: #01#01
+# Error gives the error message
+LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE_8=<type=ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE>:[AuditEvent=ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE][SubjectID={0}][Outcome={1}][status={2}][AgentID={3}][isRandom={4}][SelectedToken={5}][KeyNickName={6}][Error={7}] TKS encrypt data request failed
+#
+#
+#
+
+
+###########################
+#Unselectable signedAudit Events
+#
+# LOGGING_SIGNED_AUDIT_SIGNING
+# - used when a signature on the audit log is generated (same as "flush" time)
+# SubjectID is predefined to be "$System$" because this operation
+# associates with no user
+# sig must be the base-64 encoded signature of the buffer just flushed
+#
+LOGGING_SIGNED_AUDIT_SIGNING_3=[AuditEvent=AUDIT_LOG_SIGNING][SubjectID={0}][Outcome={1}] signature of audit buffer just flushed: sig: {2}
+##################################################################
+# For com.netscape.cms.ocsp
+##################################################################
+OCSP_REQUEST_FAILURE=request processing failure {0}
+OCSP_DECODE_CERT=failed to decode certificate data e={0}
+OCSP_DECODE_CRL=failed to decode CRL data e={0}
+OCSP_LOCATE_CA=Failed to locate CA Certificate {0}
+OCSP_LOCATE_CRL=Failed to locate CRL {0}
+##################################################################
+# For com.netscape.cms.publish
+##################################################################
+PUBLISH_DN_PATTERN_INIT=Can't init the dnPattern: {0} - {1}
+PUBLISH_DN_NOT_FORMED=No DN formed
+PUBLISH_MORE_THAN_ONE_ENTRY=More than one entry {0} returned for {1}
+PUBLISH_ENTRY_NOT_FOUND=No entry {0} found for {1}
+PUBLISH_NO_LDAP_SERVER=Cannot connect to LDAP server. Error: LDAP Server is unavailable.
+PUBLISH_DN_MAP_EXCEPTION={0} exception in map {1}
+PUBLISH_CA_ENTRY_NOT_CREATED=CA entry is not created. This may be because of the UID uniqueness plugin setting in your slapd.ldbm.conf and the possibility that there is an entry with the same UID that already exists. See release notes for details.
+PUBLISH_CA_ENTRY_NOT_CREATED1=CA entry was not created. This may be because there are entries in the directory hierarchy that do not exist.
+PUBLISH_EXCEPTION_CAUGHT=EBasexception caught: {0}
+PUBLISH_CANT_GET_EXT=can't get ext {0}
+PUBLISH_PUBLISH_OBJ_NOT_SUPPORTED=No support for publish object {0}
+PUBLISH_CANT_FORM_DN=Can't form DN for request: {0} {1}
+PUBLISH_CANT_DECODE_CERT=Cannot decode cert: {0}
+PUBLISH_CANT_DECODE_CRL=Cannot decode CRL: {0}
+PUBLISH_NOT_SUPPORTED_OBJECT=No support for this publish object
+PUBLISH_CANT_GET_SUBJECT=Cannot get subject name in map: {0}
+PUBLISH_NO_BASE=No base and no DN formed
+PUBLISH_FROM_SUBJ_TO_DN=from subjname to DN comps failed: {0}
+PUBLISH_FILE_PUBLISHER_ERROR=FileBasedPublisher: {0}
+PUBLISH_PUBLISHER_EXCEPTION={0} exception in publisher {1}
+PUBLISH_UNPUBLISH_ERROR=Error unpublishing: {0}
+PUBLISH_PUBLISH_ERROR=Error publishing: {0}
+PUBLISH_CHECK_FAILED=Check failed: {0}
+PUBLISH_SET_CRL_REASON=Error setting CRL reason {0}. Error {1}
+PUBLISH_OCSP_PUBLISHER_ERROR=OCSPPublisher: {0}
+##################################################################
+# For com.netscape.cms.selftests
+##################################################################
+SELFTESTS_PARAMETER_WAS_NULL={0}: a self test parameter was null
+SELFTESTS_MISSING_NAME={0}: the self test property name {1} does not exist
+SELFTESTS_MISSING_VALUES={0}: the self test property name {1} contained no value(s)
+SELFTESTS_INVALID_VALUES={0}: the self test property name {1} contained invalid value(s)
+SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_FAILURE={0}: system certs verification failure
+SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_SUCCESS={0}: system certs verification success
+SELFTESTS_CA_IS_NOT_PRESENT={0}: CA is NOT present
+SELFTESTS_CA_IS_NOT_INITIALIZED={0}: CA is NOT yet initialized
+SELFTESTS_CA_IS_CORRUPT={0}: CA public key is corrupt
+SELFTESTS_CA_IS_PRESENT={0}: CA is present
+SELFTESTS_CA_IS_NOT_YET_VALID={0}: CA is not yet valid
+SELFTESTS_CA_IS_EXPIRED={0}: CA is expired
+SELFTESTS_CA_IS_VALID={0}: CA is valid
+SELFTESTS_OCSP_IS_NOT_PRESENT={0}: OCSP is NOT present
+SELFTESTS_OCSP_IS_NOT_INITIALIZED={0}: OCSP is NOT yet initialized
+SELFTESTS_OCSP_IS_CORRUPT={0}: OCSP public key is corrupt
+SELFTESTS_OCSP_IS_PRESENT={0}: OCSP is present
+SELFTESTS_OCSP_IS_NOT_YET_VALID={0}: OCSP is not yet valid
+SELFTESTS_OCSP_IS_EXPIRED={0}: OCSP is expired
+SELFTESTS_OCSP_IS_VALID={0}: OCSP is valid
+SELFTESTS_KRA_IS_NOT_PRESENT={0}: KRA is NOT present
+SELFTESTS_KRA_IS_NOT_INITIALIZED={0}: KRA is NOT yet initialized
+SELFTESTS_KRA_IS_CORRUPT={0}: KRA public key is corrupt
+SELFTESTS_KRA_IS_PRESENT={0}: KRA is present
+SELFTESTS_RA_IS_NOT_PRESENT={0}: RA is NOT present
+SELFTESTS_RA_IS_NOT_INITIALIZED={0}: RA is NOT yet initialized
+SELFTESTS_RA_IS_CORRUPT={0}: RA public key is corrupt
+SELFTESTS_RA_IS_PRESENT={0}: RA is present
+SELFTESTS_TKS_FAILED={0}: TKS self test called {1} FAILED!
+SELFTESTS_TKS_SUCCEEDED={0}: TKS self test called {1} ran SUCCESSFULLY
+SELFTESTS_RUN_ON_DEMAND_REQUEST={0}: the passed in request parameter {1}, used to invoke running self tests on-demand, was missing
+SELFTESTS_RUN_ON_DEMAND={0}: Running self test plugins specified to be executed on-demand:
+SELFTESTS_NOT_RUN_ON_DEMAND={0}: There were NO self test plugins specified to be run on-demand!
+SELFTESTS_RUN_ON_DEMAND_FAILED={0}: The CRITICAL self test plugin called {1} running on-demand FAILED!
+SELFTESTS_RUN_ON_DEMAND_SUCCEEDED={0}: All CRITICAL self test plugins ran SUCCESSFULLY on-demand!
+##################################################################
+# For com.netscape.certsrv.listeners
+##################################################################
+NO_NOTIFY_SENDER_EMAIL_CONFIG_FOUND=No sender email notification found in the configuration.
+NO_NOTIFY_RECVR_EMAIL_CONFIG_FOUND=No recipient email notification found in the configuration.
diff --git a/pki/base/common/src/UserMessages.properties b/pki/base/common/src/UserMessages.properties
new file mode 100644
index 000000000..f1570198a
--- /dev/null
+++ b/pki/base/common/src/UserMessages.properties
@@ -0,0 +1,1128 @@
+#
+# User Messages
+#
+#######################################################
+# General
+#
+# Servlets which display these messages
+#
+#
+# ProfileApproveServlet
+# ProfileProcessServlet
+# ProfileReviewServlet
+# ProfileSelectServlet
+# ProfileSubmitServlet
+#
+#######################################################
+CMS_AUTHENTICATION_ERROR=Authentication Error
+CMS_AUTHORIZATION_ERROR=Authorization Error
+CMS_INTERNAL_ERROR=Server Internal Error
+CMS_REQUEST_ID_NOT_FOUND=Request ID Not Found
+CMS_PROFILE_ID_NOT_FOUND=Profile ID Not Found
+CMS_PROFILE_ID_NOT_ENABLED=Profile ID Not Enabled
+CMS_OP_NOT_FOUND=Operation Not Found
+CMS_REQUEST_NOT_FOUND=Request {0} Not Found
+CMS_REQUEST_NOT_PENDING=Request Not In Pending State
+CMS_AUTHENTICATION_MANAGER_NOT_FOUND=Authentication Manager {0} Not Found
+CMS_INVALID_PROPERTY=Invalid Property {0}
+CMS_INVALID_OPERATION=Invalid operation
+#######################################################
+# Base
+#
+# Servlets which display these messages
+#
+# AuthAdminServlet
+# ImportCertsTemplateFiler servlet
+# DoUnrevoke servlet
+# GetCertFromRequest servlet
+# UsrGrpAdminServlet
+# ListCerts servlet
+# ReasonToRevoke servlet
+# SrchCerts servlet
+# DisplayBySerialForRecovery servlet
+# ExamineRecovery servlet
+# GetPk12 servlet
+# GrantRecovery servlet
+# RecoverBySerial servlet
+# SrchKey servlet
+# SrchKeyForRecovery servlet
+# CheckRequest servlet
+# ProcessCertReq servlet
+# ProcessReq servelt
+#######################################################
+CMS_BASE_CERT_NOT_FOUND=Certificate not found
+CMS_BASE_ENCODE_CERT_FAILED=Failed to encode certificate
+CMS_BASE_NOT_TOKEN_CERT=The certificate being deleted is not a token certificate
+CMS_BASE_CERT_ERROR=Certificate Error: {0}
+CMS_BASE_INVALID_CERT_FORMAT=Invalid certificate content
+CMS_BASE_CONN_FAILED=Connection failed {0}
+CMS_BASE_REMOTE_AUTHORITY_ERROR=Backend server rejected or cancelled the request.
+CMS_BASE_INVALID_JOB_CRON=Invalid cron job
+CMS_BASE_ATTRIBUTE_NOT_FOUND=Attribute not found {0}
+CMS_BASE_INVALID_ATTR_TYPE=Invalid type for attribute {0}, error: {1}
+CMS_BASE_INVALID_ATTR_VALUE=Invalid value for attribute {0}, error: {1}
+CMS_BASE_MUST_BE_POSITIVE_NUMBER={0} must be a positive number greater than 0
+CMS_BASE_A_GREATER_THAN_EQUAL_B={0} must be greater than {1}
+CMS_BASE_MISSING_PKCS10_HEADER=Missing PKCS #10 header
+CMS_BASE_MISSING_PKCS10_TRAILER=Missing PKCS #10 trailer
+CMS_BASE_UNKNOWN_HOST=Invalid host name {0}
+CMS_BASE_INVALID_REQUEST_TYPE=Invalid request type {0}
+CMS_BASE_PID_EXIST=pid exists in the logs directory, server may already be running
+CMS_BASE_AUTHENTICATE_FAILED=Failed to authenticate - {0}
+CMS_BASE_INTERNAL_ERROR=Internal Error: {0}
+CMS_BASE_INVALID_OPERATION=Invalid operation
+CMS_BASE_NO_CONFIG_FILE=Cannot find config file: {0}
+CMS_BASE_CREATE_SERVICE_FAILED=Failed to create {0} service: {1}
+CMS_BASE_GET_PROPERTY_FAILED=Property {0} missing value
+CMS_BASE_GET_PROPERTY_NOVALUE=Property {0} missing value
+CMS_BASE_INVALID_PROPERTY=Cannot convert property {0}
+CMS_BASE_INVALID_PROPERTY_1=Cannot convert value of property {0} to a {1}. Expected format is {2}
+CMS_BASE_LOAD_FAILED=Failed to load {0}
+CMS_BASE_LOAD_FAILED_1=Failed to load {0}. Error {1}
+CMS_BASE_PERMISSION_DENIED=Permission denied
+CMS_BASE_INVALID_ATTRIBUTE=Invalid attribute {0}
+CMS_BASE_REQUEST_IN_BAD_STATE=Request is in a bad state
+CMS_BASE_ATTRIBUTE_NAME_CAN_NOT_BE_RESOLVED=Attribute name can not be resolved : {0}
+CMS_BASE_UTF8_NOT_SUPPORTED=Internal Error: UTF8 encoding not supported. Check your classpath or installation
+CMS_BASE_CA_SIGNINGCERT_NOT_FOUND=CA signing certificate not found
+CMS_BASE_INVALID_NUMBER_FORMAT=Invalid number format
+CMS_BASE_INVALID_NUMBER_FORMAT_1=Invalid number format: {0}
+CMS_BASE_INVALID_CERT_EXTENSION=Invalid certificate extension
+CMS_BASE_INVALID_ECC_CURVE_NAME=Invalid ECC Curve Name
+CMS_BASE_NO_EMPTY_CIPHERPREFS=Blank cipher preferences are not allowed
+CMS_BASE_LOGIN_FAILED=Failed to login to the token: incorrect password
+CMS_BASE_INVALID_KEYSIZE_PARAMS=The key size {0} is outside the bounds described by the DSA key pair generation algorithm.
+CMS_BASE_PQG_GEN_FAILED=Failed to generate the PQG parameters
+CMS_BASE_ALG_NOT_SUPPORTED=The algorithm {0} is not supported
+CMS_BASE_KEY_GEN_FAILED=Failed to generate the key pair
+CMS_BASE_TOKEN_NOT_FOUND=Token {0} not found
+CMS_BASE_INVALID_X500_NAME={0} does not conform to X500
+CMS_BASE_PROVIDER_NOT_SUPPORTED=The provider is not supported
+CMS_BASE_INVALID_KEY=Invalid key
+CMS_BASE_INVALID_KEY_1=Invalid key: {0}
+CMS_BASE_CERT_REQ_FAILED=Failed to generate a certificate request
+CMS_BASE_INVALID_CERT=Invalid certificate information: {0}
+CMS_BASE_INVALID_SIGNATURE=Invalid signature
+CMS_BASE_DECODE_CERT_FAILED=Failed to decode certificate
+CMS_BASE_CRYPTOMANAGER_UNINITIALIZED=Crypto manager has not been initialized
+CMS_BASE_USERCERT_CONFLICT=Certificate conflicts with an existing certificate on the token. If it is a Subject DN conflict, go back to the Subject Name panel to re-enter the DN. If this is a clone CA, make sure its serial number range begins with a number greater than that of all the certificates existing on the master's DB.
+CMS_BASE_NICKNAME_CONFLICT=Nickname has a conflict
+CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN=Item was not found on the token
+CMS_BASE_SIGNED_FAILED=Signed Error: {0}
+CMS_BASE_TOKEN_ERROR=Token Error
+CMS_BASE_TOKEN_ERROR_1=Token Error: {0}
+CMS_BASE_REVOCATION_CHALLENGE_QUEUE_FAILED=Failed to get the queue for challenge phrase authentication
+CMS_BASE_GET_QUEUE_FAILED=Failed to get the request queue
+CMS_BASE_REQUIRED_PARAMETER={0} is a required parameter
+CMS_BASE_LOAD_CLASS_FAILED=Failed to load class {0}. Error: {1}
+CMS_BASE_INVALID_VALUE_FOR_TYPE=Invalid value for type {0}. Error: {1}
+CMS_BASE_INVALID_IP_ADDR=Invalid IP Address {0}.
+CMS_BASE_IMPORT_CERT_FAILED=Failed to import the certificate.
+CMS_BASE_INVALID_ISSUER_NAME=The client certificate was not issued from this CA
+CMS_BASE_INVALID_CERT_STATUS=Invalid certificate status: {0}
+CMS_BASE_DUPLICATE_ROLES=User {0} cannot be added to this group because he/she already belonged to some other groups
+CMS_BASE_NO_SUCH_ALGORITHM=No such algorithm
+#######################################################
+# CS gateway
+# Servlets which display these messages
+#
+# CMCRevReqServlet
+# ImportCertsTemplateFiller servlet
+# DisableEnrollResult servlet
+# DisplayCRL servlet
+# DisplayHashUserEnroll servlet
+# DoUnrevoke servlet
+# EnableEnrollResult servlet
+# EnrollServlet
+# GetBySerial servlet
+# GetCAChain servlet
+# GetCRL servlet
+# GetUserCertFromRequest servlet
+# GetEnableStatus servlet
+# GetInfo servlet
+# GetOCSPInfo servlet
+# HashEnrolServlet
+# ListCerts servlet
+# Monitor servlet
+# ReasonToRevoke servlet
+# RemotAuthConfig servlet
+# RenewalServlet
+# RevocationServlet
+# SrchCerts servlet
+# UpdateCRL servlet
+# UpdateDir servlet
+# DisplayBySerialForRecovery servlet
+# ConfirmRecoverBySerial servlet
+# DisaplayBySerial servlet
+# DisplayTransport servlet
+# ExamineRecovery servlet
+# GetApprovalStatus servlet
+# GetPk12 servlet
+# GrantRecovery servlet
+# RecoverBySerial servlet
+# SrchKey servlet
+# SrchKeyForRecovery servlet
+# AddCAServlet
+# AddCRLServlet
+# CheckCertServlet
+# ListCAServlet
+# CheckRequest servlet
+# ProcessCertReq servlet
+# ProcessReq servlet
+# QueryReq servlet
+#######################################################
+CMS_GW_MISSING_KEYGEN_INFO=Missing or malformed KeyGen, PKCS #10 or CRMF request.
+CMS_GW_MISSING_CERTINFO=Missing CertInfo in AuthToken of authenticated enrollment request.
+CMS_GW_MISSING_CA_CERT=Missing CA Certificate.
+CMS_GW_MISSING_CA_ID=Missing CA DN Id.
+CMS_GW_MISSING_CERT_HEADER=Missing Certificate Header.
+CMS_GW_MISSING_CERT_FOOTER=Missing Certificate Footer.
+CMS_GW_MISSING_CRL_=Missing CRL.
+CMS_GW_MISSING_CRL_HEADER=Missing CRL Header.
+CMS_GW_MISSING_CRL_FOOTER=Missing CRL Footer.
+CMS_GW_MISSING_KEY_IN_KEYGENINFO=Missing or malformed key in KeyGenInfo.
+CMS_GW_MISSING_KEY_IN_P10=PKCS #10 request is missing subject public key info.
+CMS_GW_MISSING_SUBJECT_IN_P10=PKCS #10 request is missing a subject name.
+CMS_GW_SET_KEY_FROM_KEYGEN_FAILED=Error setting key into certificate info from KeyGen. Error {0}.
+CMS_GW_NOT_A_CA=Feature available only for CA
+CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED=Error setting key into certificate info from certificate based enrollment. Error {0}.
+CMS_GW_INVALID_CERT_TYPE=SSL client certificate presented for this cert-based enrollment is not a signing only cert.
+CMS_GW_ENCRYPTION_CERT_NOT_FOUND=Pairing encryption certificate for cert-based dual certificate enrollment was not found in DB
+CMS_GW_MISSING_SSL_CLIENT_CERT=Missing SSL Client Certificate for certificate based enrollment
+CMS_GW_INVALID_CERTAUTH_ENROLL_TYPE=Invalid certAuthEnrollType
+CMS_GW_MISSING_CERTAUTH_ENROLL_TYPE=Missing certAuthEnrollType
+CMS_GW_SET_SUBJECT_FROM_P10_FAILED=Error setting subject name from PKCS #10 into certificate info . Error {0}.
+CMS_GW_CMC_TO_CERTINFO_ERROR=An Error was encountered while filling the certificate with the contents of the CMC message.
+CMS_GW_CRMF_TO_CERTINFO_ERROR=An Error was encountered while filling the certificate with the contents of the CRMF message.
+CMS_GW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN=Missing subject name from authentication.
+CMS_GW_SET_KEY_FROM_P10_FAILED=Error setting key from PKCS #10 into certificate info . Error {0}.
+CMS_GW_DECODING_CRL_ERROR=Error encountered while decoding CRL.
+CMS_GW_DECODING_CERT_ERROR=Error encountered while decoding certificate.
+CMS_GW_OLD_CRL_ERROR=CRL sent is older than the current CRL.
+CMS_GW_DELTA_CRL_NOT_SUPPORTED=Delta CRLs are not supported.
+CMS_GW_ENCODING_ISSUED_CERT_ERROR=Error encountered while encoding a certificate.
+CMS_GW_RETURNING_RESULT_ERROR=I/O Error encountered while outputting results.
+CMS_GW_DISPLAY_TEMPLATE_ERROR=Error encountered while rendering a response.
+CMS_GW_SET_SUBJECT_NAME_ERROR=Cannot convert the subject name from a string to an X500 Name.
+CMS_GW_SET_VALIDITY_ERROR=An Error was encountered while setting the validity in a cert.
+CMS_GW_SET_EXTENSIONS_ERROR=An Error was encountered while setting the extensions in a cert.
+CMS_GW_MISSING_CERTS_RENEW_FROM_AUTHMGR=You have no certificates to be renewed or the certificates are malformed.
+CMS_GW_MISSING_SERIALNO_FOR_RENEW=Missing or malformed serial number of certificate to renew.
+CMS_GW_INVALID_CERT_FOR_RENEWAL=The certificate(s) selected to be renewed is not from this CA.
+CMS_GW_SETTING_RENEWAL_VALIDITY_ERROR=An error was encountered while setting the certificate validity.
+CMS_GW_MISSING_SUBJECT_FROM_FORM=Missing subject name from the form.
+CMS_GW_MISSING_CERTS_REVOKE_FROM_AUTHMGR=You have no certificates to be revoked or the certificates are malformed.
+CMS_GW_MISSING_CERTS_REVOKE_FROM_SSL=You did not select a certificate to revoke or the certificate you selected is malformed.
+CMS_GW_MISSING_SERIALNO_FOR_REVOKE=Missing or malformed serial number of certificate to revoke.
+CMS_GW_CERT_ALREADY_REVOKED=The certificate has already been revoked.
+CMS_GW_INVALID_CERT_FOR_REVOCATION=The certificate(s) selected to be revoked is not from this CA.
+CMS_GW_NO_OPTIONS_SELECTED=You must select an option from the form.
+CMS_GW_INVALID_OPTIONS_SELECTED=The option(s) you selected is invalid. This could indicate a flaw in the form you are using.
+CMS_GW_GETTING_CA_CERT_ERROR=An error was encountered while getting the CA chain.
+CMS_GW_CA_CHAIN_EMPTY=The CA chain is missing or could not be obtained from the remote Certificate Manager or Registration Manager. The remote server could be down.
+CMS_GW_ENCODING_CA_CHAIN_ERROR=An error was encountered while encoding the CA chain.
+CMS_GW_CA_CHAIN_NOT_AVAILABLE=The CA chain is missing or could not be obtained from the remote Certificate Manager or Registration Manager. The remote server could be down.
+CMS_GW_DISPLAYING_CACHAIN_ERROR=An I/O error was encountered while outputting the CA chain.
+CMS_GW_NO_CRL_SELECTED=You must specify the CRL issuing point.
+CMS_GW_CRL_NOT_FOUND=The CRL you selected for download was not found.
+CMS_GW_CRL_NOT_UPDATED=The CRL you selected for download has not been updated.
+CMS_GW_NOT_YET_IMPLEMENTED=The operation you requested has not yet been implemented.
+CMS_GW_DISPLAYING_CRLINFO_ERROR=An I/O error was encountered while outputting the CRL result.
+CMS_GW_REQUEST_ID_NOT_FOUND=Request ID {0} was not found in the request queue.
+CMS_GW_INVALID_SERIAL_NUMBER=Certificate Serial number is not set or invalid.
+CMS_GW_FORMING_PKCS7_ERROR=Error Forming PKCS #7
+CMS_GW_INVALID_REQUEST_ID=Invalid Request ID {0}.
+CMS_GW_CRL_NOT_YET_UPDATED=The Certificate Revocation List has not been updated.
+CMS_GW_DECODE_CRL_FAILED=Failed to DER decode the Certificate Revocation List.
+CMS_GW_CERT_SERIAL_NOT_FOUND=Certificate Serial Number {0} not found
+CMS_GW_NO_RECOVERY_TOKEN_FOUND=No Recovery Token Found for recovery reference number {0}.
+CMS_GW_INVALID_AGENT=Agent: {0} cannot retrieve PKCS #12 for recovery reference number {2}. Agent: {1} initialized the request.
+CMS_GW_INVALID_AGENT_ASYNC=Agent: {0} cannot retrieve PKCS #12 for recovery request id {2}. Agent: {1} initialized the request.
+CMS_GW_REDIRECTING_ADMINENROLL_ERROR=Error encountered while accessing the adminEnroll page.{0}
+CMS_GW_NO_PUB_MODULE=Publishing module is disabled.
+CMS_GW_CONVERT_DN_TO_X500NAME_ERROR=Cannot convert the subject name from a String to an X500 Name form. \nCheck to make sure valid characters are in the subject name. \nFor example, the email address should only have IA5String characters\nand the country should only have PrintableString characters and have 2 characters exactly.
+CMS_GW_ADDING_ADMIN_CERT_ERROR=An error was encountered while adding the administrator's certificate to its entry in the user group database. Error {0}
+CMS_GW_ADDING_ADMIN_ERROR=An error was encountered while adding the administrator to the Certificate Manager Agent Group - the Group does not exist.
+CMS_GW_MISSING_GRANT_UID=You must specify a user ID for the trusted manager or agent.
+CMS_GW_FIND_GROUP_ERROR=Could not grant privilege. Could not find group {0}.
+CMS_GW_ADDING_USER_ERROR=Could not grant privilege. Error adding user {0}.
+CMS_GW_ADDING_CERT_ERROR=Could not grant privilege. Error adding the certificate to user {0}.
+CMS_GW_ADDING_MEMBER=Could not grant privilege. Error adding user {0} to group {1}.
+CMS_GW_ADDING_MEMBER_1=Could not grant privilege. Error adding user {0} to group {1} or group {2}.
+CMS_GW_REQUEST_HAD_NO_CERTS=Request ID {0} had no certificates issued as a result.
+CMS_GW_REQUEST_NOT_COMPLETED=Request ID {0} was not completed.
+CMS_GW_REQUEST_HAD_ERROR=Request ID {0} resulted in an error. No certificates were issued.
+CMS_GW_REQUEST_NOT_ENROLLMENT=Request ID {0} is not a certificate enrollment request.
+CMS_GW_NO_REQUEST_ID_PROVIDED=A Request ID must be provided for this operation.
+CMS_GW_NO_PKIDATA=No PKIData in the CMC full enrollment request.
+CMS_GW_PKCS10_ERROR=Error processing PKCS #10 in CMC full enrollment request: {0}
+CMS_GW_NO_CMC_CONTENT=No PKCS #10 nor CRMF in the CMC full enrollment request.
+CMS_GW_CMC_ERROR=Unexpected error processing the CMC full enrollment request: {0}
+CMS_GW_UNAUTHORIZED_CREATE_GROUP=Unauthorized to create group: {0}
+CMS_GW_CRL_CACHE_IS_NOT_ENABLED=CRL cache is not enabled for {0} issuing point.
+CMS_GW_CRL_CACHE_IS_EMPTY=CRL cache for {0} issuing point is empty.
+#######################################################
+# Admin Servlets
+#
+# Servlets which display these messages
+#
+# ACLAdminServlet
+# AuthAdminServlet
+# CAAdminServlet
+# CMSAdminServlet
+# JobsAdminServlet
+# KRAAdminServlet
+# LogAdminServlet
+# OCSPAdminServlet
+# PolicyAdminServlet
+# ProfileAdminServlet
+# PublisherAdminServlet
+# RAAdminServlet
+# RegistryAdminServlet
+# UsrGrpAdminServlet
+#######################################################
+CMS_ADMIN_SRVLT_AUTHS_FAILED=Authentication failed
+CMS_ADMIN_SRVLT_AUTHZ_FAILED=You are not authorized to perform this operation.
+CMS_ADMIN_SRVLT_INVALID_OP_TYPE=Invalid OP_TYPE {0}
+CMS_ADMIN_SRVLT_INVALID_OP_SCOPE=Invalid OP_SCOPE
+CMS_ADMIN_SRVLT_INVALID_PROTOCOL=Invalid protocol: OP_TYPE must be specified
+CMS_ADMIN_SRVLT_INVALID_PATH=Invalid Content Template path
+CMS_ADMIN_SRVLT_NULL_RS_ID=Resource ID (RS_ID) can not be null
+CMS_ADMIN_SRVLT_RS_ID_BS=Resource ID (RS_ID) can not contain backslashes
+CMS_ADMIN_SRVLT_SPECIAL_ID=Not allowed to create this special user: {0}
+CMS_ADMIN_SRVLT_COMMIT_FAILED=Failed to save changes to the configuration file
+CMS_ADMIN_SRVLT_PERFORM_FAILED=Failed to perform
+#######################################################
+# Authentication
+#
+# Servlets which display these messages
+#
+# AuthAdminServlet
+# ProfileApproveServlet
+# ProfileProcessServlet
+# ProfileReviewServlet
+# ProfileSelectServlet
+# ProfileSubmitServlet
+#######################################################
+CMS_POP_VERIFICATION_ERROR=Proof-of-Possession Verification Failed
+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
+CMS_AUTHENTICATION_LDAP_UID_PIN_TEXT=This plugin authenticates the username and password provided by the user against an LDAP directory. It works with the Dir-Based Enrollment HTML form.
+CMS_AUTHENTICATION_LDAP_UID_NAME=LDAP UID & Password Authentication
+CMS_AUTHENTICATION_LDAP_UID_TEXT=This plugin authenticates the username and password provided by the user against an LDAP directory. It works with the Dir-Based Enrollment HTML form.
+CMS_AUTHENTICATION_CMS_SIGN_NAME=CMC Authentication
+CMS_AUTHENTICATION_CMS_SIGN_TEXT=This plugin does the authentication by checking the signature of the signed CMC request.
+CMS_AUTHENTICATION_LDAP_UID=LDAP User ID
+CMS_AUTHENTICATION_LDAP_PWD=LDAP User Password
+CMS_AUTHENTICATION_LDAP_PIN=LDAP Pin
+CMS_AUTHENTICATION_NULL_CREDENTIAL=Authentication credential for {0} is null.
+CMS_AUTHENTICATION_NO_CERT=No Client Certificate Found
+CMS_AUTHENTICATION_INVALID_CREDENTIAL=Invalid Credential.
+CMS_AUTHENTICATION_INTERNAL_ERROR=Authentication encountered an internal error. Detailed msg: {0}.
+CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND=Authentication {0} not found.
+CMS_AUTHENTICATION_FORM_SUBJECTDN_ERROR=Error formulating the Subject Name. See logs for more details.
+CMS_AUTHENTICATION_COMPONENT_SYNTAX=DN pattern syntax error: {0}.
+CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE=Invalid attribute error: {0}
+CMS_AUTHENTICATION_LDAPATTRIBUTES_NOT_FOUND=No LDAP attributes found.
+CMS_AUTHENTICATION_EMPTY_DN_FORMED=Empty DN formed in Authentication Manager {0}.
+CMS_AUTHENTICATION_DUP_MGR_PLUGIN_ID=Another Auth manager plugin ID already exists: {0}
+CMS_AUTHENTICATION_NULL_AUTHMGR_CLASSNAME=Authentication manager plugin classname is null
+CMS_AUTHENTICATION_AUTHMGR_PLUGIN_NOT_FOUND=Authentication manager plugin class not found
+CMS_AUTHENTICATION_ILL_CLASS=Auth manager plugin class is not an instance of IAuthManager
+CMS_AUTHENTICATION_ILL_MGR_INST_ID=An Authentication Instance with this ID already exists. Please choose a different ID.
+CMS_AUTHENTICATION_MISSING_PARAMS=Auth manager instance is missing implementation parameters
+CMS_AUTHENTICATION_LOAD_CLASS_FAIL=Could not load authentication manager class {0}
+CMS_AUTHENTICATION_MGR_IN_USE=An authentication manager of this implementation is still in use.
+CMS_AUTHENTICATION_MGR_IMPL_NOT_FOUND=Cannot modify the auth manager plugin. Cannot locate the Auth Manager Implementation.
+#######################################################
+# Authorization
+#
+# Servlets which display these messages
+# ProfileApproveServlet
+# ProfileListServlet
+# ProfileProcessServlet
+# ProfileReviewServlet
+# ProfileSelectServlet
+#
+#######################################################
+CMS_AUTHORIZATION_INTERNAL_ERROR=Authorization encountered an internal error. Detailed msg: {0}
+CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND=Authorization {0} not found
+CMS_AUTHORIZATION_AUTHZMGR_PLUGIN_NOT_FOUND=Authorization manager plugin name {0} not found
+CMS_AUTHORIZATION_UNKNOWN_PROTECTED_RESOURCE=Unknown protected resource specified: {0}
+CMS_AUTHORIZATION_UNKNOWN_OPERATION=Unknown operation specified: {0}
+CMS_AUTHORIZATION_AUTHZ_ACCESS_DENIED=Authorization failed on resource: {0}, operation: {1}
+CMS_AUTHORIZATION_LOAD_CLASS_FAIL=Could not load authorization manager class {0}
+#######################################################
+# CA
+#
+# Servlets which display these messages
+#
+# None
+#######################################################
+CMS_CA_ERROR_PUBLISH_CRL=Error publishing CRL {0}: {1}
+CMS_CA_FAILED_CONSTRUCTING_CRL=Failed constructing CRL : {0}
+CMS_CA_CRL_ISSUING_POINT_INIT_FAILED=Initialization of CRL issuing point {0} failed : {1}
+CMS_CA_SEND_KRA_REQUEST=Sending DRM request failed
+CMS_CA_SEND_CLA_REQUEST=Sending CLA request failed
+CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED=Signing Algorithm {0} is not supported for the CA signing token
+CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED_FOR_KEY=Algorithm {0} is not supported for the signing token and key
+CMS_CA_INIT_PUBLISH_MODULE_FAILED=Failed initializing the publishing module
+CMS_CA_CERT_ALREADY_REVOKED=Certificate Serial Number {0} is already revoked
+CMS_CA_MISSING_REQD_FIELDS_IN_CERTISSUE=Missing required fields in certificate info of certificate issuing request
+CMS_CA_UNRECOGNIZED_REQUEST_TYPE=Unrecogized request type {0}
+CMS_CA_ERROR_GETTING_FIELDS_IN_ISSUE=Error Getting certificate info fields in issuing request
+CMS_CA_CRL_ISSUEPT_NOT_FOUND=CRL Issuing Point {0} not found in CRL repository
+CMS_CA_CRL_ISSUEPT_NOGOOD=CRL in CRL Issuing Point {0} is malformed. Cannot instantiate CRL
+CMS_CA_CRL_ISSUEPT_EXT_NOGOOD=CRL in CRL Issuing Point {0} has malformed extensions. Cannot instantiate CRL
+CMS_CA_SET_ISSUER_FAILED=Request {0} was completed with errors.\nError setting certificate issuer name
+CMS_CA_SET_SERIALNO_FAILED=Request {0} was completed with errors.\nError setting certificate serial number
+CMS_CA_NOSERIALNO=Request {0} was completed with errors.\nCA has exausted all available serial numbers
+CMS_CA_SIGNING_CRL_FAILED=Failed signing CRL. Error {0}
+CMS_CA_SIGNING_CERT_FAILED=Failed signing certificate. Error {0}
+CMS_CA_MISSING_INFO_IN_ISSUEREQ=Missing certificate info in issuing request
+CMS_CA_MISSING_INFO_IN_REVREQ=Missing revocation info in revocation request
+CMS_CA_MISSING_INFO_IN_CLAREQ=Missing CLA certificate info in cert4crl request
+CMS_CA_MISSING_INFO_IN_RENEWREQ=Missing certificate info in renewal request
+CMS_CA_REVOKE_FAILED=One or more certificates could not be revoked
+CMS_CA_UNREVOKE_FAILED=One or more certificates could not be unrevoked
+CMS_CA_CERT4CRL_FAILED=One or more revoked certificates could not be recorded by the CLA
+CMS_CA_UNCERT4CRL_FAILED=One or more revoked certificates could not be removed by the CLA
+CMS_CA_RENEW_FAILED=One or more certificates could not be renewed
+CMS_CA_CANT_FIND_CERT_SERIAL=Cannot find certificate with serial number {0}
+CMS_CA_TOKEN_NOT_FOUND=Token {0} not found
+CMS_CA_CERT_OBJECT_NOT_FOUND=Certificate object not found
+CMS_CA_TOKEN_ERROR=Token Error
+CMS_CA_CRYPTO_NOT_INITIALIZED=Crypto Layer has not been initialized
+CMS_CA_INVALID_PASSWORD=Invalid Password
+CMS_CA_BUILD_CA_CHAIN_FAILED=Could not get or build CA chain. Error {0}
+CMS_CA_X509CERT_VERSION_NOT_SUPPORTED=Certificate Version in the configuration is not supported
+CMS_CA_CERT_BEGIN_AFTER_CA_VALIDITY=Certificate validity cannot begin past the CA certificate's validity
+CMS_CA_MISSING_SERIAL_NUMBER=Missing or invalid serial number
+CMS_CA_IS_NOT_ON_HOLD=Certificate {0} has to be on-hold to perform this operation
+CMS_CA_CANNOT_RENEW_REVOKED_CERT=Certificate serial number {0} to be renewed is revoked. Cannot renew a revoked certificate
+CMS_CA_ERROR_GETTING_RENEWED_CERT=Error getting renewed certificate {0} for certificate {1}
+#######################################################
+# KRA
+#
+# Servlets which display these messages
+#
+# None
+#######################################################
+CMS_KRA_PUBLIC_KEY_NOT_MATCHED=Public Key does not match
+CMS_KRA_INVALID_KEYRECORD=Invalid Key record
+CMS_KRA_INVALID_OWNER_NAME=Invalid Owner Name
+CMS_KRA_INVALID_PUBLIC_KEY=Invalid Public Key
+CMS_KRA_INVALID_PRIVATE_KEY=Invalid Private Key
+CMS_KRA_INVALID_STATE=Invalid State
+CMS_KRA_INVALID_M=Invalid M
+CMS_KRA_INVALID_N=Invalid N
+CMS_KRA_INVALID_PASSWORD=Invalid Password
+CMS_KRA_CREDENTIALS_EXIST=Credentials Exist
+CMS_KRA_CREDENTIALS_NOT_EXIST=Credentials Not Exist
+CMS_KRA_POA_DECODE_FAILED_1=Failed to decode Proof-of-Archival {0}
+CMS_KRA_POA_ENCODE_FAILED_1=Failed to encode Proof-of-Archival {0}
+CMS_KRA_INVALID_KRA_NAME=Invalid KRA Name
+CMS_KRA_RECOVERY_FAILED_1=Recovery Failed {0}
+CMS_KRA_PKCS12_FAILED_1=PKCS #12 Creation Failed {0}
+CMS_KRA_KEYID_FAILED_1=Key Identifier Creation Failed {0}
+CMS_KRA_KEYBAG_FAILED_1=Key Bag Creation Failed {0}
+#######################################################
+# DBS
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_DBS_INTERNAL_DIR_UNAVAILABLE=Internal database is unavailable
+CMS_DBS_CONNECT_LDAP_FAILED=Failed to connect LDAP server {0}
+CMS_DBS_SERIALIZE_FAILED=Failed to serialize attribute {0}
+CMS_DBS_DESERIALIZE_FAILED=Failed to de-serialize attribute {0}
+CMS_DBS_INVALID_ATTRS=Invalid attributes
+CMS_DBS_INVALID_CLASS_NAME=Invalid class name {0}
+CMS_DBS_INVALID_FILTER_ITEM=Invalid filter item {0}
+CMS_DBS_LDAP_OP_FAILURE=LDAP operation failure - {0}
+CMS_DBS_NO_MAPPER_FOUND=No mapper found for {0}
+CMS_DBS_INTERNAL_DIR_ERROR=Internal Database Error encountered: {0}
+CMS_DBS_ADD_ENTRY_FAILED=Failed to add the schema entry: {0}
+CMS_DBS_LIMIT_REACHED=All serial numbers are used. The max serial number is 0x{0}
+CMS_DBS_SETBACK_SERIAL=The serial number is already in use.\nYou can only set the serial number greater than 0x{0}
+CMS_DBS_SETBACK_MAXSERIAL=The serial number is already in use.\nYou can only set the end serial number greater than 0x{0}
+CMS_DBS_LDIF_FAILED=Failed to create ldif file: {0}
+CMS_DBS_COPY_LDIF_FAILED=Failed to copy ldif file: {0}
+CMS_DBS_RECORD_NOT_FOUND=Record not found
+#######################################################
+# Jobs
+#
+# Servlets which display these messages
+#
+# JobsAdminServlet
+#
+#######################################################
+CMS_JOB_LOAD_CLASS_FAILED=Could not load Job class {0} for the Jobs Scheduler
+CMS_JOB_PLUGIN_NOT_FOUND=Could not find plugin {0} for the Jobs Scheduler
+CMS_JOB_SRVLT_ILL_JOB_PLUGIN_ID=Another job plugin ID already exists {0}
+CMS_JOB_SRVLT_JOB_PLUGIN_NOT_FOUND=Job plugin {0} not found
+CMS_JOB_SRVLT_JOB_NOT_FOUND=Job {0} not found
+CMS_JOB_SRVLT_NULL_CLASS=Job plugin classname is null
+CMS_JOB_SRVLT_NO_CLASS=Job plugin class not found
+CMS_JOB_SRVLT_ILL_CLASS=Job plugin class is not an instance of IJob
+CMS_JOB_SRVLT_ILL_JOB_INST_ID=Job plugin ID already exists
+CMS_JOB_SRVLT_ADD_MISSING_PARAMS=Job instance is missing an implementation parameter
+CMS_JOB_SRVLT_MISSING_INST_PARAM_VAL=Job instance is missing a value for this parameter: {0}
+CMS_JOB_SRVLT_JOB_IN_USE=A job of this implementation is still in use
+#######################################################
+# Logging
+#
+# Servlets which display these messages
+#
+# LogAdminServlet
+#
+#######################################################
+CMS_LOG_INSTANCE_NOT_FOUND=Log instance not found named: {0)
+CMS_LOG_PLUGIN_NOT_FOUND=Log plugin not found named: {0}
+CMS_LOG_THREAD_INTERRUPT=Log {0} thread interrupted
+CMS_LOG_ROTATE_LOG_FAILED=Failed to rotate log \"{0}\", error: {1}
+CMS_LOG_WRITE_FAILED=Failed to write in file: \"{0}\", entry: {1}, error: {2}
+CMS_LOG_FLUSH_LOG_FAILED=Failed to flush log \"{0}\", error: {1}
+CMS_LOG_EXPIRE_LOG_FAILED=Can't expire log files, error:{0}
+CMS_LOG_EVENT_FAILED=Failed to log event \"{0}\", error: {1}
+CMS_LOG_LOGFILE_CLOSED=Attempt to log message \"{0}\" to closed log file {1}
+CMS_LOG_EXPIRATION_TIME_ZERO=Log expiration time must be greater than 0
+CMS_LOG_DIRECTORY_LIST_FAILED=Unable to list directory {0} with filter {1}
+CMS_LOG_NO_SUCH_ALGORITHM=Can't find MessageDigest algorithm for {0}. Tamper evident log disabled
+CMS_LOG_INVALID_FILE_NAME=Attempt to initialize log with an invalid filename: \"{0}\"
+CMS_LOG_UNEXPECTED_EXCEPTION=Caught unexpected exception: {0}
+CMS_LOG_ILLEGALARGUMENT=Illegal argument when opening: {0}
+CMS_LOG_CLOSE_FAILED=Failed to close file \"{0}\", error: {1}
+CMS_LOG_INVALID_LOG_TYPE=Attempt to initialize log with an invalid log type: \"{0}\"
+CMS_LOG_SRVLT_ILL_PLUGIN_ID=Another plugin ID already exists {0}
+CMS_LOG_SRVLT_NULL_CLASS=Plugin classname is null
+CMS_LOG_SRVLT_NO_CLASS=Plugin class not found
+CMS_LOG_SRVLT_ILL_CLASS=Plugin class is not an instance of {0}
+CMS_LOG_SRVLT_ILL_INST_ID=Plugin instance ID already exists
+CMS_LOG_SRVLT_ADD_MISSING_PARAMS=Instance is missing an implementation parameter
+CMS_LOG_SRVLT_IN_USE=An instance of this implementation is still in use
+CMS_LOG_LOAD_CLASS_FAIL=Failed to load class {0}
+#######################################################
+# Notification
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_NOTIFICATION_SMTP_SEND_FAILED=Failed to send mail to {0}
+CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED=Failed to resolve email for {0}
+CMS_NOTIFICATION_NO_SMTP_SENDER=Email sender not found
+CMS_NOTIFICATION_NO_SMTP_RECEIVER=Email receiver not found
+#######################################################
+# Extensions
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_EXTENSION_CLASS_NOT_FOUND=Class {0} was not found
+CMS_EXTENSION_INSTANTIATE_ERROR=Could not create an instance of {0}. Error {1}
+CMS_EXTENSION_INVALID_IMPL=Class {0} does not implement the ICMSTemplate interface
+CMS_EXTENSION_INCORRECT_IMPL=Class {0} must return non-null for the extension name and OID
+CMS_EXTENSION_CREATING_EXT_ERROR=Error creating a {0} extension
+#######################################################
+# Users and Groups
+#
+# Servlets which display these messages
+#
+# UsrGrpAdminServlet
+#
+#######################################################
+CMS_USRGRP_SRVLT_GROUP_NOT_EXIST=Group Not Found
+CMS_USRGRP_SRVLT_USER_NOT_EXIST=User Not Found
+CMS_USRGRP_SRVLT_CERT_ERROR=Certificate exception
+CMS_USRGRP_SRVLT_CERT_EXPIRED=Certificate expired
+CMS_USRGRP_SRVLT_CERT_NOT_YET_VALID=Certificate not yet valid
+CMS_USRGRP_SRVLT_CERT_O_ERROR=Certificate related error
+CMS_USRGRP_USER_ADD_FAILED=Failed to add user
+CMS_USRGRP_USER_ADD_FAILED_1=Failed to add user. Missing \"{0}\"
+CMS_USRGRP_USER_MOD_FAILED=Failed to modify user.
+CMS_USRGRP_USER_MOD_FAILED_1=Failed to modify user. Missing \"{0}\"
+CMS_USRGRP_SRVLT_USER_CERT_EXISTS=Failed to add cert: The certificate you tried to add already exists
+CMS_USRGRP_SRVLT_FAIL_USER_RMV=Failed to remove user
+CMS_USRGRP_SRVLT_FAIL_USER_RMV_G=The user you tryed to delete belongs to one or more groups.\nIf you click yes to continue, then the user will also be deleted\nfrom all the groups that it belongs to.
+CMS_USRGRP_GROUP_ADD_FAILED=Failed to add group
+CMS_USRGRP_GROUP_MODIFY_FAILED=Failed to modify group
+#######################################################
+# Password checker
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_PASSWORD_EMPTY_PASSWORD=The password is empty
+CMS_PASSWORD_INVALID_LEN=The password must be at least {0} characters
+CMS_PASSWORD_INVALID_LEN_1=The password must be at least {0} characters
+CMS_PASSWORD_NON_ALPHANUMERIC=The password contains non-alphanumeric characters
+CMS_PASSWORD_MISSING_NUMERIC_1=The password requires at least {0} numeric digit(s)
+CMS_PASSWORD_MISSING_UPPER_CASE_1=The password requires at least {0} upper case letter(s)
+CMS_PASSWORD_MISSING_LOWER_CASE_1=The password requires at least {0} lower case letter(s)
+#######################################################
+# Policy
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_POLICY_NO_SUBJECT_NAME=Policy Rule: {0} - Internal Error: No Subject Name Found
+CMS_POLICY_SUBJECT_NAME_EXIST=Policy Rule: {0} - Subject Name Exists
+CMS_POLICY_NO_CERT_INFO=Policy Rule: {0} - Internal Error: No Certificate info set on the request
+CMS_POLICY_NO_OLD_CERT=Policy Rule: {0} - Internal Error: The certificate(s) being renewed are not set on the request
+CMS_POLICY_LONG_RENEWAL_LEAD_TIME=Policy Rule: {0} - Certificate(s) can be renewed only within {1} days before expiry
+CMS_POLICY_MISMATCHED_CERTINFO=Policy Rule: {0} - Internal Error: The number of certificates input for renewal are incorrect
+CMS_POLICY_KEY_SIZE_VIOLATION=Policy Rule: {0} - Key Size Violation occurred: Actual: {1}, Constraints (Min: {2}, Max: {3})
+CMS_POLICY_KEY_SIZE_VIOLATION_1=Policy Rule: {0} - Key Size Violation occurred: Actual: {1}, Constraints (Min: {2}, Max: {3}, Increment: {4})
+CMS_POLICY_EXPONENT_VIOLATION=Policy Rule: {0} - The given exponent: {1} was not in the configured list: {2}
+CMS_POLICY_NO_KEY_PARAMS=Policy Rule: {0} - Could not parse key parameters in key number {1}
+CMS_POLICY_KEY_ALG_VIOLATION=Policy Rule: {0} - Key algorithm: {1} is not allowed by the policy
+CMS_POLICY_INVALID_BEGIN_TIME=Policy Rule: {0} - Begin time cannot be after current time
+CMS_POLICY_MORE_THAN_MAX_VALIDITY=Requested validity ({1} day(s)) is longer than the maximum allowed ({2} day(s)) in the {0} policy
+CMS_POLICY_LESS_THAN_MIN_VALIDITY=Requested validity ({1} day(s)) is shorter than the minimum allowed ({2} days) in the {0} policy
+CMS_POLICY_SIGNING_ALG_VIOLATION=Policy Rule: {0} - Signing algorithm: {1} is not allowed by the policy
+CMS_POLICY_EXISTING_CERT_DETAILS=Policy Rule: {0} - Your most recent certificate details are : {1}
+CMS_POLICY_UNEXPECTED_POLICY_ERROR=Policy Rule: {0} - Unexpected error: {1}
+CMS_POLICY_INVALID_ISSUER=Invalid Issuer DN
+CMS_POLICY_CLIENT_ISSUER_NOT_FOUND=Issuer of client certificate not found
+CMS_POLICY_INVALID_POLICY_CLASS=Policy rule: {0} - Invalid policy class: {1}
+CMS_POLICY_LOADING_POLICY_ERROR=Policy rule: {0} - Error loading policy class: {1}
+CMS_POLICY_UNSUPPORTED_KEY_ALG=Policy rule: {0} - Key algorithm: {1} is not supported
+CMS_POLICY_INVALID_CONFIG_PARAM=Policy rule: {0} - Invalid configuration value: {1} for parameter: {2}
+CMS_POLICY_MISSING_POLICY_CONFIG=Policy rule: {0} - Missing configuration info
+CMS_POLICY_INVALID_POLICY_CONFIG=Policy rule: {0} - Error in configuration: {1}
+CMS_POLICY_PARAM_CONFIG_ERROR=Policy rule: {0} - Unexpected error: {1} in configuring parameter: {2}
+CMS_POLICY_BAD_POLICY_EXPRESSION=Malformed Policy Expression: {0}
+CMS_POLICY_INVALID_ATTR_VALUE=Invalid value type: {0} for policy attribute
+CMS_POLICY_PERSISTENT_RULE_MISCONFIG=Persistent rule: {0} is configured with a different predicate: default: {1}, actual: {2}
+CMS_POLICY_MISSING_PERSISTENT_RULE=Persistent rule: {0} is missing in the configuration.
+CMS_POLICY_CANT_DELETE_PERSISTENT_POLICY=Persistent rule: {0} can't be deleted.
+CMS_POLICY_PERSISTENT_RULE_INACTIVE=Persistent rule: {0} should not be disabled.
+CMS_POLICY_NO_POLICY_CONFIG=No policy rule configuration for rule: {0}
+CMS_POLICY_NO_POLICY_IMPL=No policy implementation exists for: {0}
+CMS_POLICY_INVALID_POLICY_INSTANCE=No policy instance exists for: {0}
+CMS_POLICY_ACTIVE_POLICY_RULES_EXIST=Active policy rule instances exist for implementation: {0}
+CMS_POLICY_DELETING_POLICY_ERROR=Error deleting policy {0}: {1}
+CMS_POLICY_DUPLICATE_IMPL_ID=A Policy implementation with ID: {0} already exists
+CMS_POLICY_ADDING_POLICY_ERROR=Error adding policy {0}: {1}
+CMS_POLICY_INVALID_POLICY_IMPL=Invalid policy implementation: {0}. Policy class must implement one or more of IEnrollmentPolicy, IRenewalPolicy, IRevocationPolicy, IKeyRecoveryPolicy or IKeyArchivalPolicy
+CMS_POLICY_DUPLICATE_INST_ID=A Policy rule with ID: {0} already exists
+CMS_POLICY_ORDER_ERROR=Error changing policy ordering: {0}
+CMS_POLICY_IMPLCHANGE_ERROR=Can't change the implementation while modifying the policy instance: {0}
+CMS_POLICY_SYSTEM_POLICY_CONFIG_ERROR=System policy: {0} is not configurable
+CMS_POLICY_IMPL_NOT_FOUND=Policy implementation {0} configured for instance {1} was not found
+CMS_POLICY_INVALID_RENEWAL_INTERVAL=Policy Rule: {0} - Renewal interval: {1} days cannot be more than maximum validity: {2} days
+CMS_POLICY_INVALID_RENEWAL_MIN_MAX=Policy Rule: {0} - Renewal minimum validity: {1} days cannot be bigger than maximum validity: {2} days
+CMS_POLICY_MAXPATHLEN_TOO_BIG=In policy rule {0}, the subordinate CA basic constraints extension path length ({1}) cannot be greater than or equal to the maxPathLen configuration value ({2})
+CMS_POLICY_MAXPATHLEN_TOO_BIG_1=In policy rule {0}, the maxPathLen configuration value ({1}) cannot be greater than or equal to the maxPathLen of the CA certificate ({2})
+CMS_POLICY_INVALID_MAXPATHLEN=In policy rule {0}, the maxPathLen configuration value ({1}) must be 0 if the CA's basic constraints extension path length is 0
+CMS_POLICY_INVALID_MAXPATHLEN_1=In policy rule {0}, the maxPathLen configuration value ({1}) must be greater than or equal to 0 or left empty
+CMS_POLICY_PATHLEN_TOO_BIG=In policy rule {0}, the requested basic constraints extension path length ({1}) cannot be greater than the maximum path length allowed ({2})
+CMS_POLICY_BASIC_CONSTRAINTS_ERROR=In policy rule {0}, could not create a basic constraints extension for the certificate
+CMS_POLICY_INVALID_PATHLEN_FORMAT=In policy rule {0}, the requested basic constraints extension path length ({1}) must be an integer
+CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED=In policy rule {0}, no subordinate CA certificates are allowed since the CA's basic constraints path length is 0
+CMS_POLICY_MISSING_KEY=In policy rule {0}, missing public key in certificate request
+CMS_POLICY_SUBJECT_KEY_ID_ERROR=In policy rule {0}, failed to create subject key identifier extension for certificate request
+CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS=In policy rule {0}, one or more certificates to be renewed has expired. Cannot renew an expired certificate
+CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS_AFTER_ALLOWED_PERIOD=In policy rule {0}, one or more certificates to be renewed has been expired for more than {1} days. Cannot renew an expired certificate
+CMS_POLICY_CANNOT_REVOKE_EXPIRED_CERTS=In policy rule {0}, one or more certificates to be revoked has expired. Cannot revoke an expired certificate
+CMS_POLICY_PIN_UNAUTHORIZED=You are not authorized to make this transaction
+CMS_POLICY_CERTIFICATE_POLICIES_ERROR=In policy rule {0}, could not create a certificate policies extension for the certificate
+CMS_POLICY_UNKNOWN_SIGNING_ALG=In policy rule {0}, signing algorithm {1} is unknown to CS
+CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY_1=In policy rule {0}, signing algorithm {1} is unknown to CS.
+CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY=In policy rule {0}, allowed algorithms do not match the CA's private key. The parameters of this rule need to be updated in the CS.cfg.
+CMS_POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET=In policy rule {0}, no extension bits are set.
+CMS_POLICY_NO_ON_HOLD_ALLOWED=Policy Rule: {0} - On-Hold is not allowed.
+#######################################################
+# LDAP
+#
+# Servlets which display these messages
+#
+# PublisherAdminServlet
+#
+#######################################################
+CMS_LDAP_BAD_LDAP_EXPRESSION=Malformed publishing rule predicate expression: {0}
+CMS_LDAP_INTERNAL_ERROR=Publishing encountered an internal error. Detailed msg: {0}
+CMS_LDAP_COMPONENT_SYNTAX_ERROR=DN pattern syntax error: {0}
+CMS_LDAP_PUBLISH_FAILED=Failed to publish using rule: {0}
+CMS_LDAP_UNPUBLISH_FAILED=Failed to unpublish using rule: {0}
+CMS_LDAP_INVALID_ATTR_VALUE=Attribute: {0} is not supported in dnPattern
+CMS_LDAP_SRVLT_ILL_PLUGIN_ID=Another plugin ID already exists {0}
+CMS_LDAP_SRVLT_NULL_CLASS=Plugin classname is null
+CMS_LDAP_SRVLT_NO_CLASS=Plugin class not found
+CMS_LDAP_SRVLT_ILL_CLASS=Plugin class is not an instance of {0}
+CMS_LDAP_SRVLT_ILL_INST_ID=Plugin instance ID already exists {0}
+CMS_LDAP_SRVLT_ADD_MISSING_PARAMS=Instance missing implementation parameter
+CMS_LDAP_SRVLT_IN_USE=An instance of this implementation is still in use
+CMS_LDAP_INIT_LDAP_PUBLISH_MODULE_FAILED=Failed initializing LDAP publishing module
+CMS_LDAP_NO_LDAP_PUBLISH_CONFIG_FOUND=No LDAP Publishing configuration found
+CMS_LDAP_CONNECT_TO_LDAP_SERVER_FAILED=Could not connect to LDAP server host {0} port {1} Error {2}
+CMS_LDAP_UNKNOWN_ATTR_IN_DN_FILTER_COMPS=Unrecognized attribute {0} in DN or Filter comps
+CMS_LDAP_GET_ISSUER_FROM_CRL_FAILED=Cannot get Issuer name from Crl {0}
+CMS_LDAP_DECODING_CERT_FAILED=Could not parse a DER encoded certificate from the LDAP server. {0}
+CMS_LDAP_GET_DER_ENCODED_CERT_FAILED=Error getting DER encoding of certificate for {0}
+CMS_LDAP_GET_DER_ENCODED_CRL_FAILED=Error getting DER encoding of CRL. {0}
+CMS_LDAP_PUBLISH_CACERT_ERROR=Error publishing CA Certificate {0}
+CMS_LDAP_PUBLISH_CRL_ERROR=Error publishing CRL {0}
+CMS_LDAP_UNPUBLISH_CRL_ERROR=Error unpublishing CRL {0}
+CMS_LDAP_PUBLISH_USERCERT_ERROR=Error publishing User Certificate {0}
+CMS_LDAP_UNPUBLISH_USERCERT_ERROR=Error unpublishing User Certificate {0}
+CMS_LDAP_UNPUBLISH_CACERT_ERROR=Error unpublishing CA Certificate {0}
+CMS_LDAP_NO_MATCH_FOUND=Cannot find a match in the LDAP server for certificate. {0}
+CMS_LDAP_OTHER_LDAP_EXCEPTION=LDAPException caught from operation. {0}
+CMS_LDAP_NO_DN_MATCH=No DN matched for {0}
+CMS_LDAP_NO_DN_COMPS_AND_BASEDN=No base DN and no components to form DN for {0}
+CMS_LDAP_MORE_THAN_ONE_ENTRY=Certificate {0} mapped to more than one entry
+CMS_LDAP_CANNOT_RESET_CONNFAC=Cannot reset LDAP connection factory because some connections are still outstanding.
+CMS_LDAP_MAPPER_PLUGIN_NOT_FOUND=Mapper plugin not found named: {0}
+CMS_LDAP_PUBLISHER_PLUGIN_NOT_FOUND=Publisher plugin not found named: {0}
+CMS_LDAP_RULE_PLUGIN_NOT_FOUND=Rule plugin not found named: {0}
+CMS_LDAP_NO_RULE_INSTANCE=No Rule instance is found.
+CMS_LDAP_NO_RULE_MATCHED=No Rule instance is matched for request {0}.
+CMS_LDAP_CLASS_NOT_FOUND=Class not found for {0}
+CMS_LDAP_FAIL_LOAD_CLASS=Failed to load class {0}
+CMS_LDAP_INSTANTIATING_CLASS_FAILED=Cannot instantiate class {0}
+CMS_LDAP_INSUFFICIENT_CREDENTIALS=Insufficient credentials to instantiate class for {0}
+CMS_LDAP_NO_MATCH=certificate or CRL {0} did not map to an entry in the directory
+CMS_LDAP_FORM_DN_COMPS_FAILED=Failed to form DN components from the subject name
+CMS_LDAP_SERVER_UNAVAILABLE=LDAP server on host {0} port {1} is unavailable
+CMS_LDAP_UNKNOWN_RETURNED_CONN=Connection returned is not from this factory
+CMS_LDAP_BAD_RETURNED_CONN=Connection returned has already been returned
+CMS_LDAP_INVALID_NUMCONN_PARAMETERS=Invalid value for minConn or maxConn parameters. minConn and maxConn must be greater than 0 and minConn must be less than maxConn.
+CMS_LDAP_NO_REQUEST=No request associated with the cert. Can not get request {0} to form LDAP DN component {1}.
+CMS_LDAP_CREATE_CA_FAILED=Failed to create CA entry with DN: {0}. There may be entries in the directory hierarchy which do not exist. Please create them manually.
+CMS_LDAP_CREATE_ENTRY=Failed to create entry with DN: {0}. There may be entries in the directory hierarchy which do not exist. Please create them manually.
+CMS_LDAP_MAPPER_NOT_FOUND=Mapper not found {0}
+CMS_LDAP_PUBLISHER_NOT_FOUND=Publisher not found {0}
+CMS_LDAP_RULE_NOT_FOUND=Missing rule which links a publisher and mapper {0}
+#######################################################
+# OCSP Store Plugins
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_OCSP_DEFSTORE_PROP_NOT_FOUND_GOOD=Return GOOD if the requested serial number was not found.
+CMS_OCSP_DEFSTORE_PROP_BY_NAME=Use the OCSP authority subject name as the responder ID or not. If false, the OCSP authority signing signing key hash will be used.
+CMS_OCSP_DEFSTORE_PROP_INCLUDE_NEXT_UPDATE=Include the next update of the CRL in the OCSP response.
+CMS_OCSP_DEFSTORE_DESC=Default OCSP Store where revocation information is stored
+CMS_OCSP_LDAPSTORE_PROP_NOT_FOUND_GOOD=Return GOOD if the requested serial number was not found.
+CMS_OCSP_LDAPSTORE_PROP_BY_NAME=Use the OCSP authority subject name as the responder ID or not. If false, the OCSP authority signing signing key hash will be used.
+CMS_OCSP_LDAPSTORE_PROP_INCLUDE_NEXT_UPDATE=Include the next update of the CRL in the OCSP response.
+CMS_OCSP_LDAPSTORE_PROP_NUM_CONNS=The total number of LDAP connections.
+CMS_OCSP_LDAPSTORE_PROP_CRL_ATTR=CRL attribute name.
+CMS_OCSP_LDAPSTORE_PROP_CA_CERT_ATTR=CA Certificate attribute name.
+CMS_OCSP_LDAPSTORE_DESC=LDAP-based OCSP store. The OCSP server makes a validation decision based upon the CRL information on the LDAP server.
+#######################################################
+# Profile
+#
+# Servlets which display these messages
+#
+# ProfileAdminServlet
+# ProfileApproveServlet
+# ProfileProcessServlet
+# ProfileReviewServlet
+# ProfileSelectServlet
+# ProfileSubmitServlet
+#
+#######################################################
+CMS_PROFILE_DUPLICATE_KEY=Public key duplication detected
+CMS_PROFILE_ENCODING_ERROR=Error in BER encoding
+CMS_PROFILE_REVOKE_DUPKEY_CERT=Revoke certificate with duplicate key
+CMS_PROFILE_CONFIG_ALLOW_SAME_KEY_RENEWAL=Allow renewal of certification with same keys
+CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING=Allow duplicate subject names with different key usage for agent approved requests
+CMS_PROFILE_INTERNAL_ERROR=Profile internal error: {0}
+CMS_PROFILE_DENY_OPERATION=Not authorized to do this operation.
+CMS_PROFILE_DELETE_ENABLEPROFILE=Cannot delete enabled profile: {0}
+CMS_PROFILE_INVALID_REQUEST=Invalid Request
+CMS_PROFILE_EMPTY_REQUEST_TYPE=Request type is not specified. Check your profile input.
+CMS_PROFILE_CREATE_POLICY_FAILED=Failed to create profile policy: {0}
+CMS_PROFILE_CREATE_INPUT_FAILED=Failed to create profile input: {0}
+CMS_PROFILE_CREATE_OUTPUT_FAILED=Failed to create profile output: {0}
+CMS_PROFILE_EMPTY_KEY=Key is missing in the request. Check your profile policy.
+CMS_PROFILE_POINT_TYPE=Point Type
+CMS_PROFILE_POINT_NAME=Point Name
+CMS_PROFILE_REASONS=Reasons
+CMS_PROFILE_ISSUER_TYPE=Issuer Type
+CMS_PROFILE_ISSUER_NAME=Issuer Name
+CMS_PROFILE_PERMITTED_MIN_VAL=Permitted Min Value
+CMS_PROFILE_PERMITTED_MAX_VAL=Permitted Max Value
+CMS_PROFILE_PERMITTED_NAME_CHOICE=Permitted Name Choice
+CMS_PROFILE_PERMITTED_NAME_VAL=Permitted Name Value
+CMS_PROFILE_EXCLUDED_MIN_VAL=Excluded Min Value
+CMS_PROFILE_EXCLUDED_MAX_VAL=Excluded Max Value
+CMS_PROFILE_EXCLUDED_NAME_CHOICE=Excluded Name Choice
+CMS_PROFILE_EXCLUDED_NAME_VAL=Excluded Name Value
+CMS_PROFILE_ENABLE=Enable
+CMS_PROFILE_ISSUER_DOMAIN_POLICY=Issuer Domain Policy
+CMS_PROFILE_SUBJECT_DOMAIN_POLICY=Subject Domain Policy
+CMS_PROFILE_DOMAINS=Domains
+CMS_PROFILE_REQUIRED_EXPLICIT_POLICY=Required Explicit Policy
+CMS_PROFILE_INHIBIT_POLICY_MAPPING=Inhibit Policy Mapping
+CMS_PROFILE_PERMITTED_SUBTREES=Permitted Subtrees
+CMS_PROFILE_EXCLUDED_SUBTREES=Excluded Subtrees
+CMS_PROFILE_COMMENT=Comment
+CMS_PROFILE_DURATION=Duration
+CMS_PROFILE_VERSION=Version
+CMS_PROFILE_NUM_POLICIES=Number of Policies
+CMS_PROFILE_NUM_DIST_POINTS=Number of CRL Distribution Points
+CMS_PROFILE_NUM_EXCLUDED_SUBTREES=Number of Excluded Subtrees
+CMS_PROFILE_NUM_PERMITTED_SUBTREES=Number of Permitted Subtrees
+CMS_PROFILE_NUM_POLICY_MAPPINGS=Number of Policy Mappings
+CMS_PROFILE_NUM_GNS=Number of Subject Alt Name entities
+CMS_PROFILE_PROPERTY_ERROR=Property Error - {0}
+CMS_PROFILE_NUM_ATTRS=Number of Attributes
+CMS_PROFILE_ATTR_NAME=Attribute Name
+CMS_PROFILE_ATTR_VALUE=Attribute Value
+CMS_PROFILE_SUBJDIR_ATTRS=Subject Directory Attributes
+CMS_PROFILE_SUBJDIR_EMPTY_ATTRNAME=Attribute name should not be empty
+CMS_PROFILE_SUBJDIR_EMPTY_ATTRVAL=Attribute value should not be empty
+CMS_PROFILE_CRL_DISTRIBUTION_POINTS=CRL Distribution Points
+CMS_PROFILE_REJECTED=Request Rejected - {0}
+CMS_PROFILE_DEFERRED=Request Deferred - {0}
+CMS_PROFILE_KEY_ID=Key ID
+CMS_PROFILE_NOT_OWNER=Not Profile Owner
+CMS_PROFILE_NOT_FOUND=Profile {0} Not Found
+CMS_PROFILE_SIGNING_ALGORITHM=Signing Algorithm
+CMS_PROFILE_SIGNING_ALGORITHM_LIST=Signing Algorithm List
+CMS_PROFILE_ISSUER_ALT_NAME_TYPE=Name Type
+CMS_PROFILE_ISSUER_ALT_NAME_PATTERN=Name Pattern
+CMS_PROFILE_SUBJECT_ALT_NAME_TYPE=Name Type
+CMS_PROFILE_SUBJECT_ALT_NAME_PATTERN=Name Pattern
+CMS_PROFILE_SKIP_CERTS=Skip Certificates
+CMS_PROFILE_GN_ENABLE=Enable
+CMS_PROFILE_POLICY_ID_NOT_FOUND=Profile ID Not Found
+CMS_PROFILE_NUM_ADS=Number of Access Descriptors
+CMS_PROFILE_AD_METHOD=Access Method
+CMS_PROFILE_AD_LOCATIONTYPE=Location Type
+CMS_PROFILE_AD_LOCATION=Location
+CMS_PROFILE_AD_ENABLE=Enable
+CMS_PROFILE_AD_METHOD_0=Access Method (0)
+CMS_PROFILE_AD_LOCATIONTYPE_0=Location Type (0)
+CMS_PROFILE_AD_LOCATION_0=Location (0)
+CMS_PROFILE_AD_METHOD_1=Access Method (1)
+CMS_PROFILE_AD_LOCATIONTYPE_1=Location Type (1)
+CMS_PROFILE_AD_LOCATION_1=Location (1)
+CMS_PROFILE_AD_METHOD_2=Access Method (2)
+CMS_PROFILE_AD_LOCATIONTYPE_2=Location Type (2)
+CMS_PROFILE_AD_LOCATION_2=Location (2)
+CMS_PROFILE_CRITICAL=Criticality
+CMS_PROFILE_INVALID_GENERAL_NAME=Invalid General Name
+CMS_PROFILE_GENERAL_NAME_NOT_FOUND=General Name Not Found
+CMS_PROFILE_GENERAL_NAMES=General Names
+CMS_PROFILE_VALIDITY_CHECK_NOT_BEFORE=Check Not Before against current time
+CMS_PROFILE_VALIDITY_CHECK_NOT_AFTER=Check Not After against Not Before
+CMS_PROFILE_VALIDITY_NOT_BEFORE_GRACE_PERIOD=Grace period for Not Before being set in the future (in seconds).
+CMS_PROFILE_VALIDITY_RANGE=Validity Range (in days)
+CMS_PROFILE_VALIDITY_START_TIME=Relative Start Time (in seconds)
+CMS_PROFILE_BYPASS_CA_NOTAFTER=Bypass CA notAfter constraint
+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_AFTER_CURRENT=Not Before is later than current time
+CMS_PROFILE_NOT_AFTER_BEFORE_CURRENT=Not After is earlier than current time
+CMS_PROFILE_NOT_AFTER_BEFORE_NOT_BEFORE=Not After is earlier than Not Before
+CMS_PROFILE_TOKENKEY_LDAP_ENABLE=Enable/Disable ldap data feed
+CMS_PROFILE_TOKENKEY_LDAP_SEARCH_NAME=LDAP attribute name used for searching
+CMS_PROFILE_TOKENKEY_LDAP_STRING_ATTRS=LDAP String Attributes to be retrieved
+CMS_PROFILE_TOKENKEY_LDAP_MIN_CONN=LDAP Minimum Number Connections
+CMS_PROFILE_TOKENKEY_LDAP_MAX_CONN=LDAP Maximum Number Connections
+CMS_PROFILE_TOKENKEY_LDAP_HOST_NAME=Host Name
+CMS_PROFILE_TOKENKEY_LDAP_PORT_NUMBER=Port Number
+CMS_PROFILE_TOKENKEY_LDAP_VERSION=LDAP Version
+CMS_PROFILE_TOKENKEY_LDAP_BASEDN=BaseDN
+CMS_PROFILE_TOKENKEY_LDAP_SECURE_CONN=Secure Connection
+CMS_PROFILE_SUBJECT_NAME=Subject Name
+CMS_PROFILE_SUBJECT_NAME_PATTERN=Subject Name Pattern
+CMS_PROFILE_INVALID_SUBJECT_NAME=Invalid Subject Name {0}
+CMS_PROFILE_SUBJECT_NAME_NOT_FOUND=Subject Name Not Found
+CMS_PROFILE_SUBJECT_NAME_NOT_MATCHED=Subject Name Not Matched {0}
+CMS_PROFILE_SUBJECT_NAME_NOT_UNIQUE=Subject Name Not Unique {0}
+CMS_PROFILE_SIGNING_ALGORITHMS_ALLOWED=Allowed Signing Algorithms
+CMS_PROFILE_SIGNING_ALGORITHM_NOT_MATCHED=Signing Algorithm Not Matched {0}
+CMS_PROFILE_SIGNING_ALGORITHM_NOT_FOUND=Signing Algorithm Not Found
+CMS_PROFILE_OIDS=Comma-Separated list of Object Identifiers
+CMS_PROFILE_SSL_CLIENT=SSL Client
+CMS_PROFILE_SSL_SERVER=SSL Server
+CMS_PROFILE_EMAIL=Email
+CMS_PROFILE_OBJECT_SIGNING=Object Signing
+CMS_PROFILE_SSL_CA=SSL CA
+CMS_PROFILE_EMAIL_CA=Email CA
+CMS_PROFILE_OBJECT_SIGNING_CA=Object Signing CA
+CMS_PROFILE_SSL_CLIENT_NOT_MATCHED=SSL Client Not Matched {0}
+CMS_PROFILE_SSL_SERVER_NOT_MATCHED=SSL Server Not Matched {0}
+CMS_PROFILE_EMAIL_NOT_MATCHED=Email Not Matched {0}
+CMS_PROFILE_OBJECT_SIGNING_NOT_MATCHED=Object Signing Not Matched {0}
+CMS_PROFILE_SSL_CA_NOT_MATCHED=SSL CA Not Matched {0}
+CMS_PROFILE_EMAIL_CA_NOT_MATCHED=Email CA Not Matched {0}
+CMS_PROFILE_OBJECT_SIGNING_CA_NOT_MATCHED=Object Signing CA Not Matched {0}
+CMS_PROFILE_DIGITAL_SIGNATURE=Digital Signature
+CMS_PROFILE_NON_REPUDIATION=Non-Repudiation
+CMS_PROFILE_KEY_ENCIPHERMENT=Key Encipherment
+CMS_PROFILE_DATA_ENCIPHERMENT=Data Encipherment
+CMS_PROFILE_KEY_AGREEMENT=Key Agreement
+CMS_PROFILE_KEY_CERTSIGN=Key CertSign
+CMS_PROFILE_CRL_SIGN=CRL Sign
+CMS_PROFILE_ENCIPHER_ONLY=Encipher Only
+CMS_PROFILE_DECIPHER_ONLY=Decipher Only
+CMS_PROFILE_DIGITAL_SIGNATURE_NOT_MATCHED=Digital Signature Not Matched {0}
+CMS_PROFILE_NON_REPUDIATION_NOT_MATCHED=Non-Repudiation Not Matched {0}
+CMS_PROFILE_KEY_ENCIPHERMENT_NOT_MATCHED=Key Encipherment Not Matched {0}
+CMS_PROFILE_DATA_ENCIPHERMENT_NOT_MATCHED=Data Encipherment Not Matched {0}
+CMS_PROFILE_KEY_AGREEMENT_NOT_MATCHED=Key Agreement Not Matched {0}
+CMS_PROFILE_KEY_CERTSIGN_NOT_MATCHED=Key CertSign Not Matched {0}
+CMS_PROFILE_CRL_SIGN_NOT_MATCHED=CRL Sign Not Matched {0}
+CMS_PROFILE_ENCIPHER_ONLY_NOT_MATCHED=Encipher Only Not Matched {0}
+CMS_PROFILE_DECIPHER_ONLY_NOT_MATCHED=Decipher Only Not Matched {0}
+CMS_PROFILE_OID=Object Identifier
+CMS_PROFILE_EXT_VALUE=Extension Value
+CMS_PROFILE_KEY=Key
+CMS_PROFILE_KEY_LEN=Key Length
+CMS_PROFILE_KEY_TYPE=Key Type
+CMS_PROFILE_KEY_MIN_LEN=Min Key Length
+CMS_PROFILE_KEY_MAX_LEN=Max Key Length
+CMS_PROFILE_KEY_PARAMETERS=Key Lengths or Curves. For EC use comma separated list of curves, otherise use list of key sizes. Ex: 512,1024,2048,4096,8192 or: nistp256, sect163k1, nistk163 for EC.
+CMS_PROFILE_IS_CA=Is CA
+CMS_PROFILE_PATH_LEN=Path Length
+CMS_PROFILE_MIN_PATH_LEN=Min Path Length
+CMS_PROFILE_MAX_PATH_LEN=Max Path Length
+CMS_PROFILE_EXTENSION_NOT_FOUND=Extension {0} Not Found
+CMS_PROFILE_DUPLICATE_EXTENSION=Duplicate extension [ {0} ] found. Please contact the administrator in case of a misconfigured Certificate Profile
+CMS_PROFILE_VALIDITY_NOT_FOUND=Validity Not Found
+CMS_PROFILE_KEY_NOT_FOUND=Key Not Found
+CMS_PROFILE_NOT_BEFORE=Not Before
+CMS_PROFILE_NOT_AFTER=Not After
+CMS_PROFILE_NO_POLICY_SET_FOUND=Policy Set Not Found
+CMS_PROFILE_INVALID_NOT_BEFORE=Not Before Invalid
+CMS_PROFILE_INVALID_NOT_AFTER=Not After Invalid
+CMS_PROFILE_INVALID_KEY_TYPE=Invalid Key Type {0}
+CMS_PROFILE_KEY_TYPE_NOT_MATCHED=Key Type {0} Not Matched
+CMS_PROFILE_KEY_MIN_LEN_NOT_MATCHED=Key Min Length {0} Not Matched
+CMS_PROFILE_KEY_MAX_LEN_NOT_MATCHED=Key Max Length {0} Not Matched
+CMS_PROFILE_KEY_PARAMS_NOT_MATCHED=Key Parameters {0} Not Matched
+CMS_PROFILE_OID_NOT_MATCHED=OID {0} Not Matched
+CMS_PROFILE_CRITICAL_NOT_MATCHED=Criticality Not Matched
+CMS_PROFILE_CONSTRAINT_NO_CONSTRAINT=No Constraint
+CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_TEXT=This constraint accepts the Basic Constraint extension, if present, only when Criticality={0}, Is CA={1}, Min Path Length={2}, Max Path Length={3}
+CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_IS_CA=Is CA Not Matched
+CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_MIN_PATH=Min Path Length not matched
+CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_MAX_PATH=Max Path Length not matched
+CMS_PROFILE_CONSTRAINT_CA_VALIDITY_CONSTRAINT_TEXT=This constraint rejects the validity that is not between {0} (now) and {1} (Certificate Authority's notAfter)
+CMS_PROFILE_CONSTRAINT_EXTENDED_KEY_EXT_TEXT=This constraint accepts the Extended Key Usage extension, if present, only when Criticality={0}, OIDs={1}
+CMS_PROFILE_CONSTRAINT_EXTENSION_TEXT=This constraint accepts the extension only when Criticality={0}, OID={1}
+CMS_PROFILE_CONSTRAINT_KEY_TEXT=This constraint accepts the key only if Key Type={0}, Key Parameters ={1}
+CMS_PROFILE_CONSTRAINT_ALLOW_SAME_KEY_RENEWAL_TEXT = This constraint allows certificate requests with same keys when key uniqueness is enforced
+CMS_PROFILE_CONSTRAINT_KEY_USAGE_EXT_TEXT=This constraint accepts the Key Usage extension, if present, only when Criticality={0}, Digital Signature={1}, Non-Repudiation={2}, Key Encipherment={3}, Data Encipherment={4}, Key Agreement={5}, Key Certificate Sign={6}, Key CRL Sign={7}, Encipher Only={8}, Decipher Only={9}
+CMS_PROFILE_CONSTRAINT_NS_CERT_EXT_TEXT=This constraint accepts the NS Certificate Type extension, if present, only when Criticality={0}, SSL Client={1}, SSL Server={2}, Email={3}, Object Signing={4}, SSL CA={5}, Email CA={6}, Object Signing CA={7}
+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_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.
+CMS_PROFILE_DEF_AUTHTOKEN_SUBJECT_NAME=This default populates the authenticated name in the authentication token to the Certificate Subject Name of the request.
+CMS_PROFILE_DEF_AKI_EXT=This default populates an Authority Key Identifier Extension (2.5.29.35) to the request.
+CMS_PROFILE_DEF_SIA_OID=Invalid input parameter for method: {0}. The value should be in OID format, 1.3.6.1.5.5.7.48.1 for OCSP and 1.3.6.1.5.5.7.48.2 for CA Issuers
+CMS_PROFILE_DEF_AIA_OID=Invalid input parameter for method: {0}. The value should be in OID format, 1.3.6.1.5.5.7.48.1 for OCSP and 1.3.6.1.5.5.7.48.2 for CA Issuers
+CMS_PROFILE_DEF_BASIC_CONSTRAINTS_EXT=This default populates a Basic Constraints Extension (2.5.29.19) to the request. The default values are Criticality={0}, Is CA={1}, Path Length={2}
+CMS_PROFILE_DEF_FRESHEST_CRL_EXT=This default populates a Freshest CRL Extension (2.5.29.46) to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_CRL_DIST_POINTS_EXT=This default populates a CRL Distribution Points Extension (2.5.29.31) to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_SUBJECT_DIR_ATTR_EXT=This default populates a Subject Directory Attributes Extension () to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_EXTENDED_KEY_EXT=This default populates an Extended Key Usage Extension () to the request. The default values are Criticality={0}, OIDs={1}
+CMS_PROFILE_DEF_KEY_USAGE_EXT=This default populates a Key Usage Extension (2.5.29.15) to the request. The default values are Criticality={0}, Digital Signature={1}, Non-Repudiation={2}, Key Encipherment={3}, Data Encipherment={4}, Key Agreement={5}, Key Certificate Sign={6}, Key CRL Sign={7}, Encipher Only={8}, Decipher Only={9}
+CMS_PROFILE_DEF_PRIVATE_KEY_EXT=This default populates a Private Key Usage Period Extension (2.5.29.16) to the request. The default values are Criticality={0}, Start Time={1}, Duration={2}
+CMS_PROFILE_DEF_GENERIC_EXT=This default populates a Generic Extension to the request. The default values are Criticality={0}, OID={1}, Value={2}
+CMS_PROFILE_DEF_NS_COMMENT_EXT=This default populates a Netscape Comment Extension (2.16.840.1.113730.1.13) to the request. The default values are Criticality={0}, Comment={1}
+CMS_PROFILE_DEF_CERT_VERSION=This default populates a Certificate Version to the request. The default value is Version={0}
+CMS_PROFILE_DEF_NS_CERT_TYPE_EXT=This default populates a Netscape Certificate Type Extension (2.16.840.1.113730.1.1) to the request. The default values are Criticality={0}, SSL Client={1}, SSL Server={2}, Email={3}, Object Signing={4}, SSL CA={5}, Email CA={6}, Object Signing CA={7}
+CMS_PROFILE_DEF_NAME_CONSTRAINTS_EXT=This default populates a Name Constraints Extension (2.5.29.30) to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_NO_DEFAULT=No Default
+CMS_PROFILE_DEF_OCSP_NO_CHECK_EXT=This default populates an OCSP No Check Extension (1.3.6.1.5.5.7.48.1.5) to the request. The default values are Criticality={0}
+CMS_PROFILE_DEF_POLICY_CONSTRAINTS_EXT=This default populates a Policy Constraints Extension () to the request. The default values are Criticality={0}, Required Explicit Policy={1}, Inhibit Policy Mapping={2}
+CMS_PROFILE_DEF_CERTIFICATE_POLICIES_EXT=This default populates a Certificate Policies Extension to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_POLICY_MAPPINGS_EXT=This default populates a Policy Mappings Extension () to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_SIGNING_ALGORITHM=This default populates the Certificate Signing Algorithm. The default values are Algorithm={0}
+CMS_PROFILE_DEF_ISSUER_ALT_NAME_EXT=This default populates a Issuer Alternative Name Extension (2.5.29.18) to the request. The default values are Criticality={0}, Pattern={1}, Pattern Type={2}
+CMS_PROFILE_DEF_SUBJECT_ALT_NAME_EXT=This default populates a Subject Alternative Name Extension (2.5.29.17) to the request. The default values are Criticality={0}, {1}
+CMS_PROFILE_DEF_SUBJECT_KEY_ID_EXT=This default populates a Subject Key Identifier Extension (2.5.29.14) to the request.
+CMS_PROFILE_AUTO_ASSIGN=Agent UID
+CMS_PROFILE_DEF_AUTO_ASSIGN=This default assigns this request to Agent={0} automatically
+CMS_PROFILE_DEF_SUBJECT_NAME=This default populates a Certificate Subject Name to the request. The default values are Subject Name={0}
+CMS_PROFILE_DEF_INHIBIT_ANY_POLICY_EXT=This default populates an Inhibit Any-Policy Extension (2.25.29.54) to the request. The default values are Critically={0}, {1}
+CMS_PROFILE_INHIBIT_ANY_POLICY_WRONG_SKIP_CERTS=The value for skipped certificates must be an integer.
+CMS_PROFILE_DEF_USER_EXT=This default populates a User-Supplied Extension ({0}) to the request.
+CMS_PROFILE_DEF_USER_KEY=This default populates a User-Supplied Certificate Key to the request.
+CMS_PROFILE_DEF_USER_SIGNING_ALGORITHM=This default populates a User-Supplied Certificate Signing Algorithm to the request.
+CMS_PROFILE_DEF_USER_SUBJECT_NAME=This default populates a User-Supplied Certificate Subject Name to the request.
+CMS_PROFILE_DEF_USER_VALIDITY=This default populates a User-Supplied Certificate Validity to the request.
+CMS_PROFILE_DEF_VALIDITY=This default populates a Certificate Validity to the request. The default values are Range={0} in days
+CMS_PROFILE_CERTIFICATE_POLICIES_ID=Certificate Policies ID
+CMS_PROFILE_CERTIFICATE_POLICY_ENABLE=True if this certificate policy qualifier is enabled; false otherwise
+CMS_PROFILE_POLICY_ID=Policy ID
+CMS_PROFILE_POLICY_QUALIFIER_CPSURI_ENABLE=True if this certificate policy qualifier type is CPSuri; false otherwise
+CMS_PROFILE_POLICY_QUALIFIER_USERNOTICE_ENABLE=True if this certificate policy qualifier type is UserNotice; false otherwise
+CMS_PROFILE_POLICY_USERNOTICE_REF_ORG=Organization for notice reference
+CMS_PROFILE_POLICY_USERNOTICE_REF_NUMBERS=Notice numbers for notice reference
+CMS_PROFILE_POLICY_USERNOTICE_EXPLICIT_TEXT=Explicit Text for user notice
+CMS_PROFILE_POLICY_CPSURI=CPSUri
+CMS_PROFILE_POLICY_QUALIFIERS=Certificate Policy Qualifier
+CMS_PROFILE_POLICY_QUALIFIER_NUM=Number of Certificate Policy Qualifiers
+CMS_PROFILE_CERTIFICATE_POLICIES_POLICYID_ERROR=Wrong format policy ID: {0}
+CMS_PROFILE_CERTIFICATE_POLICIES_EMPTY_POLICYID=Empty certificate policies ID
+CMS_PROFILE_CERTIFICATE_POLICIES_EMPTY_CPSURI=Empty CPSuri
+#######################################################
+# Profile Inputs and outputs
+# The same servlets as last section display these messages
+#
+#######################################################
+CMS_PROFILE_REQUESTOR_NAME=Requestor Name
+CMS_PROFILE_REQUESTOR_EMAIL=Requestor Email
+CMS_PROFILE_REQUESTOR_PHONE=Requestor Phone
+CMS_PROFILE_SN_UID=UID
+CMS_PROFILE_SN_EMAIL=Email
+CMS_PROFILE_SN_CN=Common Name
+CMS_PROFILE_SN_OU=Organizational Unit
+CMS_PROFILE_SN_O=Organization
+CMS_PROFILE_SN_C=Country
+CMS_PROFILE_NO_CERT_REQ=Certificate Request Not Found
+CMS_PROFILE_UNKNOWN_SEQ_NUM=Unknown Sequence Number
+CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE=Unknown Certificate Request Type {0}
+CMS_PROFILE_FILE_NOT_FOUND=Cannot locate file
+CMS_PROFILE_INPUT_CERT_REQ_TYPE=Certificate Request Type
+CMS_PROFILE_INPUT_CERT_REQ=Certificate Request
+CMS_PROFILE_INPUT_KEYGEN_REQ=Key Generation Request
+CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE=Key Generation Request Type
+CMS_PROFILE_INPUT_FILE_SIGNING_NAME=File Signing Input
+CMS_PROFILE_INPUT_FILE_SIGNING_TEXT=File Signing Input
+CMS_PROFILE_INPUT_FILE_SIGNING_URL=URL Of File Being Signed
+CMS_PROFILE_INPUT_FILE_SIGNING_TEXT=Text Being Signed
+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
+CMS_PROFILE_INPUT_GENERIC_NAME_TEXT=Generic Input
+CMS_PROFILE_GI_PARAM_NAME=Parameter Name
+CMS_PROFILE_GI_SYNTAX=Syntax
+CMS_PROFILE_GI_DISPLAY_NAME=Display Name
+CMS_PROFILE_GI_ENABLE=Enable
+CMS_PROFILE_INPUT_SUBJECT_NAME_NAME=Subject Name
+CMS_PROFILE_INPUT_SUBJECT_NAME_TEXT=Subject Name
+CMS_PROFILE_INPUT_KEY_GEN_NAME=Key Generation
+CMS_PROFILE_INPUT_KEY_GEN_TEXT=Key Generation
+CMS_PROFILE_INPUT_DUAL_KEY_NAME=Dual Key Generation
+CMS_PROFILE_INPUT_DUAL_KEY_TEXT=Dual Key Generation
+CMS_PROFILE_UPDATER_SUBSYSTEM_NAME=Updater for Subsystem Group
+CMS_PROFILE_UPDATER_SUBSYSTEM_TEXT=Updater for Subsystem Group
+CMS_PROFILE_INPUT_CERT_REQ_NAME=Certificate Request Input
+CMS_PROFILE_INPUT_CERT_REQ_TEXT=Certificate Request Input
+CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_NAME=Token Key Certificate Request Input
+CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_TEXT=Token Key Certificate Request Input
+CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_UID=Token Key User ID
+CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_PK=Token Key User Public Key
+CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_TOKEN_CUID=Token Key CUID
+CMS_PROFILE_TOKENKEY_NO_TOKENCUID=Missing valid token CUID
+CMS_PROFILE_TOKENKEY_NO_ID=Token Key input ID not found
+CMS_PROFILE_TOKENKEY_NO_PUBLIC_KEY=Token Key input publickey not found
+CMS_PROFILE_OUTPUT_CERT_TOKENKEY_NAME=Token Key Certificate Output
+CMS_PROFILE_OUTPUT_CERT_TOKENKEY_TEXT=Token Key Certificate Output
+CMS_PROFILE_OUTPUT_CERT_NAME=Certificate Output
+CMS_PROFILE_OUTPUT_FINGER_PRINTS=Finger Prints
+CMS_PROFILE_OUTPUT_CERT_TEXT=Certificate Output
+CMS_PROFILE_OUTPUT_CERT_PP=Certificate Pretty Print
+CMS_PROFILE_OUTPUT_CERT_B64=Certificate Base-64 Encoded
+CMS_PROFILE_OUTPUT_CMMF_B64=CMMF Base-64 Encoded
+CMS_PROFILE_OUTPUT_PKCS7_B64=PKCS #7 Base-64 Encoded
+CMS_PROFILE_OUTPUT_DER_B64=DER Base 64 Encoded
+#######################################################
+# Self Tests
+#
+# Servlets which display these messages
+#
+# None
+#
+#######################################################
+CMS_SELFTESTS_SYSTEM_CERTS_VERIFICATION_DESCRIPTION=This self test is used to verify all system certificates
+CMS_SELFTESTS_CA_PRESENCE_DESCRIPTION=This self test is used to check whether or not the CA is present.
+CMS_SELFTESTS_CA_VALIDITY_DESCRIPTION=This self test is used to check whether or not the CA is valid.
+CMS_SELFTESTS_OCSP_PRESENCE_DESCRIPTION=This self test is used to check whether or not the OCSP is present.
+CMS_SELFTESTS_OCSP_VALIDITY_DESCRIPTION=This self test is used to check whether or not the OCSP is valid.
+CMS_SELFTESTS_RA_PRESENCE_DESCRIPTION=This self test is used to check whether or not the RA is present.
+CMS_SELFTESTS_KRA_PRESENCE_DESCRIPTION=This self test is used to check whether or not the KRA is present.
+CMS_SELFTESTS_TKS_PRESENCE_DESCRIPTION=This self test is used to check whether or not the TKS is present.
+#######################################################
+# ACL
+#
+# Servlets which display these messages
+#
+# ACLAdminServlet
+#
+#######################################################
+CMS_ACL_NULL_VALUE={0} value can not be null
+CMS_ACL_PARSING_ERROR=ACL parsing error for {0}: {1}
+CMS_ACL_CLASS_LOAD_FAIL=Failed to load class: {0}
+CMS_ACL_PERMISSION_DENIED=Permission denied
+CMS_ACL_NO_PERMISSION={0} does not have permission to {1}
+CMS_ACL_PARSING_ERROR_0=Failed to parse ACLs
+CMS_ACL_UPDATE_FAIL=Failed to update ACLs.
+CMS_ACL_METHOD_NOT_IMPLEMENTED=ACL method not implemented
+CMS_ACL_CONNECT_LDAP_FAIL=Failed to connect LDAP server: {0}
+CMS_ACL_RESOURCE_NOT_FOUND=ACLs resource not found
+CMS_ACL_ILL_CLASS=Class must extend IAccessEvaluator
+CMS_ACL_COMMIT_FAIL=Failed to save changes to the configuration file
+CMS_ACL_INST_CLASS_FAIL=Failed to instantiate class
+CMS_ACL_EVAL_NOT_FOUND=Evaluator not found
+#######################################################
+# User/group
+#
+# Servlets which display these messages
+#
+# UserGrpAdminServlet
+#
+#######################################################
+CMS_USRGRP_USER_NOT_FOUND=User not found
+CMS_USRGRP_ADD_USER_FAIL=Failed to add user
+CMS_USRGRP_ADD_USER_FAIL_NO_UID=Failed to add user: UID required
+CMS_USRGRP_MOD_USER_FAIL=Failed to modify user
+CMS_USRGRP_CERT_NOT_FOUND=Certificate not found
+CMS_USRGRP_REMOVE_USER_FAIL=Failed to remove user
+CMS_USRGRP_ADD_GROUP_FAIL=Failed to add group
+CMS_USRGRP_REMOVE_GROUP_FAIL=Failed to remove group
+CMS_USRGRP_ILL_GRP_MOD=Certificate Server administrators group must not be empty
+CMS_USRGRP_MOD_GROUP_FAIL=Failed to modify group
+CMS_USRGRP_USR_CERT_ERROR=User certificate related error
+#######################################################
+#
+# DBSubsystem
+#
+#######################################################
+CMS_DB_ADD_ATTRIBUTE_FAILED=Failed to add attribute.
+CMS_DB_ADD_OBJECTCLASS_FAILED=Failed to add objectclass.
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/ACL.java b/pki/base/common/src/com/netscape/certsrv/acls/ACL.java
new file mode 100644
index 000000000..38d8aee72
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/ACL.java
@@ -0,0 +1,184 @@
+// --- 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.certsrv.acls;
+
+
+import java.util.*;
+import java.lang.Object;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents an access control list (ACL). An ACL
+ * is associated with an protected resources. The policy
+ * enforcer can verify the ACLs with the current
+ * context to see if the corresponding resource is accessible.
+ * <P>
+ * An <code>ACL</code> may contain one or more <code>ACLEntry</code>.
+ * However, in case of multiple <code>ACLEntry</code>, a subject must
+ * pass ALL of the <code>ACLEntry</code> evaluation for permission
+ * to be granted
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class ACL implements IACL, java.io.Serializable {
+
+ protected Vector mEntries = new Vector(); // ACL entries
+ protected Vector mRights = null; // possible rights entries
+ protected String mResourceACLs = null; // exact resourceACLs string on ldap server
+ protected String mName = null; // resource name
+ protected String mDescription = null; // resource description
+
+ /**
+ * Class constructor.
+ */
+ public ACL() {
+ }
+
+ /**
+ * Class constructor.
+ * Constructs an access control list associated
+ * with a resource name
+ * @param name resource name
+ * @param rights applicable rights defined for this resource
+ * @param resourceACLs the entire ACL specification. For example:
+ * "certServer.log.configuration:read,modify:
+ * allow (read,modify)
+ * group=\"Administrators\":
+ * Allow administrators to read and modify log
+ * configuration"
+ */
+ public ACL(String name, Vector rights, String resourceACLs) {
+ setName(name);
+ if (rights != null) {
+ mRights = rights;
+ } else {
+ mRights = new Vector();
+ }
+ mResourceACLs = resourceACLs;
+
+ }
+
+ /**
+ * Sets the name of the resource governed by this
+ * access control.
+ * @param name name of the resource
+ */
+ public void setName(String name) {
+ mName = name;
+ }
+
+ /**
+ * Retrieves the name of the resource governed by
+ * this access control.
+ * @return name of the resource
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Retrieves the exact string of the resourceACLs
+ * @return resource's acl
+ */
+ public String getResourceACLs() {
+ return mResourceACLs;
+ }
+
+ /**
+ * Sets the description of the resource governed by this
+ * access control.
+ * @param description Description of the protected resource
+ */
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ /**
+ * Retrieves the description of the resource governed by
+ * this access control.
+ * @return Description of the protected resource
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Adds an ACL entry to this list.
+ * @param entry the <code>ACLEntry</code> to be added to this resource
+ */
+ public void addEntry(ACLEntry entry) {
+ mEntries.addElement(entry);
+ }
+
+ /**
+ * Returns ACL entries.
+ * @return enumeration for the <code>ACLEntry</code> vector
+ */
+ public Enumeration entries() {
+ return mEntries.elements();
+ }
+
+ /**
+ * Returns the string reprsentation.
+ * @return the string representation of the ACL entries in the
+ * following format:
+ * <resource name>[<ACLEntry1>,<ACLEntry 2>,...<ACLEntry N>]
+ */
+ public String toString() {
+ String entries = "";
+ Enumeration e = entries();
+
+ for (; e.hasMoreElements();) {
+ ACLEntry entry = (ACLEntry) e.nextElement();
+
+ entries += entry.toString();
+ if (e.hasMoreElements())
+ entries += ",";
+ }
+ return getName() + "[" + entries + "]";
+ }
+
+ /**
+ * Adds an rights entry to this list.
+ * @param right The right to be added for this ACL
+ */
+ public void addRight(String right) {
+ mRights.addElement(right);
+ }
+
+ /**
+ * Tells if the permission is one of the defined "rights"
+ * @param permission permission to be checked
+ * @return true if it's one of the "rights"; false otherwise
+ */
+ public boolean checkRight(String permission) {
+ return (mRights.contains((Object) permission));
+ }
+
+ /**
+ * Returns rights entries.
+ * @return enumeration of rights defined for this ACL
+ */
+ public Enumeration rights() {
+ return mRights.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/ACLEntry.java b/pki/base/common/src/com/netscape/certsrv/acls/ACLEntry.java
new file mode 100644
index 000000000..c58572400
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/ACLEntry.java
@@ -0,0 +1,228 @@
+// --- 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.certsrv.acls;
+
+
+import java.util.*;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.acls.*;
+
+
+/**
+ * A class represents an ACI entry of an access control list.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class ACLEntry implements IACLEntry, java.io.Serializable {
+
+ protected Hashtable mPerms = new Hashtable();
+ protected String mExpressions = null;
+ protected boolean mNegative = false;
+ protected String mACLEntryString = null;
+
+ /**
+ * Class Constructor
+ */
+ public ACLEntry() {
+ }
+
+ /**
+ * Checks if this ACL entry is set to negative.
+ * @return true if this ACL entry expression is for "deny";
+ * false if this ACL entry expression is for "allow"
+ */
+ public boolean isNegative() {
+ return mNegative;
+ }
+
+ /**
+ * Sets this ACL entry negative. This ACL entry expression is for "deny".
+ */
+ public void setNegative() {
+ mNegative = true;
+ }
+
+ /**
+ * Sets the ACL entry string
+ * @param s string in the following format:
+ * <PRE>
+ * allow|deny (right[,right...]) attribute_expression
+ * </PRE>
+ */
+ public void setACLEntryString(String s) {
+ mACLEntryString = s;
+ }
+
+ /**
+ * Gets the ACL Entry String
+ * @return ACL Entry string in the following format:
+ * <PRE>
+ * allow|deny (right[,right...]) attribute_expression
+ * </PRE>
+ */
+ public String getACLEntryString() {
+ return mACLEntryString;
+ }
+
+ /**
+ * Adds permission to this entry. Permission must be one of the
+ * "rights" defined for each protected resource in its ACL
+ * @param acl the acl instance that this aclEntry is associated with
+ * @param permission one of the "rights" defined for each
+ * protected resource in its ACL
+ */
+ public void addPermission(IACL acl, String permission) {
+ if (acl.checkRight(permission) == true) {
+ mPerms.put(permission, permission);
+ } else {
+ // not a valid right...log it later
+ }
+ }
+
+ /**
+ * Returns a list of permissions associated with
+ * this entry.
+ * @return a list of permissions for this ACL entry
+ */
+ public Enumeration permissions() {
+ return mPerms.elements();
+ }
+
+ /**
+ * Sets the expression associated with this entry.
+ * @param expressions the evaluator expressions. For example,
+ * group="Administrators"
+ */
+ public void setAttributeExpressions(String expressions) {
+ mExpressions = expressions;
+ }
+
+ /**
+ * Retrieves the expression associated with this entry.
+ * @return the evaluator expressions. For example,
+ * group="Administrators"
+ */
+ public String getAttributeExpressions() {
+ return mExpressions;
+ }
+
+ /**
+ * Checks to see if this <code>ACLEntry</code> contains a
+ * particular permission
+ * @param permission one of the "rights" defined for each
+ * protected resource in its ACL
+ * @return true if permission contained in the permission list
+ * for this <code>ACLEntry</code>; false otherwise.
+ */
+ public boolean containPermission(String permission) {
+ return (mPerms.get(permission) != null);
+ }
+
+ /**
+ * Checks if this entry has the given permission.
+ * @param permission one of the "rights" defined for each
+ * protected resource in its ACL
+ * @return true if the permission is allowed; false if the
+ * permission is denied. If a permission is not
+ * recognized by this ACL, it is considered denied
+ */
+ public boolean checkPermission(String permission) {
+ // default - if we dont know about the requested permission,
+ // don't grant permission
+ if (mPerms.get(permission) == null)
+ return false;
+ if (isNegative()) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Parse string in the following format:
+ * <PRE>
+ * allow|deny (right[,right...]) attribute_expression
+ * </PRE>
+ * into an instance of the <code>ACLEntry</code> class
+ * @param acl the acl instance associated with this aclentry
+ * @param aclEntryString aclEntryString in the specified format
+ * @return an instance of the <code>ACLEntry</code> class
+ */
+ public static ACLEntry parseACLEntry(IACL acl, String aclEntryString) {
+ if (aclEntryString == null) {
+ return null;
+ }
+
+ String te = aclEntryString.trim();
+
+ // locate first space
+ int i = te.indexOf(' ');
+ // prefix should be "allowed" or "deny"
+ String prefix = te.substring(0, i);
+ String suffix = te.substring(i + 1).trim();
+ ACLEntry entry = new ACLEntry();
+
+ if (prefix.equals("allow")) {
+ // do nothing
+ } else if (prefix.equals("deny")) {
+ entry.setNegative();
+ } else {
+ return null;
+ }
+ // locate the second space
+ i = suffix.indexOf(' ');
+ // this prefix should be rights list, delimited by ","
+ prefix = suffix.substring(1, i - 1);
+ // the suffix is the rest, which is the "expressions"
+ suffix = suffix.substring(i + 1).trim();
+
+ StringTokenizer st = new StringTokenizer(prefix, ",");
+
+ for (; st.hasMoreTokens();) {
+ entry.addPermission(acl, st.nextToken());
+ }
+ entry.setAttributeExpressions(suffix);
+ return entry;
+ }
+
+ /**
+ * Returns the string representation of this ACLEntry
+ * @return string representation of this ACLEntry
+ */
+ public String toString() {
+ String entry = "";
+
+ if (isNegative()) {
+ entry += "deny (";
+ } else {
+ entry += "allow (";
+ }
+ Enumeration e = permissions();
+
+ for (; e.hasMoreElements();) {
+ String p = (String) e.nextElement();
+
+ entry += p;
+ if (e.hasMoreElements())
+ entry += ",";
+ }
+ entry += ") " + getAttributeExpressions();
+ return entry;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/ACLsResources.java b/pki/base/common/src/com/netscape/certsrv/acls/ACLsResources.java
new file mode 100644
index 000000000..d193365ce
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/ACLsResources.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.acls;
+
+import java.util.*;
+
+/**
+ * A class represents a resource bundle for the entire ACL component.
+ * system.
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ACLsResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ * @return the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * A set of constants for localized error messages.
+ */
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/EACLsException.java b/pki/base/common/src/com/netscape/certsrv/acls/EACLsException.java
new file mode 100644
index 000000000..e982b1bb2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/EACLsException.java
@@ -0,0 +1,138 @@
+// --- 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.certsrv.acls;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents an acls exception. Note that this is
+ * an Runtime exception so that methods used AccessManager
+ * do not have to explicity declare this exception. This
+ * allows AccessManager to be easily integrated into any
+ * existing code.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EACLsException extends EBaseException {
+
+ /**
+ * resource class name
+ */
+ private static final String ACL_RESOURCES = ACLsResources.class.getName();
+
+ /**
+ * Constructs an acls exception.
+ * <P>
+ * @param msgFormat exception details
+ */
+ public EACLsException(String msgFormat) {
+ super(msgFormat);
+ mParams = null;
+ }
+
+ /**
+ * Constructs a base exception with a parameter. For example,
+ * <PRE>
+ * new EACLsException("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EACLsException(String msgFormat, String param) {
+ super(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a base exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * throw new EACLsException("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param param system exception
+ */
+ public EACLsException(String msgFormat, Exception param) {
+ super(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a base exception with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param params list of message format parameters
+ */
+ public EACLsException(String msgFormat, Object params[]) {
+ super(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns a list of parameters.
+ * <P>
+ *
+ * @return list of message format parameters
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * String representation for the corresponding exception.
+ * @return String representation for the corresponding exception.
+ */
+ public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns string representation for the corresponding exception.
+ * @param locale client specified locale for string representation.
+ * @return String representation for the corresponding exception.
+ */
+ public String toString(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ super.getMessage(), mParams);
+ }
+
+ /**
+ * Return the class name of the resource bundle.
+ * @return class name of the resource bundle.
+ */
+ protected String getBundleName() {
+ return ACL_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/IACL.java b/pki/base/common/src/com/netscape/certsrv/acls/IACL.java
new file mode 100644
index 000000000..9036a3652
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/IACL.java
@@ -0,0 +1,67 @@
+// --- 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.certsrv.acls;
+
+
+import java.util.*;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents an access control list (ACL). An ACL
+ * is associated with a protected resource. The policy
+ * enforcer can verify the ACLs with the current
+ * context to see if the corresponding resource is accessible.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IACL {
+
+ /**
+ * Returns the name of the current ACL.
+ * @return the name of the current ACL.
+ */
+ public String getName();
+
+ /**
+ * Returns the description of the current ACL.
+ * @return the description of the current ACL.
+ */
+ public String getDescription();
+
+ /**
+ * Returns a list of access rights of the current ACL.
+ * @return a list of access rights
+ */
+ public Enumeration rights();
+
+ /**
+ * Returns a list of entries of the current ACL.
+ * @return a list of entries
+ */
+ public Enumeration entries();
+
+ /**
+ * Verifies if permission is granted.
+ * @param permission one of the applicable rights
+ * @return true if the given permission is one of the applicable rights; false otherwise.
+ */
+ public boolean checkRight(String permission);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/acls/IACLEntry.java b/pki/base/common/src/com/netscape/certsrv/acls/IACLEntry.java
new file mode 100644
index 000000000..1646e22ff
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/acls/IACLEntry.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.acls;
+
+
+import java.util.*;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents an entry of access control list.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IACLEntry {
+
+ /**
+ * Returns the ACL entry string of the entry.
+ * @return the ACL entry string of the entry.
+ */
+ public String getACLEntryString();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/apps/CMS.java b/pki/base/common/src/com/netscape/certsrv/apps/CMS.java
new file mode 100644
index 000000000..376dce8b0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/apps/CMS.java
@@ -0,0 +1,1606 @@
+// --- 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.certsrv.apps;
+
+
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CRL;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.registry.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.tks.*;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import java.security.NoSuchAlgorithmException;
+import com.netscape.cmsutil.password.*;
+
+
+/**
+ * This represents the CMS server. Plugins can access other
+ * public objects such as subsystems via this inteface.
+ * This object also include a set of utility functions.
+ *
+ * This object does not include the actual implementation.
+ * It acts as a public interface for plugins, and the
+ * actual implementation is in the CMS engine
+ * (com.netscape.cmscore.apps.CMSEngine) that implements
+ * ICMSEngine interface.
+ *
+ * @version $Revision$, $Date$
+ */
+public final class CMS {
+
+ public static final int DEBUG_OBNOXIOUS = 10;
+ public static final int DEBUG_VERBOSE = 5;
+ public static final int DEBUG_INFORM = 1;
+
+ private static final String CONFIG_FILE = "CS.cfg";
+ private static ICMSEngine _engine = null;
+
+ public static final String SUBSYSTEM_LOG = ILogSubsystem.ID;
+ public static final String SUBSYSTEM_CRYPTO = ICryptoSubsystem.ID;
+ public static final String SUBSYSTEM_DBS = IDBSubsystem.SUB_ID;
+ public static final String SUBSYSTEM_CA = ICertificateAuthority.ID;
+ public static final String SUBSYSTEM_RA = IRegistrationAuthority.ID;
+ public static final String SUBSYSTEM_KRA = IKeyRecoveryAuthority.ID;
+ public static final String SUBSYSTEM_OCSP = IOCSPAuthority.ID;
+ public static final String SUBSYSTEM_TKS = ITKSAuthority.ID;
+ public static final String SUBSYSTEM_UG = IUGSubsystem.ID;
+ public static final String SUBSYSTEM_AUTH = IAuthSubsystem.ID;
+ public static final String SUBSYSTEM_AUTHZ = IAuthzSubsystem.ID;
+ public static final String SUBSYSTEM_REGISTRY = IPluginRegistry.ID;
+ public static final String SUBSYSTEM_PROFILE = IProfileSubsystem.ID;
+ public static final String SUBSYSTEM_JOBS = IJobsScheduler.ID;
+ public static final String SUBSYSTEM_SELFTESTS = ISelfTestSubsystem.ID;
+ public static final int PRE_OP_MODE = 0;
+ public static final int RUNNING_MODE = 1;
+
+ /**
+ * Private constructor.
+ *
+ * @param engine CMS engine implementation
+ */
+ private CMS(ICMSEngine engine) {
+ _engine = engine;
+ }
+
+ /**
+ * This method is used for unit tests. It allows the underlying _engine
+ * to be stubbed out.
+ * @param engine The stub engine to set, for testing.
+ */
+ public static void setCMSEngine(ICMSEngine engine) {
+ _engine = engine;
+ }
+
+ /**
+ * Gets this ID .
+ *
+ * @return CMS engine identifier
+ */
+ public static String getId() {
+ return _engine.getId();
+ }
+
+ /**
+ * Sets the identifier of this subsystem. Should never be called.
+ * Returns error.
+ *
+ * @param id CMS engine identifier
+ */
+ public static void setId(String id) throws EBaseException {
+ _engine.setId(id);
+ }
+
+ /**
+ * Initialize all static, dynamic and final static subsystems.
+ *
+ * @param owner null
+ * @param config main config store.
+ * @exception EBaseException if any error occur in subsystems during
+ * initialization.
+ */
+ public static void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ _engine.init(owner, config);
+ }
+
+ public static void reinit(String id) throws EBaseException {
+ _engine.reinit(id);
+ }
+
+ /**
+ * Starts up all subsystems. subsystems must be initialized.
+ *
+ * @exception EBaseException if any subsystem fails to startup.
+ */
+ public static void startup() throws EBaseException {
+ _engine.startup();
+ }
+
+ /**
+ * Blocks all new incoming requests.
+ */
+ public static void disableRequests() {
+ _engine.disableRequests();
+ }
+
+ /**
+ * Terminates all requests that are currently in process.
+ */
+ public static void terminateRequests() {
+ _engine.terminateRequests();
+ }
+
+ /**
+ * Checks to ensure that all new incoming requests have been blocked.
+ * This method is used for reentrancy protection.
+ * <P>
+ *
+ * @return true or false
+ */
+ public static boolean areRequestsDisabled() {
+ return _engine.areRequestsDisabled();
+ }
+
+ /**
+ * Shuts down subsystems in backwards order
+ * exceptions are ignored. process exists at end to force exit.
+ */
+ public static void shutdown() {
+ _engine.shutdown();
+ }
+
+ /**
+ * Shuts down subsystems in backwards order
+ * exceptions are ignored. process exists at end to force exit.
+ */
+
+ public static void forceShutdown() {
+
+ _engine.forceShutdown();
+ }
+
+ /**
+ * mode = 0 (pre-operational)
+ * mode = 1 (running)
+ */
+ public static void setCSState(int mode) {
+ _engine.setCSState(mode);
+ }
+
+ public static int getCSState() {
+ return _engine.getCSState();
+ }
+
+ public static boolean isPreOpMode() {
+ return _engine.isPreOpMode();
+ }
+
+ public static boolean isRunningMode() {
+ return _engine.isRunningMode();
+ }
+
+ /**
+ * Is the server in running state. After server startup, the
+ * server will be initialization state first. After the
+ * initialization state, the server will be in the running
+ * state.
+ *
+ * @return true if the server is in the running state
+ */
+ public static boolean isInRunningState() {
+ return _engine.isInRunningState();
+ }
+
+ /**
+ * Returns the logger of the current server. The logger can
+ * be used to log critical informational or critical error
+ * messages.
+ *
+ * @return logger
+ */
+ public static ILogger getLogger() {
+ return _engine.getLogger();
+ }
+
+ /**
+ * Returns the signed audit logger of the current server. This logger can
+ * be used to log critical informational or critical error
+ * messages.
+ *
+ * @return signed audit logger
+ */
+ public static ILogger getSignedAuditLogger() {
+ return _engine.getSignedAuditLogger();
+ }
+
+ /**
+ * Creates a repository record in the internal database.
+ *
+ * @return repository record
+ */
+ public static IRepositoryRecord createRepositoryRecord() {
+ return _engine.createRepositoryRecord();
+ }
+
+ /**
+ * Parse ACL resource attributes
+ * @param resACLs same format as the resourceACLs attribute:
+ * <PRE>
+ * <resource name>:<permission1,permission2,...permissionn>:
+ * <allow|deny> (<subset of the permission set>) <evaluator expression>
+ * </PRE>
+ * @exception EACLsException ACL related parsing errors for resACLs
+ * @return an ACL instance built from the parsed resACLs
+ */
+ public static IACL parseACL(String resACLs) throws EACLsException {
+ return _engine.parseACL(resACLs);
+ }
+
+ /**
+ * Creates an issuing poing record.
+ *
+ * @return issuing record
+ */
+ public static ICRLIssuingPointRecord createCRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return _engine.createCRLIssuingPointRecord(id, crlNumber, crlSize, thisUpdate, nextUpdate);
+ }
+
+ /**
+ * Retrieves the default CRL issuing point record name.
+ *
+ * @return CRL issuing point record name
+ */
+ public static String getCRLIssuingPointRecordName() {
+ return _engine.getCRLIssuingPointRecordName();
+ }
+
+ /**
+ * Retrieves the process id of this server.
+ *
+ * @return process id of the server
+ */
+ public static int getpid() {
+ return _engine.getpid();
+ }
+
+ /**
+ * Retrieves the instance roort path of this server.
+ *
+ * @return instance directory path name
+ */
+ public static String getInstanceDir() {
+ return _engine.getInstanceDir();
+ }
+
+ /**
+ * Returns a server wide system time. Plugins should call
+ * this method to retrieve system time.
+ *
+ * @return current time
+ */
+ public static Date getCurrentDate() {
+ if (_engine == null)
+ return new Date();
+ return _engine.getCurrentDate();
+ }
+
+ /**
+ * Puts data of an byte array into the debug file.
+ *
+ * @param data byte array to be recorded in the debug file
+ */
+ public static void debug(byte data[]) {
+ if (_engine != null)
+ _engine.debug(data);
+ }
+
+ /**
+ * Puts a message into the debug file.
+ *
+ * @param msg debugging message
+ */
+ public static void debug(String msg) {
+ if (_engine != null)
+ _engine.debug(msg);
+ }
+
+ /**
+ * Puts a message into the debug file.
+ *
+ * @param level 0-10 (0 is less detail, 10 is more detail)
+ * @param msg debugging message
+ */
+ public static void debug(int level, String msg) {
+ if (_engine != null)
+ _engine.debug(level, msg);
+ }
+
+ /**
+ * Puts an exception into the debug file.
+ *
+ * @param e exception
+ */
+ public static void debug(Throwable e) {
+ if (_engine != null)
+ _engine.debug(e);
+ }
+
+ /**
+ * Checks if the debug mode is on or not.
+ *
+ * @return true if debug mode is on
+ */
+ public static boolean debugOn() {
+ if (_engine != null)
+ return _engine.debugOn();
+ return false;
+ }
+
+ /**
+ * Puts the current stack trace in the debug file.
+ */
+ public static void debugStackTrace() {
+ if (_engine != null)
+ _engine.debugStackTrace();
+ }
+
+ /*
+ * If debugging for the particular realm is enabled, output name/value
+ * pair info to the debug file. This is useful to dump out what hidden
+ * config variables the server is looking at, or what HTTP variables it
+ * is expecting to find, or what database attributes it is looking for.
+ * @param type indicates what the source of key/val is. For example,
+ * this could be 'CS.cfg', or something else. In the debug
+ * subsystem, there is a mechanism to filter this so only the types
+ * you care about are listed
+ * @param key the 'key' of the hashtable which is being accessed.
+ * This could be the name of the config parameter, or the http param
+ * name.
+ * @param val the value of the parameter
+ * @param default the default value if the param is not found
+ */
+
+ public static void traceHashKey(String type, String key) {
+ if (_engine != null) {
+ _engine.traceHashKey(type, key);
+ }
+ }
+ public static void traceHashKey(String type, String key, String val) {
+ if (_engine != null) {
+ _engine.traceHashKey(type, key, val);
+ }
+ }
+ public static void traceHashKey(String type, String key, String val, String def) {
+ if (_engine != null) {
+ _engine.traceHashKey(type, key, val, def);
+ }
+ }
+
+
+ /**
+ * Returns the names of all the registered subsystems.
+ *
+ * @return a list of string-based subsystem names
+ */
+ public static Enumeration getSubsystemNames() {
+ return _engine.getSubsystemNames();
+ }
+
+ public static byte[] getPKCS7(Locale locale, IRequest req) {
+ return _engine.getPKCS7(locale, req);
+ }
+
+ /**
+ * Returns all the registered subsystems.
+ *
+ * @return a list of ISubsystem-based subsystems
+ */
+ public static Enumeration getSubsystems() {
+ return _engine.getSubsystems();
+ }
+
+ /**
+ * Retrieves the registered subsytem with the given name.
+ *
+ * @param name subsystem name
+ * @return subsystem of the given name
+ */
+ public static ISubsystem getSubsystem(String name) {
+ return _engine.getSubsystem(name);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param msgID message id defined in UserMessages.properties
+ * @return localized user message
+ */
+ public static String getUserMessage(String msgID) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(null /* from session context */, msgID);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @return localized user message
+ */
+ public static String getUserMessage(Locale locale, String msgID) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(locale, msgID);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(String msgID, String p1) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(null /* from session context */, msgID, p1);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(Locale locale, String msgID, String p1) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(locale, msgID, p1);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(String msgID, String p1, String p2) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(null /* from session context */, msgID, p1, p2);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(Locale locale, String msgID, String p1, String p2) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(locale, msgID, p1, p2);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(String msgID, String p1, String p2, String p3) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(null /* from session context */, msgID, p1, p2, p3);
+ }
+
+ public static LDAPConnection getBoundConnection(String host, int port,
+ int version, LDAPSSLSocketFactoryExt fac, String bindDN,
+ String bindPW) throws LDAPException
+ {
+ return _engine.getBoundConnection(host, port, version, fac,
+ bindDN, bindPW);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @return localized user message
+ */
+ public static String getUserMessage(Locale locale, String msgID, String p1, String p2, String p3) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(locale, msgID, p1, p2, p3);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param msgID message id defined in UserMessages.properties
+ * @param p an array of parameters
+ * @return localized user message
+ */
+ public static String getUserMessage(String msgID, String p[]) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(null /* from session context */, msgID, p);
+ }
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p an array of parameters
+ * @return localized user message
+ */
+ public static String getUserMessage(Locale locale, String msgID, String p[]) {
+ if (_engine == null)
+ return msgID;
+ return _engine.getUserMessage(locale, msgID, p);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID) {
+ return _engine.getLogMessage(msgID);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p an array of parameters
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p[]) {
+ return _engine.getLogMessage(msgID, p);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1) {
+ return _engine.getLogMessage(msgID, p1);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2) {
+ return _engine.getLogMessage(msgID, p1, p2);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3) {
+ return _engine.getLogMessage(msgID, p1, p2, p3);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4, p5);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4, p5, p6);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4, p5, p6, p7);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @param p8 8th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4, p5, p6, p7, p8);
+ }
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @param p8 8th parameter
+ * @param p9 9th parameter
+ * @return localized log message
+ */
+ public static String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+ return _engine.getLogMessage(msgID, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ }
+
+ /**
+ * Returns the main config store. It is a handle to CMS.cfg.
+ *
+ * @return configuration store
+ */
+ public static IConfigStore getConfigStore() {
+ return _engine.getConfigStore();
+ }
+
+ /**
+ * Retrieves time server started up.
+ *
+ * @return last startup time
+ */
+ public static long getStartupTime() {
+ return _engine.getStartupTime();
+ }
+
+ /**
+ * Retrieves the HTTP Connection for use with connector.
+ *
+ * @param authority remote authority
+ * @param factory socket factory
+ * @return http connection to the remote authority
+ */
+ public static IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory) {
+ return _engine.getHttpConnection(authority, factory);
+ }
+
+ /**
+ * Retrieves the HTTP Connection for use with connector.
+ *
+ * @param authority remote authority
+ * @param factory socket factory
+ * @param timeout return error if connection cannot be established within
+ * the timeout period
+ * @return http connection to the remote authority
+ */
+ public static IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory, int timeout) {
+ return _engine.getHttpConnection(authority, factory, timeout);
+ }
+
+ /**
+ * Retrieves the request sender for use with connector.
+ *
+ * @param authority local authority
+ * @param nickname nickname of the client certificate
+ * @param remote remote authority
+ * @param interval timeout interval
+ * @return resender
+ */
+ public static IResender getResender(IAuthority authority, String nickname,
+ IRemoteAuthority remote, int interval) {
+ return _engine.getResender(authority, nickname, remote, interval);
+ }
+
+ /**
+ * Retrieves the nickname of the server's server certificate.
+ *
+ * @return nickname of the server certificate
+ */
+ public static String getServerCertNickname() {
+ return _engine.getServerCertNickname();
+ }
+
+ /**
+ * Sets the nickname of the server's server certificate.
+ *
+ * @param tokenName name of token where the certificate is located
+ * @param nickName name of server certificate
+ */
+ public static void setServerCertNickname(String tokenName, String nickName) {
+ _engine.setServerCertNickname(tokenName, nickName);
+ }
+
+ /**
+ * Sets the nickname of the server's server certificate.
+ *
+ * @param newName new nickname of server certificate
+ */
+ public static void setServerCertNickname(String newName) {
+ _engine.setServerCertNickname(newName);
+ }
+
+ /**
+ * Retrieves the host name of the server's secure end entity service.
+ *
+ * @return host name of end-entity service
+ */
+ public static String getEEHost() {
+ return _engine.getEEHost();
+ }
+
+ /**
+ * Retrieves the host name of the server's non-secure end entity service.
+ *
+ * @return host name of end-entity non-secure service
+ */
+ public static String getEENonSSLHost() {
+ return _engine.getEENonSSLHost();
+ }
+
+ /**
+ * Retrieves the IP address of the server's non-secure end entity service.
+ *
+ * @return ip address of end-entity non-secure service
+ */
+ public static String getEENonSSLIP() {
+ return _engine.getEENonSSLIP();
+ }
+
+ /**
+ * Retrieves the port number of the server's non-secure end entity service.
+ *
+ * @return port of end-entity non-secure service
+ */
+ public static String getEENonSSLPort() {
+ return _engine.getEENonSSLPort();
+ }
+
+ /**
+ * Retrieves the host name of the server's secure end entity service.
+ *
+ * @return port of end-entity secure service
+ */
+ public static String getEESSLHost() {
+ return _engine.getEESSLHost();
+ }
+
+ /**
+ * Retrieves the host name of the server's secure end entity service.
+ *
+ * @return port of end-entity secure service
+ */
+ public static String getEEClientAuthSSLPort() {
+ return _engine.getEEClientAuthSSLPort();
+ }
+
+ /**
+ * Retrieves the IP address of the server's secure end entity service.
+ *
+ * @return ip address of end-entity secure service
+ */
+ public static String getEESSLIP() {
+ return _engine.getEESSLIP();
+ }
+
+ /**
+ * Retrieves the port number of the server's secure end entity service.
+ *
+ * @return port of end-entity secure service
+ */
+ public static String getEESSLPort() {
+ return _engine.getEESSLPort();
+ }
+
+ /**
+ * Retrieves the host name of the server's agent service.
+ *
+ * @return host name of agent service
+ */
+ public static String getAgentHost() {
+ return _engine.getAgentHost();
+ }
+
+ /**
+ * Retrieves the IP address of the server's agent service.
+ *
+ * @return ip address of agent service
+ */
+ public static String getAgentIP() {
+ return _engine.getAgentIP();
+ }
+
+ /**
+ * Retrieves the port number of the server's agent service.
+ *
+ * @return port of agent service
+ */
+ public static String getAgentPort() {
+ return _engine.getAgentPort();
+ }
+
+ /**
+ * Retrieves the host name of the server's administration service.
+ *
+ * @return host name of administration service
+ */
+ public static String getAdminHost() {
+ return _engine.getAdminHost();
+ }
+
+ /**
+ * Retrieves the IP address of the server's administration service.
+ *
+ * @return ip address of administration service
+ */
+ public static String getAdminIP() {
+ return _engine.getAdminIP();
+ }
+
+ /**
+ * Retrieves the port number of the server's administration service.
+ *
+ * @return port of administration service
+ */
+ public static String getAdminPort() {
+ return _engine.getAdminPort();
+ }
+
+ /**
+ * Creates a general name constraints.
+ *
+ * @param generalNameChoice type of general name
+ * @param value general name string
+ * @return general name object
+ * @exception EBaseException failed to create general name constraint
+ */
+ public static GeneralName form_GeneralNameAsConstraints(String generalNameChoice, String value) throws EBaseException {
+ return _engine.form_GeneralName(generalNameChoice, value);
+ }
+
+ /**
+ * Creates a general name.
+ *
+ * @param generalNameChoice type of general name
+ * @param value general name string
+ * @return general name object
+ * @exception EBaseException failed to create general name
+ */
+ public static GeneralName form_GeneralName(String generalNameChoice,
+ String value) throws EBaseException {
+ return _engine.form_GeneralName(generalNameChoice, value);
+ }
+
+ /**
+ * Get default parameters for subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param params configuration parameters
+ */
+ public static void getSubjAltNameConfigDefaultParams(String name,
+ Vector params) {
+ _engine.getSubjAltNameConfigDefaultParams(name, params);
+ }
+
+ /**
+ * Get extended plugin info for subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param params configuration parameters
+ */
+ public static void getSubjAltNameConfigExtendedPluginInfo(String name,
+ Vector params) {
+ _engine.getSubjAltNameConfigExtendedPluginInfo(name, params);
+ }
+
+ /**
+ * Creates subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static ISubjAltNameConfig createSubjAltNameConfig(String name, IConfigStore config, boolean isValueConfigured) throws EBaseException {
+ return _engine.createSubjAltNameConfig(
+ name, config, isValueConfigured);
+ }
+
+ /**
+ * Retrieves default general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param params configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static void getGeneralNameConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params) {
+ _engine.getGeneralNameConfigDefaultParams(name,
+ isValueConfigured, params);
+ }
+
+ /**
+ * Retrieves default general names configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param params configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static void getGeneralNamesConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params) {
+ _engine.getGeneralNamesConfigDefaultParams(name,
+ isValueConfigured, params);
+ }
+
+ /**
+ * Retrieves extended plugin info for general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param info configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static void getGeneralNameConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info) {
+ _engine.getGeneralNameConfigExtendedPluginInfo(name,
+ isValueConfigured, info);
+ }
+
+ /**
+ * Retrieves extended plugin info for general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param info configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static void getGeneralNamesConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info) {
+ _engine.getGeneralNamesConfigExtendedPluginInfo(name,
+ isValueConfigured, info);
+ }
+
+ /**
+ * Created general names configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static IGeneralNamesConfig createGeneralNamesConfig(String name,
+ IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return _engine.createGeneralNamesConfig(name, config, isValueConfigured,
+ isPolicyEnabled);
+ }
+
+ /**
+ * Created general name constraints configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static IGeneralNameAsConstraintsConfig createGeneralNameAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return _engine.createGeneralNameAsConstraintsConfig(
+ name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ /**
+ * Created general name constraints configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public static IGeneralNamesAsConstraintsConfig createGeneralNamesAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return _engine.createGeneralNamesAsConstraintsConfig(
+ name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ /**
+ * Returns the finger print of the given certificate.
+ *
+ * @param cert certificate
+ * @return finger print of certificate
+ */
+ public static String getFingerPrint(Certificate cert)
+ throws CertificateEncodingException, NoSuchAlgorithmException {
+ return _engine.getFingerPrint(cert);
+ }
+
+ /**
+ * Returns the finger print of the given certificate.
+ *
+ * @param certDer DER byte array of the certificate
+ * @return finger print of certificate
+ */
+ public static String getFingerPrints(byte[] certDer)
+ throws NoSuchAlgorithmException {
+ return _engine.getFingerPrints(certDer);
+ }
+
+ /**
+ * Returns the finger print of the given certificate.
+ *
+ * @param cert certificate
+ * @return finger print of certificate
+ */
+ public static String getFingerPrints(Certificate cert)
+ throws NoSuchAlgorithmException, CertificateEncodingException {
+ return _engine.getFingerPrints(cert);
+ }
+
+ /**
+ * Creates a HTTP PKI Message that can be sent to a remote
+ * authority.
+ *
+ * @return a new PKI Message for remote authority
+ */
+ public static IPKIMessage getHttpPKIMessage() {
+ return _engine.getHttpPKIMessage();
+ }
+
+ /**
+ * Creates a request encoder. A request cannot be sent to
+ * the remote authority in its regular format.
+ *
+ * @return a request encoder
+ */
+ public static IRequestEncoder getHttpRequestEncoder() {
+ return _engine.getHttpRequestEncoder();
+ }
+
+ /**
+ * Converts a BER-encoded byte array into a MIME-64 encoded string.
+ *
+ * @param data data in byte array format
+ * @return base-64 encoding for the data
+ */
+ public static String BtoA(byte data[]) {
+ return _engine.BtoA(data);
+ }
+
+ /**
+ * Converts a MIME-64 encoded string into a BER-encoded byte array.
+ *
+ * @param data base-64 encoding for the data
+ * @return data data in byte array format
+ */
+ public static byte[] AtoB(String data) {
+ return _engine.AtoB(data);
+ }
+
+ /**
+ * Retrieves the ldap connection information from the configuration
+ * store.
+ *
+ * @param config configuration parameters of ldap connection
+ * @return a LDAP connection info
+ */
+ public static ILdapConnInfo getLdapConnInfo(IConfigStore config)
+ throws EBaseException, ELdapException {
+ return _engine.getLdapConnInfo(config);
+ }
+
+ /**
+ * Creates a LDAP SSL socket with the given nickname. The
+ * certificate associated with the nickname will be used
+ * for client authentication.
+ *
+ * @param certNickname nickname of client certificate
+ * @return LDAP SSL socket factory
+ */
+ public static LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory(
+ String certNickname) {
+ return _engine.getLdapJssSSLSocketFactory(certNickname);
+ }
+
+ /**
+ * Creates a LDAP SSL socket.
+ *
+ * @return LDAP SSL socket factory
+ */
+ public static LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory() {
+ return _engine.getLdapJssSSLSocketFactory();
+ }
+
+ /**
+ * Creates a LDAP Auth Info object.
+ *
+ * @return LDAP authentication info
+ */
+ public static ILdapAuthInfo getLdapAuthInfo() {
+ return _engine.getLdapAuthInfo();
+ }
+
+ /**
+ * Retrieves the LDAP connection factory.
+ *
+ * @return bound LDAP connection pool
+ */
+ public static ILdapConnFactory getLdapBoundConnFactory()
+ throws ELdapException {
+ return _engine.getLdapBoundConnFactory();
+ }
+
+ /**
+ * Retrieves the LDAP connection factory.
+ *
+ * @return anonymous LDAP connection pool
+ */
+ public static ILdapConnFactory getLdapAnonConnFactory()
+ throws ELdapException {
+ return _engine.getLdapAnonConnFactory();
+ }
+
+ /**
+ * Retrieves the default X.509 certificate template.
+ *
+ * @return default certificate template
+ */
+ public static X509CertInfo getDefaultX509CertInfo() {
+ return _engine.getDefaultX509CertInfo();
+ }
+
+ /**
+ * Retrieves the certifcate in MIME-64 encoded format
+ * with header and footer.
+ *
+ * @param cert certificate
+ * @return base-64 format certificate
+ */
+ public static String getEncodedCert(X509Certificate cert) {
+ return _engine.getEncodedCert(cert);
+ }
+
+ /**
+ * Verifies all system certs
+ * with tags defined in <subsystemtype>.cert.list
+ */
+ public static boolean verifySystemCerts() {
+ return _engine.verifySystemCerts();
+ }
+
+ /**
+ * Verify a system cert by tag name
+ * with tags defined in <subsystemtype>.cert.list
+ */
+ public static boolean verifySystemCertByTag(String tag) {
+ return _engine.verifySystemCertByTag(tag);
+ }
+
+ /**
+ * Verify a system cert by certificate nickname
+ */
+ public static boolean verifySystemCertByNickname(String nickname, String certificateUsage) {
+ return _engine.verifySystemCertByNickname(nickname, certificateUsage);
+ }
+
+ /**
+ * get the CertificateUsage as defined in JSS CryptoManager
+ */
+ public static CertificateUsage getCertificateUsage(String certusage) {
+ return _engine.getCertificateUsage(certusage);
+ }
+
+ /**
+ * Checks if the given certificate is a signing certificate.
+ *
+ * @param cert certificate
+ * @return true if the given certificate is a signing certificate
+ */
+ public static boolean isSigningCert(X509Certificate cert) {
+ return _engine.isSigningCert(cert);
+ }
+
+ /**
+ * Checks if the given certificate is an encryption certificate.
+ *
+ * @param cert certificate
+ * @return true if the given certificate is an encryption certificate
+ */
+ public static boolean isEncryptionCert(X509Certificate cert) {
+ return _engine.isEncryptionCert(cert);
+ }
+
+ /**
+ * Retrieves the email form processor.
+ *
+ * @return email form processor
+ */
+ public static IEmailFormProcessor getEmailFormProcessor() {
+ return _engine.getEmailFormProcessor();
+ }
+
+ /**
+ * Retrieves the email form template.
+ *
+ * @return email template
+ */
+ public static IEmailTemplate getEmailTemplate(String path) {
+ return _engine.getEmailTemplate(path);
+ }
+
+ /**
+ * Retrieves the email notification handler.
+ *
+ * @return email notification
+ */
+ public static IMailNotification getMailNotification() {
+ return _engine.getMailNotification();
+ }
+
+ /**
+ * Retrieves the email key resolver.
+ *
+ * @return email key resolver
+ */
+ public static IEmailResolverKeys getEmailResolverKeys() {
+ return _engine.getEmailResolverKeys();
+ }
+
+ /**
+ * Checks if the given OID is valid.
+ *
+ * @param attrName attribute name
+ * @param value attribute value
+ * @return object identifier of the given attrName
+ */
+ public static ObjectIdentifier checkOID(String attrName, String value)
+ throws EBaseException {
+ return _engine.checkOID(attrName, value);
+ }
+
+ /**
+ * Retrieves the email resolver that checks for subjectAlternateName.
+ *
+ * @return email key resolver
+ */
+ public static IEmailResolver getReqCertSANameEmailResolver() {
+ return _engine.getReqCertSANameEmailResolver();
+ }
+
+ /**
+ * Retrieves the extension pretty print handler.
+ *
+ * @param e extension
+ * @param indent indentation
+ * @return extension pretty print handler
+ */
+ public static IExtPrettyPrint getExtPrettyPrint(Extension e, int indent) {
+ return _engine.getExtPrettyPrint(e, indent);
+ }
+
+ /**
+ * Retrieves the certificate pretty print handler.
+ *
+ * @param delimiter delimiter
+ * @return certificate pretty print handler
+ */
+ public static IPrettyPrintFormat getPrettyPrintFormat(String delimiter) {
+ return _engine.getPrettyPrintFormat(delimiter);
+ }
+
+ /**
+ * Retrieves the CRL pretty print handler.
+ *
+ * @param crl CRL
+ * @return CRL pretty print handler
+ */
+ public static ICRLPrettyPrint getCRLPrettyPrint(X509CRL crl) {
+ return _engine.getCRLPrettyPrint(crl);
+ }
+
+ /**
+ * Retrieves the CRL cache pretty print handler.
+ *
+ * @param ip CRL issuing point
+ * @return CRL pretty print handler
+ */
+ public static ICRLPrettyPrint getCRLCachePrettyPrint(ICRLIssuingPoint ip) {
+ return _engine.getCRLCachePrettyPrint(ip);
+ }
+
+ /**
+ * Retrieves the certificate pretty print handler.
+ *
+ * @param cert certificate
+ * @return certificate pretty print handler
+ */
+ public static ICertPrettyPrint getCertPrettyPrint(X509Certificate cert) {
+ return _engine.getCertPrettyPrint(cert);
+ }
+
+ public static String getConfigSDSessionId() {
+ return _engine.getConfigSDSessionId();
+ }
+
+ public static void setConfigSDSessionId(String val) {
+ _engine.setConfigSDSessionId(val);
+ }
+
+ /**
+ * Retrieves the password check.
+ *
+ * @return default password checker
+ */
+ public static IPasswordCheck getPasswordChecker() {
+ return _engine.getPasswordChecker();
+ }
+
+ /**
+ * Puts a password entry into the single-sign on cache.
+ *
+ * @param tag password tag
+ * @param pw password
+ */
+ public static void putPasswordCache(String tag, String pw) {
+ _engine.putPasswordCache(tag, pw);
+ }
+
+ /**
+ * Retrieves the password callback.
+ *
+ * @return default password callback
+ */
+ public static PasswordCallback getPasswordCallback() {
+ return _engine.getPasswordCallback();
+ }
+
+ /**
+ * Retrieves command queue
+ *
+ * @return command queue
+ */
+ public static ICommandQueue getCommandQueue() {
+ return _engine.getCommandQueue();
+ }
+
+ /**
+ * Loads the configuration file and starts CMS's core implementation.
+ *
+ * @param path path to configuration file (CMS.cfg)
+ * @exception EBaseException failed to start CMS
+ */
+ public static void start(String path) throws EBaseException {
+ //FileConfigStore mainConfig = null;
+/*
+ try {
+ mainConfig = new FileConfigStore(path);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ System.out.println(
+ "Error: The Server is not fully configured.\n" +
+ "Finish configuring server using Configure Setup Wizard in " +
+ "the Certificate Server Console.");
+ System.out.println(e.toString());
+ System.exit(0);
+ }
+*/
+
+ String classname = "com.netscape.cmscore.apps.CMSEngine";
+
+ CMS cms = null;
+
+ try {
+ ICMSEngine engine = (ICMSEngine)
+ Class.forName(classname).newInstance();
+
+ cms = new CMS(engine);
+ IConfigStore mainConfig = createFileConfigStore(path);
+ cms.init(null, mainConfig);
+ cms.startup();
+
+ } catch (EBaseException e) { // catch everything here purposely
+ CMS.debug("CMS:Caught EBaseException");
+ CMS.debug(e);
+
+ // Raidzilla Bug #57592: Always print error message to stdout.
+ System.out.println(e.toString());
+
+ shutdown();
+ throw e;
+ } catch (Exception e) { // catch everything here purposely
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bos);
+
+ e.printStackTrace(ps);
+ System.out.println(Constants.SERVER_SHUTDOWN_MESSAGE);
+ throw new EBaseException(bos.toString());
+ // cms.shutdown();
+ }
+ }
+
+ public static IConfigStore createFileConfigStore(String path) throws EBaseException {
+ return _engine.createFileConfigStore(path);
+ }
+
+ public static IArgBlock createArgBlock() {
+ return _engine.createArgBlock();
+ }
+
+ public static IArgBlock createArgBlock(String realm, Hashtable httpReq) {
+ return _engine.createArgBlock(realm, httpReq);
+ }
+
+ public static IArgBlock createArgBlock(Hashtable httpReq) {
+ return _engine.createArgBlock(httpReq);
+ }
+
+ public static boolean isRevoked(X509Certificate[] certificates) {
+ return _engine.isRevoked(certificates);
+ }
+
+ public static void setListOfVerifiedCerts(int size, long interval, long unknownStateInterval) {
+ _engine.setListOfVerifiedCerts(size, interval, unknownStateInterval);
+ }
+
+ public static IPasswordStore getPasswordStore() {
+ return _engine.getPasswordStore();
+ }
+
+ public static ISecurityDomainSessionTable getSecurityDomainSessionTable() {
+ return _engine.getSecurityDomainSessionTable();
+ }
+
+ /**
+ * Main driver to start CMS.
+ */
+ public static void main(String[] args) {
+ String path = CONFIG_FILE;
+
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+
+ if (arg.equals("-f")) {
+ path = args[++i];
+ } else {
+ // ignore unknown arguments since we
+ // have no real way to report them
+ }
+ }
+ try {
+ start(path);
+ } catch (EBaseException e) {
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/pki/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
new file mode 100644
index 000000000..060ab7dcb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
@@ -0,0 +1,1088 @@
+// --- 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.certsrv.apps;
+
+
+import java.math.*;
+import java.util.*;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Date;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CRL;
+import java.security.NoSuchAlgorithmException;
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import com.netscape.cmsutil.password.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import com.netscape.certsrv.acls.*;
+
+/**
+ * This interface represents the CMS core framework. The
+ * framework contains a set of services that provide
+ * the foundation of a security application.
+ * <p>
+ * The engine implementation is loaded by CMS at startup.
+ * It is responsible for starting up all the related
+ * subsystems.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICMSEngine extends ISubsystem {
+
+ /**
+ * Gets this ID .
+ *
+ * @return CMS engine identifier
+ */
+ public String getId();
+
+ /**
+ * Sets the identifier of this subsystem. Should never be called.
+ * Returns error.
+ *
+ * @param id CMS engine identifier
+ */
+ public void setId(String id) throws EBaseException;
+
+ /**
+ * Retrieves the process id of this server.
+ *
+ * @return process id of the server
+ */
+ public int getpid();
+
+ public void reinit(String id) throws EBaseException;
+ public int getCSState();
+ public void setCSState(int mode);
+ public boolean isPreOpMode();
+ public boolean isRunningMode();
+ /**
+ * Retrieves the instance roort path of this server.
+ *
+ * @return instance directory path name
+ */
+ public String getInstanceDir();
+
+ /**
+ * Returns a server wide system time. Plugins should call
+ * this method to retrieve system time.
+ *
+ * @return current time
+ */
+ public Date getCurrentDate();
+
+ /**
+ * Retrieves time server started up.
+ *
+ * @return last startup time
+ */
+ public long getStartupTime();
+
+ /**
+ * Is the server in running state. After server startup, the
+ * server will be initialization state first. After the
+ * initialization state, the server will be in the running
+ * state.
+ *
+ * @return true if the server is in the running state
+ */
+ public boolean isInRunningState();
+
+ /**
+ * Returns the names of all the registered subsystems.
+ *
+ * @return a list of string-based subsystem names
+ */
+ public Enumeration getSubsystemNames();
+
+ /**
+ * Returns all the registered subsystems.
+ *
+ * @return a list of ISubsystem-based subsystems
+ */
+ public Enumeration getSubsystems();
+
+ /**
+ * Retrieves the registered subsytem with the given name.
+ *
+ * @param name subsystem name
+ * @return subsystem of the given name
+ */
+ public ISubsystem getSubsystem(String name);
+
+ /**
+ * Returns the logger of the current server. The logger can
+ * be used to log critical informational or critical error
+ * messages.
+ *
+ * @return logger
+ */
+ public ILogger getLogger();
+
+ /**
+ * Returns the signed audit logger of the current server. This logger can
+ * be used to log critical informational or critical error
+ * messages.
+ *
+ * @return signed audit logger
+ */
+ public ILogger getSignedAuditLogger();
+
+ /**
+ * Puts data of an byte array into the debug file.
+ *
+ * @param data byte array to be recorded in the debug file
+ */
+ public void debug(byte data[]);
+
+ /**
+ * Puts a message into the debug file.
+ *
+ * @param msg debugging message
+ */
+ public void debug(String msg);
+
+ /**
+ * Puts a message into the debug file.
+ *
+ * @param level 0-10
+ * @param msg debugging message
+ */
+ public void debug(int level, String msg);
+
+ /**
+ * Puts an exception into the debug file.
+ *
+ * @param e exception
+ */
+ public void debug(Throwable e);
+
+ /**
+ * Checks if the debug mode is on or not.
+ *
+ * @return true if debug mode is on
+ */
+ public boolean debugOn();
+
+ /**
+ * Puts the current stack trace in the debug file.
+ */
+ public void debugStackTrace();
+
+
+ /**
+ * Dump name/value pair debug information to debug file
+ */
+ public void traceHashKey(String type, String key);
+ public void traceHashKey(String type, String key, String val);
+ public void traceHashKey(String type, String key, String val, String def);
+
+
+ public byte[] getPKCS7(Locale locale, IRequest req);
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @return localized user message
+ */
+ public String getUserMessage(Locale locale, String msgID);
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p an array of parameters
+ * @return localized user message
+ */
+ public String getUserMessage(Locale locale, String msgID, String p[]);
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @return localized user message
+ */
+ public String getUserMessage(Locale locale, String msgID, String p1);
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @return localized user message
+ */
+ public String getUserMessage(Locale locale, String msgID, String p1, String p2);
+
+ /**
+ * Retrieves the localized user message from UserMessages.properties.
+ *
+ * @param locale end-user locale
+ * @param msgID message id defined in UserMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @return localized user message
+ */
+ public String getUserMessage(Locale locale, String msgID, String p1, String p2, String p3);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p an array of parameters
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p[]);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @param p8 8th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8);
+
+ /**
+ * Retrieves the centralized log message from LogMessages.properties.
+ *
+ * @param msgID message id defined in LogMessages.properties
+ * @param p1 1st parameter
+ * @param p2 2nd parameter
+ * @param p3 3rd parameter
+ * @param p4 4th parameter
+ * @param p5 5th parameter
+ * @param p6 6th parameter
+ * @param p7 7th parameter
+ * @param p8 8th parameter
+ * @param p9 9th parameter
+ * @return localized log message
+ */
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9);
+
+ /**
+ * Parse ACL resource attributes
+ * @param resACLs same format as the resourceACLs attribute:
+ * <PRE>
+ * <resource name>:<permission1,permission2,...permissionn>:
+ * <allow|deny> (<subset of the permission set>) <evaluator expression>
+ * </PRE>
+ * @exception EACLsException ACL related parsing errors for resACLs
+ * @return an ACL instance built from the parsed resACLs
+ */
+ public IACL parseACL(String resACLs) throws EACLsException;
+
+ /**
+ * Creates an issuing poing record.
+ *
+ * @return issuing record
+ */
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize, Date thisUpdate, Date nextUpdate);
+
+ /**
+ * Retrieves the default CRL issuing point record name.
+ *
+ * @return CRL issuing point record name
+ */
+ public String getCRLIssuingPointRecordName();
+
+ /**
+ * Returns the finger print of the given certificate.
+ *
+ * @param cert certificate
+ * @return finger print of certificate
+ */
+ public String getFingerPrint(Certificate cert)
+ throws CertificateEncodingException, NoSuchAlgorithmException;
+
+ /**
+ * Returns the finger print of the given certificate.
+ *
+ * @param cert certificate
+ * @return finger print of certificate
+ */
+ public String getFingerPrints(Certificate cert)
+ throws NoSuchAlgorithmException, CertificateEncodingException;
+
+ /*
+ * Returns the finger print of the given certificate.
+ *
+ * @param certDer DER byte array of certificate
+ * @return finger print of certificate
+ */
+ public String getFingerPrints(byte[] certDer)
+ throws NoSuchAlgorithmException;
+
+ /**
+ * Creates a repository record in the internal database.
+ *
+ * @return repository record
+ */
+ public IRepositoryRecord createRepositoryRecord();
+
+ /**
+ * Creates a HTTP PKI Message that can be sent to a remote
+ * authority.
+ *
+ * @return a new PKI Message for remote authority
+ */
+ public IPKIMessage getHttpPKIMessage();
+
+ /**
+ * Creates a request encoder. A request cannot be sent to
+ * the remote authority in its regular format.
+ *
+ * @return a request encoder
+ */
+ public IRequestEncoder getHttpRequestEncoder();
+
+ /**
+ * Converts a BER-encoded byte array into a MIME-64 encoded string.
+ *
+ * @param data data in byte array format
+ * @return base-64 encoding for the data
+ */
+ public String BtoA(byte data[]);
+
+ /**
+ * Converts a MIME-64 encoded string into a BER-encoded byte array.
+ *
+ * @param data base-64 encoding for the data
+ * @return data data in byte array format
+ */
+ public byte[] AtoB(String data);
+
+ /**
+ * Retrieves the certifcate in MIME-64 encoded format
+ * with header and footer.
+ *
+ * @param cert certificate
+ * @return base-64 format certificate
+ */
+ public String getEncodedCert(X509Certificate cert);
+
+ /**
+ * Retrieves the certificate pretty print handler.
+ *
+ * @param delimiter delimiter
+ * @return certificate pretty print handler
+ */
+ public IPrettyPrintFormat getPrettyPrintFormat(String delimiter);
+
+ /**
+ * Retrieves the extension pretty print handler.
+ *
+ * @param e extension
+ * @param indent indentation
+ * @return extension pretty print handler
+ */
+ public IExtPrettyPrint getExtPrettyPrint(Extension e, int indent);
+
+ /**
+ * Retrieves the certificate pretty print handler.
+ *
+ * @param cert certificate
+ * @return certificate pretty print handler
+ */
+ public ICertPrettyPrint getCertPrettyPrint(X509Certificate cert);
+
+ /**
+ * Retrieves the CRL pretty print handler.
+ *
+ * @param crl CRL
+ * @return CRL pretty print handler
+ */
+ public ICRLPrettyPrint getCRLPrettyPrint(X509CRL crl);
+
+ /**
+ * Retrieves the CRL cache pretty print handler.
+ *
+ * @param ip CRL issuing point
+ * @return CRL pretty print handler
+ */
+ public ICRLPrettyPrint getCRLCachePrettyPrint(ICRLIssuingPoint ip);
+
+ /**
+ * Retrieves the ldap connection information from the configuration
+ * store.
+ *
+ * @param config configuration parameters of ldap connection
+ * @return a LDAP connection info
+ */
+ public ILdapConnInfo getLdapConnInfo(IConfigStore config)
+ throws EBaseException, ELdapException;
+
+ /**
+ * Creates a LDAP SSL socket with the given nickname. The
+ * certificate associated with the nickname will be used
+ * for client authentication.
+ *
+ * @param certNickname nickname of client certificate
+ * @return LDAP SSL socket factory
+ */
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory(
+ String certNickname);
+
+ /**
+ * Creates a LDAP SSL socket.
+ *
+ * @return LDAP SSL socket factory
+ */
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory();
+
+ /**
+ * Creates a LDAP Auth Info object.
+ *
+ * @return LDAP authentication info
+ */
+ public ILdapAuthInfo getLdapAuthInfo();
+
+ /**
+ * Retrieves the LDAP connection factory.
+ *
+ * @return bound LDAP connection pool
+ */
+ public ILdapConnFactory getLdapBoundConnFactory() throws ELdapException;
+
+ public LDAPConnection getBoundConnection(String host, int port,
+ int version, LDAPSSLSocketFactoryExt fac, String bindDN,
+ String bindPW) throws LDAPException;
+ /**
+ * Retrieves the LDAP connection factory.
+ *
+ * @return anonymous LDAP connection pool
+ */
+ public ILdapConnFactory getLdapAnonConnFactory() throws ELdapException;
+
+ /**
+ * Retrieves the password check.
+ *
+ * @return default password checker
+ */
+ public IPasswordCheck getPasswordChecker();
+
+ /**
+ * Puts a password entry into the single-sign on cache.
+ *
+ * @param tag password tag
+ * @param pw password
+ */
+ public void putPasswordCache(String tag, String pw);
+
+ /**
+ * Retrieves the password callback.
+ *
+ * @return default password callback
+ */
+ public PasswordCallback getPasswordCallback();
+
+ /**
+ * Retrieves the nickname of the server's server certificate.
+ *
+ * @return nickname of the server certificate
+ */
+ public String getServerCertNickname();
+
+ /**
+ * Sets the nickname of the server's server certificate.
+ *
+ * @param tokenName name of token where the certificate is located
+ * @param nickName name of server certificate
+ */
+ public void setServerCertNickname(String tokenName, String nickName);
+
+ /**
+ * Sets the nickname of the server's server certificate.
+ *
+ * @param newName new nickname of server certificate
+ */
+ public void setServerCertNickname(String newName);
+
+ /**
+ * Retrieves the host name of the server's secure end entity service.
+ *
+ * @return host name of end-entity service
+ */
+ public String getEEHost();
+
+ /**
+ * Retrieves the host name of the server's non-secure end entity service.
+ *
+ * @return host name of end-entity non-secure service
+ */
+ public String getEENonSSLHost();
+
+ /**
+ * Retrieves the IP address of the server's non-secure end entity service.
+ *
+ * @return ip address of end-entity non-secure service
+ */
+ public String getEENonSSLIP();
+
+ /**
+ * Retrieves the port number of the server's non-secure end entity service.
+ *
+ * @return port of end-entity non-secure service
+ */
+ public String getEENonSSLPort();
+
+ /**
+ * Retrieves the host name of the server's secure end entity service.
+ *
+ * @return port of end-entity secure service
+ */
+ public String getEESSLHost();
+
+ /**
+ * Retrieves the IP address of the server's secure end entity service.
+ *
+ * @return ip address of end-entity secure service
+ */
+ public String getEESSLIP();
+
+ /**
+ * Retrieves the port number of the server's secure end entity service.
+ *
+ * @return port of end-entity secure service
+ */
+ public String getEESSLPort();
+
+ /**
+ * Retrieves the port number of the server's client auth secure end entity service.
+ *
+ * @return port of end-entity client auth secure service
+ */
+ public String getEEClientAuthSSLPort();
+
+ /**
+ * Retrieves the host name of the server's agent service.
+ *
+ * @return host name of agent service
+ */
+ public String getAgentHost();
+
+ /**
+ * Retrieves the IP address of the server's agent service.
+ *
+ * @return ip address of agent service
+ */
+ public String getAgentIP();
+
+ /**
+ * Retrieves the port number of the server's agent service.
+ *
+ * @return port of agent service
+ */
+ public String getAgentPort();
+
+ /**
+ * Retrieves the host name of the server's administration service.
+ *
+ * @return host name of administration service
+ */
+ public String getAdminHost();
+
+ /**
+ * Retrieves the IP address of the server's administration service.
+ *
+ * @return ip address of administration service
+ */
+ public String getAdminIP();
+
+ /**
+ * Retrieves the port number of the server's administration service.
+ *
+ * @return port of administration service
+ */
+ public String getAdminPort();
+
+ /**
+ * Verifies all system certificates
+ * @return true if all passed, false otherwise
+ */
+ public boolean verifySystemCerts();
+
+ /**
+ * Verifies a system certificate by its tag name
+ * as defined in <subsystemtype>.cert.list
+ * @return true if passed, false otherwise
+ */
+ public boolean verifySystemCertByTag(String tag);
+
+ /**
+ * Verifies a system certificate by its nickname
+ * @return true if passed, false otherwise
+ */
+ public boolean verifySystemCertByNickname(String nickname, String certificateUsage);
+
+ /**
+ * get the CertificateUsage as defined in JSS CryptoManager
+ * @return CertificateUsage as defined in JSS CryptoManager
+ */
+ public CertificateUsage getCertificateUsage(String certusage);
+
+ /**
+ * Checks if the given certificate is a signing certificate.
+ *
+ * @param cert certificate
+ * @return true if the given certificate is a signing certificate
+ */
+ public boolean isSigningCert(X509Certificate cert);
+
+ /**
+ * Checks if the given certificate is an encryption certificate.
+ *
+ * @param cert certificate
+ * @return true if the given certificate is an encryption certificate
+ */
+ public boolean isEncryptionCert(X509Certificate cert);
+
+ /**
+ * Retrieves the default X.509 certificate template.
+ *
+ * @return default certificate template
+ */
+ public X509CertInfo getDefaultX509CertInfo();
+
+ /**
+ * Retrieves the email form processor.
+ *
+ * @return email form processor
+ */
+ public IEmailFormProcessor getEmailFormProcessor();
+
+ /**
+ * Retrieves the email form template.
+ *
+ * @return email template
+ */
+ public IEmailTemplate getEmailTemplate(String path);
+
+ /**
+ * Retrieves the email notification handler.
+ *
+ * @return email notification
+ */
+ public IMailNotification getMailNotification();
+
+ /**
+ * Retrieves the email key resolver.
+ *
+ * @return email key resolver
+ */
+ public IEmailResolverKeys getEmailResolverKeys();
+
+ /**
+ * Retrieves the email resolver that checks for subjectAlternateName.
+ *
+ * @return email key resolver
+ */
+ public IEmailResolver getReqCertSANameEmailResolver();
+
+ /**
+ * Checks if the given OID is valid.
+ *
+ * @param attrName attribute name
+ * @param value attribute value
+ * @return object identifier of the given attrName
+ */
+ public ObjectIdentifier checkOID(String attrName, String value)
+ throws EBaseException;
+
+ /**
+ * Creates a general name constraints.
+ *
+ * @param generalNameChoice type of general name
+ * @param value general name string
+ * @return general name object
+ * @exception EBaseException failed to create general name constraint
+ */
+ public GeneralName form_GeneralNameAsConstraints(String generalNameChoice, String value) throws EBaseException;
+
+ /**
+ * Creates a general name.
+ *
+ * @param generalNameChoice type of general name
+ * @param value general name string
+ * @return general name object
+ * @exception EBaseException failed to create general name
+ */
+ public GeneralName form_GeneralName(String generalNameChoice,
+ String value) throws EBaseException;
+
+ /**
+ * Retrieves default general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param params configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public void getGeneralNameConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params);
+
+ /**
+ * Retrieves default general names configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param params configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public void getGeneralNamesConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params);
+
+ /**
+ * Retrieves extended plugin info for general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param info configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public void getGeneralNameConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info);
+
+ /**
+ * Retrieves extended plugin info for general name configuration.
+ *
+ * @param name configuration name
+ * @param isValueConfigured true if value is configured
+ * @param info configuration parameters
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public void getGeneralNamesConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info);
+
+ /**
+ * Created general names configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public IGeneralNamesConfig createGeneralNamesConfig(String name,
+ IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException;
+
+ /**
+ * Created general name constraints configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public IGeneralNameAsConstraintsConfig createGeneralNameAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException;
+
+ /**
+ * Created general name constraints configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @param isPolicyEnabled true if policy is enabled
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public IGeneralNamesAsConstraintsConfig createGeneralNamesAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException;
+
+ /**
+ * Get default parameters for subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param params configuration parameters
+ */
+ public void getSubjAltNameConfigDefaultParams(String name, Vector params);
+
+ /**
+ * Get extended plugin info for subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param params configuration parameters
+ */
+ public void getSubjAltNameConfigExtendedPluginInfo(String name, Vector params);
+
+ /**
+ * Creates subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param config configuration store
+ * @param isValueConfigured true if value is configured
+ * @exception EBaseException failed to create subject alt name configuration
+ */
+ public ISubjAltNameConfig createSubjAltNameConfig(String name, IConfigStore config, boolean isValueConfigured) throws EBaseException;
+
+ /**
+ * Retrieves the HTTP Connection for use with connector.
+ *
+ * @param authority remote authority
+ * @param factory socket factory
+ * @return http connection to the remote authority
+ */
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory);
+
+ /**
+ * Retrieves the HTTP Connection for use with connector.
+ *
+ * @param authority remote authority
+ * @param factory socket factory
+ * @param timeout return error if connection cannot be established within
+ * the timeout period
+ * @return http connection to the remote authority
+ */
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory, int timeout);
+
+ /**
+ * Retrieves the request sender for use with connector.
+ *
+ * @param authority local authority
+ * @param nickname nickname of the client certificate
+ * @param remote remote authority
+ * @param interval timeout interval
+ * @return resender
+ */
+ public IResender getResender(IAuthority authority, String nickname,
+ IRemoteAuthority remote, int interval);
+
+ /**
+ * Retrieves command queue
+ *
+ * @return command queue
+ */
+ public ICommandQueue getCommandQueue();
+
+ /**
+ * Blocks all new incoming requests.
+ */
+ public void disableRequests();
+
+ /**
+ * Terminates all requests that are currently in process.
+ */
+ public void terminateRequests();
+
+ /**
+ * Checks to ensure that all new incoming requests have been blocked.
+ * This method is used for reentrancy protection.
+ * <P>
+ *
+ * @return true or false
+ */
+ public boolean areRequestsDisabled();
+
+ /**
+ * Create configuration file.
+ *
+ * @param path configuration path
+ * @return configuration store
+ * @exception EBaseException failed to create file
+ */
+ public IConfigStore createFileConfigStore(String path) throws EBaseException;
+ /**
+ * Creates argument block.
+ */
+ public IArgBlock createArgBlock();
+
+ /**
+ * Creates argument block.
+ */
+ public IArgBlock createArgBlock(String realm, Hashtable httpReq);
+
+ /**
+ * Creates argument block.
+ */
+ public IArgBlock createArgBlock(Hashtable httpReq);
+
+ /**
+ * Checks against the local certificate repository to see
+ * if the certificates are revoked.
+ *
+ * @param certificates certificates
+ * @return true if certificate is revoked in the local
+ * certificate repository
+ */
+ public boolean isRevoked(X509Certificate[] certificates);
+
+ /**
+ * Sets list of verified certificates
+ *
+ * @param size size of verified certificates list
+ * @param interval interval in which certificate is not recheck
+ * against local certificate repository
+ * @param unknownStateInterval interval in which certificate
+ * may not recheck against local certificate repository
+ */
+ public void setListOfVerifiedCerts(int size, long interval, long unknownStateInterval);
+
+ /**
+ * Performs graceful shutdown of CMS.
+ * Subsystems are shutdown in reverse order.
+ * Exceptions are ignored.
+ */
+ public void forceShutdown();
+
+ public IPasswordStore getPasswordStore();
+
+ public ISecurityDomainSessionTable getSecurityDomainSessionTable();
+
+ public void setConfigSDSessionId(String id);
+
+ public String getConfigSDSessionId();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java b/pki/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java
new file mode 100644
index 000000000..15224c00c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.apps;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.TimeZone;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This interface represents a command queue for registeration
+ * and unregisteration proccess for clean shutdown
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICommandQueue {
+
+ /**
+ * Registers a thread into the command queue.
+ *
+ * @param currentRequest request object
+ * @param currentServlet servlet that serves the request object
+ */
+ public boolean registerProcess(Object currentRequest, Object currentServlet);
+ /**
+ * UnRegisters a thread from the command queue.
+ *
+ * @param currentRequest request object
+ * @param currentServlet servlet that serves the request object
+ */
+ public void unRegisterProccess(Object currentRequest, Object currentServlet);
+
+} // CommandQueue
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java b/pki/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java
new file mode 100644
index 000000000..e363f01d2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java
@@ -0,0 +1,98 @@
+// --- 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.certsrv.authentication;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+/**
+ * Authentication Credentials as input to the authMgr. It contains all the
+ * information required for authentication in the authMgr.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthCredentials implements IAuthCredentials {
+ private Hashtable authCreds = null;
+ private IArgBlock argblk = null;
+
+ /**
+ * Constructor
+ */
+ public AuthCredentials() {
+ authCreds = new Hashtable();
+ }
+
+ /**
+ * Sets an authentication credential with credential name and the credential object
+ * @param name credential name
+ * @param cred credential object
+ */
+ public void set(String name, Object cred) {
+ if (name != null && cred != null)
+ authCreds.put(name, cred);
+ }
+
+ /**
+ * Returns the credential to which the specified name is mapped in this
+ * credential set
+ * @param name credential name
+ * @return the authentication credential for the given name
+ */
+ public Object get(String name) {
+ return ((Object) authCreds.get(name));
+ }
+
+ /**
+ * Removes the name and its corresponding credential from this
+ * credential set. This method does nothing if the named
+ * credential is not in the credential set.
+ * @param name credential name
+ */
+ public void delete(String name) {
+ authCreds.remove(name);
+ }
+
+ /**
+ * Returns an enumeration of the credentials in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ * @return an enumeration of the values in this credential set
+ */
+ public Enumeration getElements() {
+ return (authCreds.elements());
+ }
+
+ /**
+ * Set the given argblock
+i * @param blk the given argblock.
+ */
+ public void setArgBlock(IArgBlock blk) {
+ argblk = blk;
+ }
+
+ /**
+ * Returns the argblock.
+ * @return the argblock.
+ */
+ public IArgBlock getArgBlock() {
+ return argblk;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java b/pki/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java
new file mode 100644
index 000000000..f98276ec5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java
@@ -0,0 +1,56 @@
+// --- 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.certsrv.authentication;
+
+
+/**
+ * A class represents an authentication manager. It contains an
+ * authentication manager instance and its state (enable or not).
+ * @version $Revision$, $Date$
+ */
+public class AuthManagerProxy {
+ private boolean mEnable;
+ private IAuthManager mMgr;
+
+ /**
+ * Constructor
+ * @param enable true if the authMgr is enabled; false otherwise
+ * @param mgr authentication manager instance
+ */
+ public AuthManagerProxy(boolean enable, IAuthManager mgr) {
+ mEnable = enable;
+ mMgr = mgr;
+ }
+
+ /**
+ * Returns the state of the authentication manager instance
+ * @return true if the state of the authentication manager instance is
+ * enabled; false otherwise.
+ */
+ public boolean isEnable() {
+ return mEnable;
+ }
+
+ /**
+ * Returns an authentication manager instance.
+ * @return an authentication manager instance
+ */
+ public IAuthManager getAuthManager() {
+ return mMgr;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java b/pki/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java
new file mode 100644
index 000000000..cb6e3e4ce
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java
@@ -0,0 +1,85 @@
+// --- 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.certsrv.authentication;
+
+
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * This class represents a registered authentication manager plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthMgrPlugin {
+ protected String mId = null;
+ protected String mClassPath = null;
+ protected Class mClass = null;
+ protected boolean mVisible = true;
+
+ /**
+ * Constructs a AuthManager plugin.
+ * @param id auth manager implementation name
+ * @param classPath class path
+ */
+ public AuthMgrPlugin(String id, String classPath) {
+
+ /*
+ if (id == null || classPath == null)
+ throw new AssertionException("Authentication Manager id or classpath can't be null");
+ */
+ mId = id;
+ mClassPath = classPath;
+ }
+
+ /**
+ * Returns an auth manager implementation name
+ * @return an auth manager implementation name
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns a classpath of a AuthManager plugin
+ * @return a classpath of a AuthManager plugin
+ */
+ public String getClassPath() {
+ return mClassPath;
+ }
+
+ /**
+ * Returns a visibility of the plugin
+ * @return a visibility of the plugin
+ */
+ public boolean isVisible() {
+ return mVisible;
+ }
+
+ /**
+ * Sets visibility of the plugin
+ * @param visibility visibility of the plugin
+ */
+ public void setVisible(boolean visibility) {
+ mVisible = visibility;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/AuthResources.java b/pki/base/common/src/com/netscape/certsrv/authentication/AuthResources.java
new file mode 100644
index 000000000..5bf52f1b8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/AuthResources.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.authentication;
+
+import java.util.*;
+
+/**
+ * A class represents a resource bundle for the authentication component.
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ * @return the contents of this resource
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * A set of constants for localized error messages.
+ */
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/AuthToken.java b/pki/base/common/src/com/netscape/certsrv/authentication/AuthToken.java
new file mode 100644
index 000000000..4ff2c6a7f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/AuthToken.java
@@ -0,0 +1,443 @@
+// --- 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.certsrv.authentication;
+
+import java.util.Hashtable;
+import java.util.Date;
+import java.util.Enumeration;
+import java.math.BigInteger;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.usrgrp.Certificates;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateExtensions;
+
+/**
+ * Authentication token returned by Authentication Managers.
+ * Upon return, it contains authentication/identification information
+ * as well as information retrieved from the database where the
+ * authentication was done against. Each authentication manager has
+ * its own list of such information. See individual authenticaiton
+ * manager for more details.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public class AuthToken implements IAuthToken {
+ protected Hashtable mAttrs = null;
+
+ /* Subject name of the certificate in the authenticating entry */
+ public static final String TOKEN_CERT_SUBJECT = "tokenCertSubject";
+
+ /* NotBefore value of the certificate in the authenticating entry */
+ public static final String TOKEN_CERT_NOTBEFORE = "tokenCertNotBefore";
+
+ /* NotAfter value of the certificate in the authenticating entry */
+ public static final String TOKEN_CERT_NOTAFTER = "tokenCertNotAfter";
+
+ /* Cert Extentions value of the certificate in the authenticating entry */
+ public static final String TOKEN_CERT_EXTENSIONS = "tokenCertExts";
+
+ /* Serial number of the certificate in the authenticating entry */
+ public static final String TOKEN_CERT_SERIALNUM = "certSerial";
+
+ /**
+ * Certificate to be renewed
+ */
+ public static final String TOKEN_CERT = "tokenCert";
+
+ /* Certificate to be revoked */
+ public static final String TOKEN_CERT_TO_REVOKE = "tokenCertToRevoke";
+
+ /**
+ * Plugin name of the authentication manager that created the
+ * AuthToken as a string.
+ */
+ public static final String TOKEN_AUTHMGR_IMPL_NAME = "authMgrImplName";
+
+ /**
+ * Name of the authentication manager that created the AuthToken
+ * as a string.
+ */
+ public static final String TOKEN_AUTHMGR_INST_NAME = "authMgrInstName";
+
+ /**
+ * Time of authentication as a java.util.Date
+ */
+ public static final String TOKEN_AUTHTIME = "authTime";
+
+ /**
+ * Constructs an instance of a authentication token.
+ * The token by default contains the following attributes: <br>
+ * <pre>
+ * "authMgrInstName" - The authentication manager instance name.
+ * "authMgrImplName" - The authentication manager plugin name.
+ * "authTime" - The - The time of authentication.
+ * </pre>
+ * @param authMgr The authentication manager that created this Token.
+ */
+ public AuthToken(IAuthManager authMgr) {
+ mAttrs = new Hashtable();
+ if (authMgr != null) {
+ set(TOKEN_AUTHMGR_INST_NAME, authMgr.getName());
+ set(TOKEN_AUTHMGR_IMPL_NAME, authMgr.getImplName());
+ }
+ set(TOKEN_AUTHTIME, new Date());
+ }
+
+ public String getInString(String attrName) {
+ return (String)mAttrs.get(attrName);
+ }
+
+ public boolean set(String attrName, String value) {
+ if (value == null) {
+ return false;
+ }
+ mAttrs.put(attrName, value);
+ return true;
+ }
+
+ /**
+ * Removes an attribute in the AuthToken
+ * @param attrName The name of the attribute to remove.
+ */
+ public void delete(String attrName) {
+ mAttrs.remove(attrName);
+ }
+
+ /**
+ * Enumerate all attribute names in the AuthToken.
+ * @return Enumeration of all attribute names in this AuthToken.
+ */
+ public Enumeration getElements() {
+ return (mAttrs.keys());
+ }
+
+ public byte[] getInByteArray(String name) {
+ String value = getInString(name);
+ if (value == null) {
+ return null;
+ }
+ return CMS.AtoB(value);
+ }
+
+ public boolean set(String name, byte[] value) {
+ if (value == null) {
+ return false;
+ }
+ return set(name, CMS.BtoA(value));
+ }
+
+ public Integer getInInteger(String name) {
+ String strVal = getInString(name);
+ if (strVal == null) {
+ return null;
+ }
+ try {
+ return Integer.valueOf(strVal);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ public boolean set(String name, Integer value) {
+ if (value == null) {
+ return false;
+ }
+ return set(name, value.toString());
+ }
+
+ public BigInteger[] getInBigIntegerArray(String name) {
+ String value = getInString(name);
+ if (value == null) {
+ return null;
+ }
+ String[] values = value.split(",");
+ if (values.length == 0) {
+ return null;
+ }
+ BigInteger[] result = new BigInteger[values.length];
+ for (int i = 0; i < values.length; i++) {
+ try {
+ result[i] = new BigInteger(values[i]);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ return result;
+ }
+
+ public boolean set(String name, BigInteger[] value) {
+ if (value == null) {
+ return false;
+ }
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < value.length; i++) {
+ if (i != 0) {
+ buffer.append(",");
+ }
+ buffer.append(value[i].toString());
+ }
+ return set(name, buffer.toString());
+ }
+
+ public Date getInDate(String name) {
+ String value = getInString(name);
+ if (value == null) {
+ return null;
+ }
+ try {
+ return new Date(Long.parseLong(value));
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ public boolean set(String name, Date value) {
+ if (value == null) {
+ return false;
+ }
+ return set(name, String.valueOf(value.getTime()));
+ }
+
+ public String[] getInStringArray(String name) {
+ String[] stringValues;
+
+ byte[] byteValue = getInByteArray(name);
+ if (byteValue == null) {
+ return null;
+ }
+ try {
+ DerInputStream in = new DerInputStream(byteValue);
+ DerValue[] derValues = in.getSequence(5);
+ stringValues = new String[derValues.length];
+ for (int i = 0; i < derValues.length; i++) {
+ stringValues[i] = derValues[i].getAsString();
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ return stringValues;
+ }
+
+ public boolean set(String name, String[] value) {
+ if (value == null) {
+ return false;
+ }
+ DerOutputStream out = new DerOutputStream();
+ DerValue[] derValues = new DerValue[value.length];
+ try {
+ for (int i = 0; i < value.length; i++) {
+ derValues[i] = new DerValue(value[i]);
+ }
+ out.putSequence(derValues);
+ return set(name, out.toByteArray());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public X509CertImpl getInCert(String name) {
+ byte[] data = getInByteArray(name);
+ if (data == null) {
+ return null;
+ }
+ try {
+ return new X509CertImpl(data);
+ } catch (CertificateException e) {
+ return null;
+ }
+ }
+
+ public boolean set(String name, X509CertImpl value) {
+ if (value == null) {
+ return false;
+ }
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ value.encode(out);
+ } catch (CertificateEncodingException e) {
+ return false;
+ }
+ return set(name, out.toByteArray());
+ }
+
+ public CertificateExtensions getInCertExts(String name) {
+ CertificateExtensions exts = null;
+ byte[] data = getInByteArray(name);
+ if (data != null) {
+ try {
+ exts = new CertificateExtensions();
+ // exts.decode() doesn't work for empty CertExts
+ exts.decodeEx(new ByteArrayInputStream(data));
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return exts;
+ }
+
+ public boolean set(String name, CertificateExtensions value) {
+ if (value == null) {
+ return false;
+ }
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ value.encode(out);
+ } catch (IOException e) {
+ return false;
+ } catch (CertificateException e) {
+ return false;
+ }
+ return set(name, out.toByteArray());
+ }
+
+ public Certificates getInCertificates(String name) {
+ X509CertImpl[] certArray;
+
+ byte[] byteValue = getInByteArray(name);
+ if (byteValue == null) {
+ return null;
+ }
+
+ try {
+ DerInputStream in = new DerInputStream(byteValue);
+ DerValue[] derValues = in.getSequence(5);
+ certArray = new X509CertImpl[derValues.length];
+ for (int i = 0; i < derValues.length; i++) {
+ byte[] certData = derValues[i].toByteArray();
+ certArray[i] = new X509CertImpl(certData);
+ }
+ } catch (IOException e) {
+ return null;
+ } catch (CertificateException e) {
+ return null;
+ }
+ return new Certificates(certArray);
+ }
+
+ public boolean set(String name, Certificates value) {
+ if (value == null) {
+ return false;
+ }
+ DerOutputStream derStream = new DerOutputStream();
+ X509Certificate[] certArray = value.getCertificates();
+ DerValue[] derValues = new DerValue[certArray.length];
+ try {
+ for (int i = 0; i < certArray.length; i++) {
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ try {
+ X509CertImpl certImpl = (X509CertImpl)certArray[i];
+ certImpl.encode(byteStream);
+ derValues[i] = new DerValue(byteStream.toByteArray());
+ } catch (CertificateEncodingException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ derStream.putSequence(derValues);
+ return set(name, derStream.toByteArray());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public byte[][] getInByteArrayArray(String name) {
+ byte[][] retval;
+
+ byte[] byteValue = getInByteArray(name);
+ if (byteValue == null) {
+ return null;
+ }
+ try {
+ DerInputStream in = new DerInputStream(byteValue);
+ DerValue[] derValues = in.getSequence(5);
+ retval = new byte[derValues.length][];
+ for (int i = 0; i < derValues.length; i++) {
+ retval[i] = derValues[i].getOctetString();
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ return retval;
+ }
+
+ public boolean set(String name, byte[][] value) {
+ if (value == null) {
+ return false;
+ }
+ DerOutputStream out = new DerOutputStream();
+ DerValue[] derValues = new DerValue[value.length];
+ try {
+ for (int i = 0; i < value.length; i++) {
+ derValues[i] = new DerValue(DerValue.tag_OctetString, value[i]);
+ }
+ out.putSequence(derValues);
+ return set(name, out.toByteArray());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Enumerate all attribute values in the AuthToken.
+ * @return Enumeration of all attribute names in this AuthToken.
+ */
+ public Enumeration getVals() {
+ return (mAttrs.elements());
+ }
+
+ /**
+ * Gets the name of the authentication manager instance that created
+ * this token.
+ * @return The name of the authentication manager instance that created
+ * this token.
+ */
+ public String getAuthManagerInstName() {
+ return ((String) mAttrs.get(TOKEN_AUTHMGR_INST_NAME));
+ }
+
+ /**
+ * Gets the plugin name of the authentication manager that created this
+ * token.
+ * @return The plugin name of the authentication manager that created this
+ * token.
+ */
+ public String getAuthManagerImplName() {
+ return ((String) mAttrs.get(TOKEN_AUTHMGR_IMPL_NAME));
+ }
+
+ /**
+ * Gets the time of authentication.
+ * @return The time of authentication
+ */
+ public Date getAuthTime() {
+ return ((Date) mAttrs.get(TOKEN_AUTHTIME));
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EAuthException.java b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthException.java
new file mode 100644
index 000000000..8f68f870b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthException.java
@@ -0,0 +1,81 @@
+// --- 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.certsrv.authentication;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This class represents authentication exceptions.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class EAuthException extends EBaseException {
+
+ /**
+ * Resource class name
+ */
+ private static final String AUTH_RESOURCES = AuthResources.class.getName();
+
+ /**
+ * Constructs an authentication exception
+ * <P>
+ * @param msgFormat exception details
+ */
+ public EAuthException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs an authentication exception with a parameter.
+ * <p>
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EAuthException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a auth exception with a exception parameter.
+ * <P>
+ * @param msgFormat exception details in message string format
+ * @param exception system exception
+ */
+ public EAuthException(String msgFormat, Exception exception) {
+ super(msgFormat, exception);
+ }
+
+ /**
+ * Constructs a auth exception with a list of parameters.
+ * <P>
+ * @param msgFormat the message format.
+ * @param params list of message format parameters
+ */
+ public EAuthException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Returns the resource bundle name
+ * @return resource bundle name.
+ */
+ protected String getBundleName() {
+ return AUTH_RESOURCES;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java
new file mode 100644
index 000000000..81dcccbbd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java
@@ -0,0 +1,33 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * An exception for authentication internal error.
+ */
+public class EAuthInternalError extends EAuthException {
+
+ /**
+ * Constructs an authentication internal error exception
+ * with a detailed message.
+ * @param errorString Detailed error message.
+ */
+ public EAuthInternalError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java
new file mode 100644
index 000000000..b623f006b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * Exception for authentication manager not found.
+ */
+public class EAuthMgrNotFound extends EAuthException {
+
+ /**
+ * Constructs a exception for a missing authentication manager
+ * @param errorString error string for missing authentication manager
+ */
+ public EAuthMgrNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java
new file mode 100644
index 000000000..3904f5ed5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * Exception for authentication manager not found.
+ */
+public class EAuthMgrPluginNotFound extends EAuthException {
+
+ /**
+ * Constructs a exception for a missing authentication manager plugin
+ * @param errorString error for a missing authentication manager plugin
+ */
+ public EAuthMgrPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java
new file mode 100644
index 000000000..684b8c8a9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * Exception for invalid attribute value
+ */
+public class EAuthUserError extends EAuthException {
+
+ /**
+ * Constructs a exception for a Invalid attribute value
+ * @param errorString Detailed error message.
+ */
+ public EAuthUserError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java b/pki/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java
new file mode 100644
index 000000000..5203fa180
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * An exception for DN component syntax error.
+ */
+public class ECompSyntaxErr extends EAuthException {
+
+ /**
+ * Constructs an component syntax error
+ * @param errorString Detailed error message.
+ */
+ public ECompSyntaxErr(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java b/pki/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java
new file mode 100644
index 000000000..ff657351f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * An exception for Error formulating the subject name (X500Name)
+ */
+public class EFormSubjectDN extends EAuthException {
+
+ /**
+ * Constructs an Error on formulating the subject dn.
+ * @param errorString Detailed error message.
+ */
+ public EFormSubjectDN(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java b/pki/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java
new file mode 100644
index 000000000..e77fff3ca
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * An exception for invalid credentials.
+ */
+public class EInvalidCredentials extends EAuthException {
+
+ /**
+ * Constructs an Invalid Credentials exception.
+ * @param errorString Detailed error message.
+ */
+ public EInvalidCredentials(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java b/pki/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java
new file mode 100644
index 000000000..655366518
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authentication;
+
+/**
+ * Exception for missing a required authentication credential.
+ */
+public class EMissingCredential extends EAuthException {
+
+ /**
+ * Constructs a exception for a missing required authentication credential
+ * @param errorString Detailed error message.
+ */
+ public EMissingCredential(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java
new file mode 100644
index 000000000..bb04f0698
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.authentication;
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+/**
+ * An interface represents authentication credentials:
+ * e.g. uid/pwd, uid/pin, certificate, etc.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthCredentials extends IAttrSet {
+
+ /**
+ * Set argblock.
+ * @param blk argblock
+ */
+ public void setArgBlock(IArgBlock blk);
+
+ /**
+ * Returns argblock.
+ * @return Argblock.
+ */
+ public IArgBlock getArgBlock();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
new file mode 100644
index 000000000..c82fa72a8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
@@ -0,0 +1,106 @@
+// --- 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.certsrv.authentication;
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+/**
+ * Authentication Manager interface.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthManager {
+
+ /* standard credential for client cert from ssl client auth */
+ public static final String CRED_SSL_CLIENT_CERT = "sslClientCert";
+
+ /**
+ * Standard credential for client cert's serial number from revocation.
+ */
+ public static final String CRED_CERT_SERIAL_TO_REVOKE = "certSerialToRevoke";
+ public static final String CRED_SESSION_ID = "sessionID";
+ public static final String CRED_HOST_NAME = "hostname";
+
+ /**
+ * Get the name of this authentication manager instance.
+ * <p>
+ * @return the name of this authentication manager.
+ */
+ public String getName();
+
+ /**
+ * Get name of authentication manager plugin.
+ * <p>
+ * @return the name of the authentication manager plugin.
+ */
+ public String getImplName();
+
+ /**
+ * Authenticate the given credentials.
+ * @param authCred The authentication credentials
+ * @return authentication token
+ * @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.
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException;
+
+ /**
+ * Initialize this authentication manager.
+ * @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.
+ * @exception EBaseException If an initialization error occurred.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Prepare this authentication manager for a shutdown.
+ * Called when the server is exiting for any cleanup needed.
+ */
+ public void shutdown();
+
+ /**
+ * Gets a list of the required credentials for this authentication manager.
+ * @return The required credential attributes.
+ */
+ public String[] getRequiredCreds();
+
+ /**
+ * Get configuration parameters for this implementation.
+ * The configuration parameters returned is passed to the
+ * configuration console so configuration for instances of this
+ * implementation can be made through the console.
+ *
+ * @return a list of configuration parameters.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException;
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
new file mode 100644
index 000000000..0b91fa675
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
@@ -0,0 +1,223 @@
+// --- 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.certsrv.authentication;
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+/**
+ * An interface that represents an authentication component
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthSubsystem extends ISubsystem {
+
+ /**
+ * Constant for auths.
+ */
+ public static final String ID = "auths";
+
+ /**
+ * Constant for class.
+ */
+ public static final String PROP_CLASS = "class";
+
+ /**
+ * Constant for impl
+ */
+ public static final String PROP_IMPL = "impl";
+
+ /**
+ * Constant for pluginName.
+ */
+ public static final String PROP_PLUGIN = "pluginName";
+
+ /**
+ * Constant for instance.
+ */
+ public static final String PROP_INSTANCE = "instance";
+
+ /* XXX should not be here */
+
+ /**
+ * Constant for password based authentication plugin ID.
+ */
+ public static final String PASSWDUSERDB_PLUGIN_ID = "passwdUserDBAuthPlugin";
+
+ /**
+ * Constant for certificate based authentication plugin ID.
+ */
+ public static final String CERTUSERDB_PLUGIN_ID = "certUserDBAuthPlugin";
+
+ /**
+ * Constant for challenge based authentication plugin ID.
+ */
+ public static final String CHALLENGE_PLUGIN_ID = "challengeAuthPlugin";
+
+ /**
+ * Constant for null authentication plugin ID.
+ */
+ public static final String NULL_PLUGIN_ID = "nullAuthPlugin";
+
+ /**
+ * Constant for ssl client authentication plugin ID.
+ */
+ public static final String SSLCLIENTCERT_PLUGIN_ID = "sslClientCertAuthPlugin";
+
+ /**
+ * Constant for password based authentication manager ID.
+ */
+ public static final String PASSWDUSERDB_AUTHMGR_ID = "passwdUserDBAuthMgr";
+
+ /**
+ * Constant for certificate based authentication manager ID.
+ */
+ public static final String CERTUSERDB_AUTHMGR_ID = "certUserDBAuthMgr";
+
+ /**
+ * Constant for challenge based authentication manager ID.
+ */
+ public static final String CHALLENGE_AUTHMGR_ID = "challengeAuthMgr";
+
+ /**
+ * Constant for null authentication manager ID.
+ */
+ public static final String NULL_AUTHMGR_ID = "nullAuthMgr";
+
+ /**
+ * Constant for ssl client authentication manager ID.
+ */
+ public static final String SSLCLIENTCERT_AUTHMGR_ID = "sslClientCertAuthMgr";
+
+ /**
+ * Constant for CMC authentication plugin ID.
+ */
+ public static final String CMCAUTH_PLUGIN_ID = "CMCAuth";
+
+ /**
+ * Constant for CMC authentication manager ID.
+ */
+ public static final String CMCAUTH_AUTHMGR_ID = "CMCAuth";
+
+ /**
+ * Authenticate the given credentials using the given manager name.
+ * @param authCred The authentication credentials
+ * @param authMgrName The authentication manager name
+ * @return a authentication token.
+ * @exception EMissingCredential when missing credential during authentication
+ * @exception EInvalidCredentials when the credential is invalid
+ * @exception EBaseException If an error occurs during authentication.
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred, String authMgrName)
+ throws EMissingCredential, EInvalidCredentials, EBaseException;
+
+ /**
+ * Gets the required credential attributes for the given authentication
+ * manager.
+ * @param authMgrName The authentication manager name
+ * @return a Vector of required credential attribute names.
+ * @exception EBaseException If the required credential is missing
+ */
+ public String[] getRequiredCreds(String authMgrName) throws EBaseException;
+
+ /**
+ * Adds (registers) the given authentication manager.
+ * @param name The authentication manager name
+ * @param authMgr The authentication manager instance.
+ */
+ public void add(String name, IAuthManager authMgr);
+
+ /**
+ * Deletes (deregisters) the given authentication manager.
+ * @param name The authentication manager name to delete.
+ */
+ public void delete(String name);
+
+ /**
+ * Gets the Authentication manager instance of the specified name.
+ * @param name The authentication manager's name.
+ * @exception EBaseException when internal error occurs.
+ */
+ public IAuthManager getAuthManager(String name) throws EBaseException;
+
+ /**
+ * Gets an enumeration of authentication managers registered to the
+ * authentication subsystem.
+ * @return a list of authentication managers
+ */
+ public Enumeration getAuthManagers();
+
+ /**
+ * Gets an enumeration of authentication manager plugins.
+ * @return a list of authentication plugins
+ */
+ public Enumeration getAuthManagerPlugins();
+
+ /**
+ * Gets a single authentication manager plugin implementation
+ * @param name given authentication plugin name
+ * @return the given authentication plugin
+ */
+ public IAuthManager getAuthManagerPlugin(String name);
+
+ /**
+ * Get configuration parameters for a authentication mgr plugin.
+ * @param implName The plugin name.
+ * @return configuration parameters for the given authentication manager plugin
+ * @exception EAuthMgrPluginNotFound If the authentication manager
+ * plugin is not found.
+ * @exception EBaseException If an internal error occurred.
+ */
+ public String[] getConfigParams(String implName)
+ throws EAuthMgrPluginNotFound, EBaseException;
+
+ /**
+ * Log error message.
+ * @param level log level
+ * @param msg error message
+ */
+ public void log(int level, String msg);
+
+ /**
+ * Get a hashtable containing all authentication plugins.
+ * @return all authentication plugins.
+ */
+ public Hashtable getPlugins();
+
+ /**
+ * Get a hashtable containing all authentication instances.
+ * @return all authentication instances.
+ */
+ public Hashtable getInstances();
+
+ /**
+ * Get an authentication manager interface for the given name.
+ * @param name given authentication manager name.
+ * @return an authentication manager for the given manager name.
+ */
+ public IAuthManager get(String name);
+
+ /**
+ * Get an authentication manager plugin impl for the given name.
+ * @param name given authentication manager name.
+ * @return an authentication manager plugin
+ */
+ public AuthMgrPlugin getAuthManagerPluginImpl(String name);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
new file mode 100644
index 000000000..f8cb47ec6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
@@ -0,0 +1,208 @@
+// --- 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.certsrv.authentication;
+
+import java.util.Hashtable;
+import java.util.Date;
+import java.util.Enumeration;
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.Certificates;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateExtensions;
+
+/**
+ * AuthToken interface.
+ */
+public interface IAuthToken {
+
+ /**
+ * Constant for userid.
+ */
+ public static final String USER_ID = "userid";
+
+ /**
+ * Sets an attribute value within this AttrSet.
+ *
+ * @param name the name of the attribute
+ * @param value the attribute object.
+ * @return false on an error
+ */
+ public boolean set(String name, String value);
+
+ /**
+ * Gets an attribute value.
+ *
+ * @param name the name of the attribute to return.
+ * @exception EBaseException on attribute handling errors.
+ * @return the attribute value
+ */
+ public String getInString(String name);
+
+ /**
+ * Returns an enumeration of the names of the attributes existing within
+ * this AttrSet.
+ *
+ * @return an enumeration of the attribute names.
+ */
+ public Enumeration getElements();
+
+ /************
+ * Helpers for non-string sets and gets.
+ * These are needed because AuthToken is stored in IRequest (which can
+ * only store string values
+ */
+
+ /**
+ * Retrieves the byte array value for name. The value should have been
+ * previously stored as a byte array (it will be CMS.AtoB decoded).
+ * @param name The attribute name.
+ * @return The byte array or null on error.
+ */
+ public byte[] getInByteArray(String name);
+
+ /**
+ * Stores the byte array with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on an error
+ */
+ public boolean set(String name, byte[] value);
+
+ /**
+ * Retrieves the Integer value for name.
+ * @param name The attribute name.
+ * @return The Integer or null on error.
+ */
+ public Integer getInInteger(String name);
+
+ /**
+ * Stores the Integer with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on an error
+ */
+ public boolean set(String name, Integer value);
+
+ /**
+ * Retrieves the BigInteger array value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public BigInteger[] getInBigIntegerArray(String name);
+
+ /**
+ * Stores the BigInteger array with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on an error
+ */
+ public boolean set(String name, BigInteger[] value);
+
+ /**
+ * Retrieves the Date value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public Date getInDate(String name);
+
+ /**
+ * Stores the Date with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on an error
+ */
+ public boolean set(String name, Date value);
+
+ /**
+ * Retrieves the String array value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public String[] getInStringArray(String name);
+
+ /**
+ * Stores the String array with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return False on error.
+ */
+ public boolean set(String name, String[] value);
+
+ /**
+ * Retrieves the X509CertImpl value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public X509CertImpl getInCert(String name);
+
+ /**
+ * Stores the X509CertImpl with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on error
+ */
+ public boolean set(String name, X509CertImpl value);
+
+ /**
+ * Retrieves the CertificateExtensions value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public CertificateExtensions getInCertExts(String name);
+
+ /**
+ * Stores the CertificateExtensions with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on error
+ */
+ public boolean set(String name, CertificateExtensions value);
+
+ /**
+ * Retrieves the Certificates value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public Certificates getInCertificates(String name);
+
+ /**
+ * Stores the Certificates with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on error
+ */
+ public boolean set(String name, Certificates value);
+
+ /**
+ * Retrieves the byte[][] value for name.
+ * @param name The attribute name.
+ * @return The value or null on error.
+ */
+ public byte[][] getInByteArrayArray(String name);
+
+ /**
+ * Stores the byte[][] with the associated key.
+ * @param name The attribute name.
+ * @param value The value to store
+ * @return false on error
+ */
+ public boolean set(String name, byte[][] value);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java b/pki/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java
new file mode 100644
index 000000000..0f024ea64
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java
@@ -0,0 +1,46 @@
+// --- 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.certsrv.authentication;
+
+
+import java.security.cert.*;
+import java.util.*;
+
+
+/**
+ * This interface represents an object that captures the
+ * SSL client certificate in a SSL session. Normally, this
+ * object is a servlet.
+ * <p>
+ *
+ * This interface is used to avoid the internal imeplemtnation
+ * to have servlet (protocol handler) dependency.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISSLClientCertProvider {
+
+ /**
+ * Retrieves the SSL client certificate chain.
+ *
+ * @return certificate chain
+ */
+ public X509Certificate[] getClientCertificateChain();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java b/pki/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
new file mode 100644
index 000000000..b0806eb65
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
@@ -0,0 +1,31 @@
+// --- 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.certsrv.authentication;
+
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import java.math.*;
+
+/**
+ * Shared Token interface.
+ */
+public interface ISharedToken {
+
+ public String getSharedToken(PKIData cmcData);
+ public String getSharedToken(BigInteger serialnum);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authority/IAuthority.java b/pki/base/common/src/com/netscape/certsrv/authority/IAuthority.java
new file mode 100644
index 000000000..95fc6bf55
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authority/IAuthority.java
@@ -0,0 +1,69 @@
+// --- 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.certsrv.authority;
+
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.*;
+import netscape.security.x509.*;
+
+import java.io.*;
+
+
+/**
+ * Authority interface.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface IAuthority extends ISubsystem {
+
+ /**
+ * Retrieves the request queue for the Authority.
+ * <P>
+ * @return the request queue.
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Registers request completed class.
+ */
+ public void registerRequestListener(IRequestListener listener);
+
+ /**
+ * Registers pending request class.
+ */
+ public void registerPendingListener(IRequestListener listener);
+
+ /**
+ * log interface
+ */
+ public void log(int level, String msg);
+
+ /**
+ * nickname of signing (id) cert
+ */
+ public String getNickname();
+
+ /**
+ * return official product name.
+ */
+ public String getOfficialName();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java b/pki/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java
new file mode 100644
index 000000000..02001338b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java
@@ -0,0 +1,104 @@
+// --- 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.certsrv.authority;
+
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Authority that handles certificates needed by the cert registration
+ * servlets.
+ * <P>
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ICertAuthority extends IAuthority {
+
+ /**
+ * Retrieves the certificate repository for this authority.
+ * <P>
+ *
+ * @return the certificate repository.
+ */
+ public ICertificateRepository getCertificateRepository();
+
+ /**
+ * Returns CA's certificate chain.
+ * <P>
+ * @return the Certificate Chain for the CA.
+ */
+ public CertificateChain getCACertChain();
+
+ /**
+ * Returns CA's certificate implementaion.
+ * <P>
+ * @return CA's certificate.
+ */
+ public X509CertImpl getCACert();
+
+ /**
+ * Returns signing algorithms supported by the CA.
+ * Dependent on CA's key type and algorithms supported by security lib.
+ */
+ public String[] getCASigningAlgorithms();
+
+ /**
+ * Returns authority's X500 Name. - XXX what's this for ??
+ */
+ public X500Name getX500Name();
+
+ /**
+ * Register a request listener
+ */
+ public void registerRequestListener(IRequestListener l);
+
+ /**
+ * Remove a request listener
+ */
+ public void removeRequestListener(IRequestListener l);
+
+ /**
+ * Register a pending listener
+ */
+ public void registerPendingListener(IRequestListener l);
+
+ /**
+ * get authority's publishing module if any.
+ */
+ public IPublisherProcessor getPublisherProcessor();
+
+ /**
+ * Returns the logging interface for this authority.
+ * Using this interface both System and Audit events can be
+ * logged.
+ *
+ */
+ public ILogger getLogger();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java
new file mode 100644
index 000000000..0960311ee
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java
@@ -0,0 +1,56 @@
+// --- 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.certsrv.authorization;
+
+
+/**
+ * A class represents an authorization manager. It contains an
+ * authorization manager instance and its state (enable or not).
+ * @version $Revision$, $Date$
+ */
+public class AuthzManagerProxy {
+ private boolean mEnable;
+ private IAuthzManager mMgr;
+
+ /**
+ * Constructor
+ * @param enable true if the authzMgr is enabled; false otherwise
+ * @param mgr authorization manager instance
+ */
+ public AuthzManagerProxy(boolean enable, IAuthzManager mgr) {
+ mEnable = enable;
+ mMgr = mgr;
+ }
+
+ /**
+ * Returns the state of the authorization manager instance
+ * @return true if the state of the authorization manager instance is
+ * enabled; false otherwise.
+ */
+ public boolean isEnable() {
+ return mEnable;
+ }
+
+ /**
+ * Returns an authorization manager instance.
+ * @return an authorization manager instance
+ */
+ public IAuthzManager getAuthzManager() {
+ return mMgr;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java
new file mode 100644
index 000000000..ef8c62f8f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java
@@ -0,0 +1,80 @@
+// --- 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.certsrv.authorization;
+
+
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * This class represents a registered authorization manager plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthzMgrPlugin {
+ protected String mId = null;
+ protected String mClassPath = null;
+ protected Class mClass = null;
+ protected boolean mVisible = true;
+
+ /**
+ * Constructs a AuthzManager plugin.
+ * @param id authz manager implementation name
+ * @param classPath class path
+ */
+ public AuthzMgrPlugin(String id, String classPath) {
+ mId = id;
+ mClassPath = classPath;
+ }
+
+ /**
+ * Returns an authorization manager implementation name
+ * @return an authorization manager implementation name
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns a classpath of a AuthzManager plugin
+ * @return a classpath of a AuthzManager plugin
+ */
+ public String getClassPath() {
+ return mClassPath;
+ }
+
+ /**
+ * Returns a visibility of the plugin
+ * @return a visibility of the plugin
+ */
+ public boolean isVisible() {
+ return mVisible;
+ }
+
+ /**
+ * Sets visibility of the plugin
+ * @param visibility visibility of the plugin
+ */
+ public void setVisible(boolean visibility) {
+ mVisible = visibility;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java
new file mode 100644
index 000000000..f17038eff
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.authorization;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the authorization subsystem
+ * <P>
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthzResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ * @return the content of this resource
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * A set of constants for localized error messages.
+ */
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java
new file mode 100644
index 000000000..dc64d322a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java
@@ -0,0 +1,164 @@
+// --- 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.certsrv.authorization;
+
+
+import java.util.Hashtable;
+import java.util.Date;
+import java.util.Enumeration;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Authorization token returned by Authorization Managers.
+ * Upon return, it contains the name of the authorization manager that create
+ * the AuthzToken, the plugin name of the authorization manager, time of
+ * authorization happened, name of the resource, type of operation performed
+ * on the resource.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public class AuthzToken implements IAttrSet {
+ private Hashtable mAttrs = null;
+
+ /**
+ * Plugin name of the authorization manager that created the
+ * AuthzToken as a string.
+ */
+ public static final String TOKEN_AUTHZMGR_IMPL_NAME = "authzMgrImplName";
+
+ /**
+ * Name of the authorization manager that created the AuthzToken
+ * as a string.
+ */
+ public static final String TOKEN_AUTHZMGR_INST_NAME = "authzMgrInstName";
+
+ /**
+ * Time of authorization as a java.util.Date
+ */
+ public static final String TOKEN_AUTHZTIME = "authzTime";
+
+ /**
+ * name of the resource
+ */
+ public static final String TOKEN_AUTHZ_RESOURCE = "authzRes";
+
+ /**
+ * name of the operation
+ */
+ public static final String TOKEN_AUTHZ_OPERATION = "authzOp";
+
+ /*
+ * Status of the authorization evaluation
+ */
+ public static final String TOKEN_AUTHZ_STATUS = "status";
+
+ /**
+ * Constant for the success status of the authorization evaluation.
+ */
+ public static final String AUTHZ_STATUS_SUCCESS = "statusSuccess";
+
+ /**
+ * Constructs an instance of a authorization token.
+ * The token by default contains the following attributes: <br>
+ * <pre>
+ * "authzMgrInstName" - The authorization manager instance name.
+ * "authzMgrImplName" - The authorization manager plugin name.
+ * "authzTime" - The - The time of authorization.
+ * </pre>
+ * @param authzMgr The authorization manager that created this Token.
+ */
+ public AuthzToken(IAuthzManager authzMgr) {
+ mAttrs = new Hashtable();
+ mAttrs.put(TOKEN_AUTHZMGR_INST_NAME, authzMgr.getName());
+ mAttrs.put(TOKEN_AUTHZMGR_IMPL_NAME, authzMgr.getImplName());
+ mAttrs.put(TOKEN_AUTHZTIME, new Date());
+ }
+
+ /**
+ * Get the value of an attribute in the AuthzToken
+ * @param attrName The attribute name
+ * @return The value of attrName if any.
+ */
+ public Object get(String attrName) {
+ return mAttrs.get(attrName);
+ }
+
+ /**
+ * Used by an Authorization manager to set an attribute and value
+ * in the AuthzToken.
+ * @param attrName The name of the attribute
+ * @param value The value of the attribute to set.
+ */
+ public void set(String attrName, Object value) {
+ mAttrs.put(attrName, value);
+ }
+
+ /**
+ * Removes an attribute in the AuthzToken
+ * @param attrName The name of the attribute to remove.
+ */
+ public void delete(String attrName) {
+ mAttrs.remove(attrName);
+ }
+
+ /**
+ * Enumerate all attribute names in the AuthzToken.
+ * @return Enumeration of all attribute names in this AuthzToken.
+ */
+ public Enumeration getElements() {
+ return (mAttrs.keys());
+ }
+
+ /**
+ * Enumerate all attribute values in the AuthzToken.
+ * @return Enumeration of all attribute names in this AuthzToken.
+ */
+ public Enumeration getVals() {
+ return (mAttrs.elements());
+ }
+
+ /**
+ * Gets the name of the authorization manager instance that created
+ * this token.
+ * @return The name of the authorization manager instance that created
+ * this token.
+ */
+ public String getAuthzManagerInstName() {
+ return ((String) mAttrs.get(TOKEN_AUTHZMGR_INST_NAME));
+ }
+
+ /**
+ * Gets the plugin name of the authorization manager that created this
+ * token.
+ * @return The plugin name of the authorization manager that created this
+ * token.
+ */
+ public String getAuthzManagerImplName() {
+ return ((String) mAttrs.get(TOKEN_AUTHZMGR_IMPL_NAME));
+ }
+
+ /**
+ * Gets the time of authorization.
+ * @return The time of authorization
+ */
+ public Date getAuthzTime() {
+ return ((Date) mAttrs.get(TOKEN_AUTHZTIME));
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java
new file mode 100644
index 000000000..0284de58c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * Exception for authorization failure
+ */
+public class EAuthzAccessDenied extends EAuthzException {
+
+ /**
+ * Constructs a exception for access denied by Authz manager
+ * @param errorString Detailed error message.
+ */
+ public EAuthzAccessDenied(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java
new file mode 100644
index 000000000..4c2670b00
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java
@@ -0,0 +1,82 @@
+// --- 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.certsrv.authorization;
+
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This class represents authorization exceptions.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class EAuthzException extends EBaseException {
+
+ /**
+ * Resource class name.
+ */
+ private static final String AUTHZ_RESOURCES = AuthzResources.class.getName();
+
+ /**
+ * Constructs a authz exception
+ * <P>
+ * @param msgFormat exception details
+ */
+ public EAuthzException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a authz exception with a parameter.
+ * <p>
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EAuthzException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a authz exception with a exception parameter.
+ * <P>
+ * @param msgFormat exception details in message string format
+ * @param param system exception
+ */
+ public EAuthzException(String msgFormat, Exception param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a authz exception with a list of parameters.
+ * <P>
+ * @param msgFormat the message format.
+ * @param params list of message format parameters
+ */
+ public EAuthzException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Returns the resource bundle name
+ * @return resource bundle name
+ */
+ protected String getBundleName() {
+ return AUTHZ_RESOURCES;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java
new file mode 100644
index 000000000..52b1b9ade
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * An exception for internal error for authorization.
+ */
+public class EAuthzInternalError extends EAuthzException {
+
+ /**
+ * Constructs an authorization internal error exception
+ * @param errorString error with a detailed message.
+ */
+ public EAuthzInternalError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java
new file mode 100644
index 000000000..7bf76ba6f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * Exception for authorization manager not found.
+ */
+public class EAuthzMgrNotFound extends EAuthzException {
+
+ /**
+ * Constructs a exception for a missing required authorization manager
+ * @param errorString Detailed error message.
+ */
+ public EAuthzMgrNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java
new file mode 100644
index 000000000..b305d627b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * Exception for authorization manager plugin not found.
+ */
+public class EAuthzMgrPluginNotFound extends EAuthzException {
+
+ /**
+ * Constructs a exception for a missing authorization plugin
+ * @param errorString Detailed error message.
+ */
+ public EAuthzMgrPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java
new file mode 100644
index 000000000..99caba2be
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * Exception for operation unknown to the authorization manager
+ */
+public class EAuthzUnknownOperation extends EAuthzException {
+
+ /**
+ * Constructs a exception for an operation unknown to the authorization manager
+ * @param errorString Detailed error message.
+ */
+ public EAuthzUnknownOperation(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java
new file mode 100644
index 000000000..169ed443c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.authorization;
+
+/**
+ * Exception for protected resource unknown to the authorization manager
+ */
+public class EAuthzUnknownProtectedRes extends EAuthzException {
+
+ /**
+ * Constructs a exception for a protected resource unknown to the authorization manager
+ * @param errorString Detailed error message.
+ */
+ public EAuthzUnknownProtectedRes(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java b/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java
new file mode 100644
index 000000000..db016f248
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java
@@ -0,0 +1,169 @@
+// --- 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.certsrv.authorization;
+
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.evaluators.*;
+import java.util.*;
+
+
+/**
+ * Authorization Manager interface needs to be implemented by all
+ * authorization managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthzManager {
+
+ /**
+ * Get the name of this authorization manager instance.
+ * <p>
+ * @return String the name of this authorization manager.
+ */
+ public String getName();
+
+ /**
+ * Get implementation name of authorization manager plugin.
+ * <p>
+ * An example of an implementation name will be:
+ * <PRE>
+ * com.netscape.cms.BasicAclAuthz
+ * </PRE>
+ * <p>
+ * @return The name of the authorization manager plugin.
+ */
+ public String getImplName();
+
+ /**
+ * <code>accessInit</code> is for servlets who want to initialize their
+ * own authorization information before full operation. It is supposed
+ * to be called from the authzMgrAccessInit() method of the AuthzSubsystem.
+ * <p>
+ * The accessInfo format is determined by each individual
+ * authzmgr. For example, for BasicAclAuthz,
+ * The accessInfo is the resACLs, whose format should conform
+ * to the following:
+ * <pre>
+ * <resource ID>:right-1[,right-n]:[allow,deny](right(s))<evaluatorType>=<value>:<comment for this resource acl
+ * </pre>
+ * <P>
+ * Example:
+ * resTurnKnob:left,right:allow(left) group="lefties":door knobs for lefties
+ * @param accessInfo the access info string in the format specified in the authorization manager
+ * @exception EBaseException error parsing the accessInfo
+ */
+ public void accessInit(String accessInfo) throws EBaseException;
+
+ /**
+ * Check if the user is authorized to perform the given operation on the
+ * given resource.
+ * @param authToken the authToken associated with a user.
+ * @param resource - the protected resource name
+ * @param operation - the protected resource operation name
+ * @return authzToken if the user is authorized
+ * @exception EAuthzInternalError if an internal error occurred.
+ * @exception EAuthzAccessDenied if access denied
+ */
+ public AuthzToken authorize(IAuthToken authToken, String resource, String operation)
+ throws EAuthzInternalError, EAuthzAccessDenied;
+
+ public AuthzToken authorize(IAuthToken authToken, String expression)
+ throws EAuthzInternalError, EAuthzAccessDenied;
+
+ /**
+ * Initialize this authorization manager.
+ * @param name The name of this authorization manager instance.
+ * @param implName The name of the authorization manager plugin.
+ * @param config The configuration store for this authorization manager.
+ * @exception EBaseException If an initialization error occurred.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Prepare this authorization manager for a graceful shutdown.
+ * Called when the server is exiting for any cleanup needed.
+ */
+ public void shutdown();
+
+ /**
+ * Get configuration parameters for this implementation.
+ * The configuration parameters returned is passed to the
+ * console so configuration for instances of this
+ * implementation can be made through the console.
+ *
+ * @return a list of names for configuration parameters.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException;
+
+ /**
+ * Get the configuration store for this authorization manager.
+ * @return The configuration store of this authorization manager.
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Get ACL entries
+ * @return enumeration of ACL entries.
+ */
+ public Enumeration getACLs();
+
+ /**
+ * Get individual ACL entry for the given name of entry.
+ * @param target The name of the ACL entry
+ * @return The ACL entry.
+ */
+ public IACL getACL(String target);
+
+ /**
+ * Update ACLs in the database
+ * @param id The name of the ACL entry (ie, resource id)
+ * @param rights The allowable rights for this resource
+ * @param strACLs The value of the ACL entry
+ * @param desc The description for this resource
+ * @exception EACLsException when update fails.
+ */
+ public void updateACLs(String id, String rights, String strACLs,
+ String desc) throws EACLsException;
+
+ /**
+ * Get all registered evaluators.
+ * @return All registered evaluators.
+ */
+ public Enumeration aclEvaluatorElements();
+
+ /**
+ * Register new evaluator
+ * @param type Type of evaluator
+ * @param evaluator Value of evaluator
+ */
+ public void registerEvaluator(String type, IAccessEvaluator evaluator);
+
+ /**
+ * Return a table of evaluators
+ * @return A table of evaluators
+ */
+ public Hashtable getAccessEvaluators();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java b/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java
new file mode 100644
index 000000000..2d0f81ee8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java
@@ -0,0 +1,149 @@
+// --- 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.certsrv.authorization;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+/**
+ * An interface that represents an authorization component
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthzSubsystem extends ISubsystem {
+
+ /**
+ * Constant for auths.
+ */
+ public static final String ID = "authz";
+
+ /**
+ * Constant for class.
+ */
+ public static final String PROP_CLASS = "class";
+
+ /**
+ * Constant for impl
+ */
+ public static final String PROP_IMPL = "impl";
+
+ /**
+ * Constant for pluginName.
+ */
+ public static final String PROP_PLUGIN = "pluginName";
+
+ /**
+ * Constant for instance.
+ */
+ public static final String PROP_INSTANCE = "instance";
+
+ /**
+ * authorize the user associated with the given authToken for a given
+ * operation with the given authorization manager name
+ * @param authzMgrName The authorization manager name
+ * @param authToken the authenticaton token associated with a user
+ * @param resource the resource protected by the authorization system
+ * @param operation the operation for resource protected by the authorization system
+ * @return a authorization token.
+ * @exception EBaseException If an error occurs during authorization.
+ */
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String resource, String operation)
+ throws EBaseException;
+
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String exp) throws EBaseException;
+
+ /**
+ * Adds (registers) the given authorization manager.
+ * @param name The authorization manager name
+ * @param authzMgr The authorization manager instance.
+ */
+ public void add(String name, IAuthzManager authzMgr);
+
+ /**
+ * Deletes (deregisters) the given authorization manager.
+ * @param name The authorization manager name to delete.
+ */
+ public void delete(String name);
+
+ /**
+ * Gets the Authorization manager instance of the specified name.
+ * @param name The authorization manager's name.
+ * @return an authorization manager interface
+ */
+ public IAuthzManager getAuthzManager(String name) throws EBaseException;
+
+ /**
+ * Gets an enumeration of authorization managers registered to the
+ * authorization component.
+ * @return a list of authorization managers
+ */
+ public Enumeration getAuthzManagers();
+
+ /**
+ * Initialize authz info - usually used for BasicAclAuthz
+ *
+ * @param authzMgrName name of the authorization manager
+ * @param accessInfo string representation of the ACL
+ * @exception EBaseException if authorization manager is not found
+ */
+ public void authzMgrAccessInit(String authzMgrName, String accessInfo) throws EBaseException;
+
+ /**
+ * Gets an enumeration of authorization manager plugins.
+ * @return list of authorization manager plugins
+ */
+ public Enumeration getAuthzManagerPlugins();
+
+ /**
+ * Gets a single authorization manager plugin implementation
+ * @param name given authorization plugin name
+ * @return authorization manager plugin
+ */
+ public IAuthzManager getAuthzManagerPlugin(String name);
+
+ /**
+ * Log error message.
+ * @param level log level
+ * @param msg error message
+ */
+ public void log(int level, String msg);
+
+ /**
+ * Get a hashtable containing all authentication plugins.
+ * @return all authentication plugins.
+ */
+ public Hashtable getPlugins();
+
+ /**
+ * Get a hashtable containing all authentication instances.
+ * @return all authentication instances.
+ */
+ public Hashtable getInstances();
+
+ /**
+ * Get an authorization manager interface for the given name.
+ * @param name given authorization manager name.
+ * @return an authorization manager interface
+ */
+ public IAuthzManager get(String name);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ASubsystem.java b/pki/base/common/src/com/netscape/certsrv/base/ASubsystem.java
new file mode 100644
index 000000000..ea3342308
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ASubsystem.java
@@ -0,0 +1,71 @@
+// --- 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.certsrv.base;
+
+
+/**
+ * This class represents a basic subsystem. Each basic
+ * subsystem is named with an identifier and has a
+ * configuration store.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class ASubsystem implements ISubsystem {
+
+ private ISubsystem mParent;
+ private IConfigStore mCfg;
+ private String mId;
+
+ /**
+ * Initializes this subsystem.
+ *
+ * @param parent parent subsystem
+ * @param cfg configuration store
+ */
+ public void init(ISubsystem parent, IConfigStore cfg) {
+ mParent = parent;
+ mCfg = cfg;
+ }
+
+ /**
+ * Retrieves the configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mCfg;
+ }
+
+ /**
+ * Sets the identifier of this subsystem.
+ *
+ * @param id subsystem identifier
+ */
+ public void setId(String id) {
+ mId = id;
+ }
+
+ /**
+ * Retrieves the subsystem identifier.
+ *
+ * @return subsystem identifier
+ */
+ public String getId() {
+ return mId;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java b/pki/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java
new file mode 100644
index 000000000..786148a0e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java
@@ -0,0 +1,70 @@
+// --- 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.certsrv.base;
+
+
+/**
+ * AttributeNameHelper. This Helper class used to decompose
+ * dot-separated attribute name into prefix and suffix.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AttributeNameHelper {
+ // Public members
+ private static final char SEPARATOR = '.';
+
+ // Private data members
+ private String prefix = null;
+ private String suffix = null;
+
+ /**
+ * Default constructor for the class. Name is of the form
+ * "proofOfPosession.type".
+ *
+ * @param name the attribute name.
+ */
+ public AttributeNameHelper(String name) {
+ int i = name.indexOf(SEPARATOR);
+
+ if (i == (-1)) {
+ prefix = name;
+ } else {
+ prefix = name.substring(0, i);
+ suffix = name.substring(i + 1);
+ }
+ }
+
+ /**
+ * Return the prefix of the name.
+ *
+ * @return attribute prefix
+ */
+ public String getPrefix() {
+ return (prefix);
+ }
+
+ /**
+ * Return the suffix of the name.
+ *
+ * @return attribute suffix
+ */
+ public String getSuffix() {
+ return (suffix);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/BaseResources.java b/pki/base/common/src/com/netscape/certsrv/base/BaseResources.java
new file mode 100644
index 000000000..f8a69f65d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/BaseResources.java
@@ -0,0 +1,47 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the entire
+ * system.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class BaseResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /*
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/EBaseException.java b/pki/base/common/src/com/netscape/certsrv/base/EBaseException.java
new file mode 100644
index 000000000..50ea8fdc7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/EBaseException.java
@@ -0,0 +1,150 @@
+// --- 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.certsrv.base;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.reflect.*;
+
+
+/**
+ * An exception with localizable error messages. It is the
+ * base class for all exceptions in certificate server.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see com.netscape.certsrv.base.BaseResources
+ */
+public class EBaseException extends Exception {
+
+ /**
+ * The resource bundle to use for error messages.
+ * Subclasses can override to use its own resource bundle.
+ */
+ private static final String BASE_RESOURCES = BaseResources.class.getName();
+
+ /**
+ * Parameters to the exception error message.
+ */
+ public Object mParams[] = null;
+
+ /**
+ * Constructs an instance of this exception with the given resource key.
+ * If resource key is not found in the resource bundle, the resource key
+ * specified is used as the error message.
+ * <pre>
+ * new EBaseException(BaseResources.PERMISSION_DENIED);
+ * new EBaseException("An plain error message");
+ * <P>
+ * @param msgFormat The error message resource key.
+ */
+ public EBaseException(String msgFormat) {
+ super(msgFormat);
+ mParams = null;
+ }
+
+ /**
+ * Constructs an instance of this exception with the given resource key
+ * and a parameter as a string.
+ * <PRE>
+ * new EBaseException(BaseResource.NO_CONFIG_FILE, fileName);
+ * </PRE>
+ * <P>
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EBaseException(String msgFormat, String param) {
+ super(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs an instance of the exception given the resource key and
+ * a exception parameter.
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * throw new EBaseException(BaseResources.INTERNAL_ERROR_1, e);
+ * }
+ * </PRE>
+ * <P>
+ * @param msgFormat The resource key
+ * @param param The parameter as an exception
+ */
+ public EBaseException(String msgFormat, Exception param) {
+ super(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs an instance of this exception given the resource key and
+ * an array of parameters.
+ * <P>
+ * @param msgFormat The resource key
+ * @param params Array of params
+ */
+ public EBaseException(String msgFormat, Object params[]) {
+ super(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns the list of parameters.
+ * <P>
+ *
+ * @return List of parameters.
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns the exception string in the default locale.
+ * <P>
+ * @return The exception string in the default locale.
+ */
+ public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the exception string in the given locale.
+ * <P>
+ * @param locale The locale
+ * @return The exception string in the given locale.
+ */
+ public String toString(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ super.getMessage(), mParams);
+ }
+
+ /**
+ * Returns the given resource bundle name.
+ * @return the name of the resource bundle for this class.
+ */
+ protected String getBundleName() {
+ return BASE_RESOURCES;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java b/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java
new file mode 100644
index 000000000..57385d700
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.base;
+
+
+/**
+ * This class represents an exception thrown when a
+ * property is not defined (empty string) the configuration store.
+ * It extends EBaseException and uses the same resource bundle.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.base.EBaseException
+ */
+public class EPropertyNotDefined extends EBaseException {
+
+ /**
+ * Constructs an instance of this exception given the name of the
+ * property that's not found.
+ * <p>
+ * @param errorString Detailed error message.
+ */
+ public EPropertyNotDefined(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java b/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java
new file mode 100644
index 000000000..a0f4ed93b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.base;
+
+
+/**
+ * This class represents an exception thrown when a
+ * property is not found in the configuration store.
+ * It extends EBaseException and uses the same resource bundle.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.base.EBaseException
+ */
+public class EPropertyNotFound extends EBaseException {
+
+ /**
+ * Constructs an instance of this exception given the name of the
+ * property that's not found.
+ * <p>
+ * @param errorString Detailed error message.
+ */
+ public EPropertyNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java b/pki/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java
new file mode 100644
index 000000000..b74131a68
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java
@@ -0,0 +1,91 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * Plugin which can return extended information to console
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtendedPluginInfo implements IExtendedPluginInfo {
+
+ private String _epi[] = null;
+
+ /**
+ * Constructs an extended plugin info object.
+ *
+ * @param epi plugin info list
+ */
+ public ExtendedPluginInfo(String epi[]) {
+ _epi = epi;
+ }
+
+ /**
+ * This method returns an array of strings. Each element of the
+ * array represents a configurable parameter, or some other
+ * meta-info (such as help-token)
+ *
+ * there is an entry indexed on that parameter name
+ * <param-name>;<type_info>[,required];<description>;...
+ *
+ * Where:
+ *
+ * type_info is either 'string', 'number', 'boolean', 'password' or
+ * 'choice(ch1,ch2,ch3,...)'
+ *
+ * If the marker 'required' is included after the type_info,
+ * the parameter will has some visually distinctive marking in
+ * the UI.
+ *
+ * 'description' is a short sentence describing the parameter
+ * 'choice' is rendered as a drop-down list. The first parameter in the
+ * list will be activated by default
+ * 'boolean' is rendered as a checkbox. The resulting parameter will be
+ * either 'true' or 'false'
+ * 'string' allows any characters
+ * 'number' allows only numbers
+ * 'password' is rendered as a password field (the characters are replaced
+ * with *'s when being types. This parameter is not passed through to
+ * the plugin. It is instead inserted directly into the password cache
+ * keyed on the instance name. The value of the parameter
+ * 'bindPWPrompt' (see example below) is set to the key.
+ *
+ * In addition to the configurable parameters, the following magic parameters
+ * may be defined:
+ *
+ * HELP_TOKEN;helptoken - a pointer to the online manual section for this plugin
+ * HELP_TEXT;helptext - a general help string describing the plugin
+ *
+ * For example:
+ * "username;string;The username you wish to login as"
+ * "bindPWPrompt;password;Enter password to bind as above user with"
+ * "algorithm;choice(RSA,DSA);Which algorithm do you want to use"
+ * "enable;boolean;Do you want to run this plugin"
+ * "port;number;Which port number do you want to use"
+ *
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return _epi;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IArgBlock.java b/pki/base/common/src/com/netscape/certsrv/base/IArgBlock.java
new file mode 100644
index 000000000..835ad0ed1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IArgBlock.java
@@ -0,0 +1,285 @@
+// --- 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.certsrv.base;
+
+import java.util.*;
+import java.io.*;
+import netscape.security.pkcs.*;
+import java.security.*;
+import java.math.BigInteger;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.BaseResources;
+
+
+/**
+ * This interface defines the abstraction for the generic collection
+ * of attributes indexed by string names.
+ * Set of cooperating implementations of this interface may exploit
+ * dot-separated attribute names to provide seamless access to the
+ * attributes of attribute value which also implements AttrSet
+ * interface as if it was direct attribute of the container
+ * E.g., ((AttrSet)container.get("x")).get("y") is equivalent to
+ * container.get("x.y");
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ **/
+public interface IArgBlock extends Serializable {
+
+ /**
+ * Checks if this argument block contains the given key.
+ *
+ * @param n key
+ * @return true if key is present
+ */
+ public boolean isValuePresent(String n);
+ /**
+ * Adds string-based value into this argument block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addStringValue(String n, String v);
+
+ /**
+ * Retrieves argument value as string.
+ *
+ * @param n key
+ * @return argument value as string
+ * @exception EBaseException failed to retrieve value
+ */
+ public String getValueAsString(String n) throws EBaseException;
+
+ /**
+ * Retrieves argument value as string.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as string
+ */
+ public String getValueAsString(String n, String def);
+
+ /**
+ * Retrieves argument value as integer.
+ *
+ * @param n key
+ * @return argument value as int
+ * @exception EBaseException failed to retrieve value
+ */
+ public int getValueAsInt(String n) throws EBaseException;
+
+ /**
+ * Retrieves argument value as integer.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as int
+ */
+ public int getValueAsInt(String n, int def);
+
+ /**
+ * Retrieves argument value as big integer.
+ *
+ * @param n key
+ * @return argument value as big integer
+ * @exception EBaseException failed to retrieve value
+ */
+ public BigInteger getValueAsBigInteger(String n) throws EBaseException;
+
+ /**
+ * Retrieves argument value as big integer.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as big integer
+ */
+ public BigInteger getValueAsBigInteger(String n, BigInteger def);
+
+ /**
+ * Retrieves argument value as object
+ *
+ * @param n key
+ * @return argument value as object
+ * @exception EBaseException failed to retrieve value
+ */
+ public Object getValue(Object n) throws EBaseException;
+
+ /**
+ * Retrieves argument value as object
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as object
+ */
+ public Object getValue(Object n, Object def);
+
+ /**
+ * Gets boolean value. They should be "true" or "false".
+ *
+ * @param name name of the input type
+ * @return boolean type: <code>true</code> or <code>false</code>
+ * @exception EBaseException failed to retrieve value
+ */
+ public boolean getValueAsBoolean(String name) throws EBaseException;
+
+ /**
+ * Gets boolean value. They should be "true" or "false".
+ *
+ * @param name name of the input type
+ * @param def Default value to return.
+ * @return boolean type: <code>true</code> or <code>false</code>
+ */
+ public boolean getValueAsBoolean(String name, boolean def);
+
+ /**
+ * Gets KeyGenInfo
+ *
+ * @param name name of the input type
+ * @param def default value to return
+ * @exception EBaseException On error.
+ * @return KeyGenInfo object
+ */
+ public KeyGenInfo getValueAsKeyGenInfo(String name, KeyGenInfo def) throws EBaseException;
+
+ /**
+ * Gets PKCS10 request. This pkcs10 attribute does not
+ * contain header information.
+ *
+ * @param name name of the input type
+ * @return pkcs10 request
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsRawPKCS10(String name) throws EBaseException;
+
+ /**
+ * Gets PKCS10 request. This pkcs10 attribute does not
+ * contain header information.
+ *
+ * @param name name of the input type
+ * @param def default PKCS10
+ * @return pkcs10 request
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsRawPKCS10(String name, PKCS10 def) throws EBaseException;
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param checkheader true if header must be present
+ * @return PKCS10 object
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsPKCS10(String name, boolean checkheader) throws EBaseException;
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param checkheader true if header must be present
+ * @param def default PKCS10
+ * @return PKCS10 object
+ * @exception EBaseException on error
+ */
+ public PKCS10 getValueAsPKCS10(String name, boolean checkheader, PKCS10 def) throws EBaseException;
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param def default PKCS10
+ * @return PKCS10 object
+ * @exception EBaseException on error
+ */
+ public PKCS10 getValuePKCS10(String name, PKCS10 def) throws EBaseException;
+
+ /**
+ * Retrieves a list of argument keys.
+ *
+ * @return a list of string-based keys
+ */
+ public Enumeration elements();
+
+ /**
+ * Adds long-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addLongValue(String n, long v);
+
+ /**
+ * Adds integer-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addIntegerValue(String n, int v);
+
+ /**
+ * Adds boolean-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addBooleanValue(String n, boolean v);
+
+ /**
+ * Adds integer-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @param radix radix
+ * @return value
+ */
+ public Object addBigIntegerValue(String n, BigInteger v, int radix);
+
+ /**
+ * Sets argument into this block.
+ *
+ * @param name key
+ * @param obj value
+ */
+ public void set(String name, Object obj);
+
+ /**
+ * Retrieves argument.
+ *
+ * @param name key
+ * @return object value
+ */
+ public Object get(String name);
+
+ /**
+ * Deletes argument by the given key.
+ *
+ * @param name key
+ */
+ public void delete(String name);
+
+ /**
+ * Retrieves a list of argument keys.
+ *
+ * @return a list of string-based keys
+ */
+ public Enumeration getElements();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IAttrSet.java b/pki/base/common/src/com/netscape/certsrv/base/IAttrSet.java
new file mode 100644
index 000000000..4e8b0205d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IAttrSet.java
@@ -0,0 +1,72 @@
+// --- 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.certsrv.base;
+
+
+import java.io.Serializable;
+import java.util.Enumeration;
+
+
+/**
+ * This interface defines the abstraction for the generic collection
+ * of attributes indexed by string names.
+ * Set of cooperating implementations of this interface may exploit
+ * dot-separated attribute names to provide seamless access to the
+ * attributes of attribute value which also implements AttrSet
+ * interface as if it was direct attribute of the container
+ * E.g., ((AttrSet)container.get("x")).get("y") is equivalent to
+ * container.get("x.y");
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ **/
+public interface IAttrSet extends Serializable {
+
+ /**
+ * Sets an attribute value within this AttrSet.
+ *
+ * @param name the name of the attribute
+ * @param obj the attribute object.
+ * @exception EBaseException on attribute handling errors.
+ */
+ public void set(String name, Object obj)throws EBaseException;
+
+ /**
+ * Gets an attribute value.
+ *
+ * @param name the name of the attribute to return.
+ * @exception EBaseException on attribute handling errors.
+ */
+ public Object get(String name) throws EBaseException;
+
+ /**
+ * Deletes an attribute value from this AttrSet.
+ *
+ * @param name the name of the attribute to delete.
+ * @exception EBaseException on attribute handling errors.
+ */
+ public void delete(String name) throws EBaseException;
+
+ /**
+ * Returns an enumeration of the names of the attributes existing within
+ * this AttrSet.
+ *
+ * @return an enumeration of the attribute names.
+ */
+ public Enumeration getElements();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IAuthInfo.java b/pki/base/common/src/com/netscape/certsrv/base/IAuthInfo.java
new file mode 100644
index 000000000..2006c8f23
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IAuthInfo.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+import java.security.*;
+
+
+/**
+ * An interface represents an authentication context. This
+ * is an entity that encapsulates the authentication
+ * information of a service requestor. For example, CMS
+ * user needs to authenticate to CMS using SSL. The
+ * client certificate is expressed in authenticated context.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthInfo {
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java b/pki/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java
new file mode 100644
index 000000000..902c0aad3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * This interface represents a CRL pretty print handler.
+ * It converts a CRL object into a printable CRL string.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICRLPrettyPrint {
+
+ /**
+ * Retrieves the printable CRL string.
+ *
+ * @param clientLocale end user clocale
+ * @param crlSize CRL size
+ * @param pageStart starting page number
+ * @param pageSize page size in rows
+ * @return printable CRL string
+ */
+ public String toString(Locale clientLocale, long crlSize, long pageStart, long pageSize);
+
+ /**
+ * Retrieves the printable CRL string.
+ *
+ * @param clientLocale end user clocale
+ * @return printable CRL string
+ */
+ public String toString(Locale clientLocale);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java b/pki/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java
new file mode 100644
index 000000000..dc3186497
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java
@@ -0,0 +1,40 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * This interface represents a certificate pretty print
+ * handler. This handler converts certificate object into
+ * a printable certificate string.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertPrettyPrint {
+
+ /**
+ * Returns printable certificate string.
+ *
+ * @param clientLocale end user locale
+ * @return printable certificate string
+ */
+ public String toString(Locale clientLocale);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IConfigStore.java b/pki/base/common/src/com/netscape/certsrv/base/IConfigStore.java
new file mode 100644
index 000000000..b53e7c66f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IConfigStore.java
@@ -0,0 +1,276 @@
+// --- 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.certsrv.base;
+
+
+import java.util.Enumeration;
+import java.math.BigInteger;
+
+
+/**
+ * An interface represents a configuration store.
+ * A configuration store is an abstraction of a hierarchical store
+ * to keep arbitrary data indexed by string names.<p>
+ * In the following example:
+ * <pre>
+ * param1=value1
+ * configStore1.param11=value11
+ * configStore1.param12=value12
+ * configStore1.subStore1.param111=value111
+ * configStore1.subStore1.param112=value112
+ * configStore2.param21=value21
+ * </pre>
+ * The top config store has parameters <i>param1</i> and sub-stores
+ * <i>configStore1</i> and <i>configStore2</i>. <br>
+ * The following illustrates how a config store is used.
+ * <pre>
+ * // the top config store is passed to the following method.
+ * public void init(IConfigStore config) throws EBaseException {
+ * IConfigStore store = config;
+ * String valx = config.getString("param1");
+ * // valx is "value1" <p>
+ *
+ * IConfigStore substore1 = config.getSubstore("configStore1");
+ * String valy = substore1.getString("param11");
+ * // valy is "value11" <p>
+ *
+ * IConfigStore substore2 = config.getSubstore("configStore2");
+ * String valz = substore2.getString("param21");
+ * // valz is "value21" <p>
+ * }
+ * </pre>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConfigStore extends ISourceConfigStore {
+
+ /**
+ * Gets the name of this Configuration Store.
+ * <P>
+ * @return The name of this Configuration store
+ */
+ public String getName();
+
+ /**
+ * Retrieves the value of the given property as a string.
+ * <p>
+ * @param name The name of the property to get
+ * @return The value of the property as a String
+ * @exception EPropertyNotFound If the property is not present
+ * @exception EBaseException If an internal error occurred
+ */
+ public String getString(String name)
+ throws EPropertyNotFound, EBaseException;
+
+ /**
+ * Retrieves the value of a given property as a string or the
+ * given default value if the property is not present.
+ * <P>
+ * @param name The property to retrive
+ * @param defval The default value to return if the property is not present
+ * @return The roperty value as a string
+ * @exception EBaseException If an internal error occurred
+ */
+ public String getString(String name, String defval)
+ throws EBaseException;
+
+ /**
+ * Stores a property and its value as a string.
+ * <p>
+ * @param name The name of the property
+ * @param value The value as a string
+ */
+ public void putString(String name, String value);
+
+ /**
+ * Retrieves the value of a property as a byte array.
+ * <P>
+ * @param name The property name
+ * @return The property value as a byte array
+ * @exception EPropertyNotFound If the property is not present
+ * @exception EBaseException If an internal error occurred
+ */
+ public byte[] getByteArray(String name)
+ throws EPropertyNotFound, EBaseException;
+
+ /**
+ * Retrieves the value of a property as a byte array, using the
+ * given default value if property is not present.
+ * <P>
+ * @param name The name of the property
+ * @param defval The default value if the property is not present.
+ * @return The property value as a byte array.
+ * @exception EBaseException If an internal error occurred
+ */
+ public byte[] getByteArray(String name, byte defval[])
+ throws EBaseException;
+
+ /**
+ * Stores the given property and value as a byte array.
+ * <p>
+ * @param name The property name
+ * @param value The value as a byte array to store
+ */
+ public void putByteArray(String name, byte value[]);
+
+ /**
+ * Retrieves the given property as a boolean.
+ * <P>
+ * @param name The name of the property as a string.
+ * @return The value of the property as a boolean.
+ * @exception EPropertyNotFound If the property is not present
+ * @exception EBaseException If an internal error occurred
+ */
+ public boolean getBoolean(String name)
+ throws EPropertyNotFound, EBaseException;
+
+ /**
+ * Retrieves the given property as a boolean.
+ * <P>
+ * @param name The name of the property
+ * @param defval The default value to turn as a boolean if
+ * property is not present
+ * @return The value of the property as a boolean.
+ * @exception EBaseException If an internal error occurred
+ */
+ public boolean getBoolean(String name, boolean defval)
+ throws EBaseException;
+
+ /**
+ * Stores the given property and its value as a boolean.
+ * <P>
+ * @param name The property name
+ * @param value The value as a boolean
+ */
+ public void putBoolean(String name, boolean value);
+
+ /**
+ * Retrieves the given property as an integer.
+ * <P>
+ * @param name The property name
+ * @return The property value as an integer
+ * @exception EPropertyNotFound If property is not found
+ * @exception EBaseException If an internal error occurred
+ */
+ public int getInteger(String name)
+ throws EPropertyNotFound, EBaseException;
+
+ /**
+ * Retrieves the given property as an integer.
+ * <P>
+ * @param name The property name
+ * @return int The default value to return as an integer
+ * @exception EBaseException If the value cannot be converted to a
+ * integer
+ */
+ public int getInteger(String name, int defval)
+ throws EBaseException;
+
+ /**
+ * Sets a property and its value as an integer.
+ * <P>
+ * @param name parameter name
+ * @param value integer value
+ */
+ public void putInteger(String name, int value);
+
+ /**
+ * Retrieves the given property as a big integer.
+ * <P>
+ * @param name The property name
+ * @return The property value as a big integer
+ * @exception EPropertyNotFound If property is not found
+ * @exception EBaseException If an internal error occurred
+ */
+ public BigInteger getBigInteger(String name)
+ throws EPropertyNotFound, EBaseException;
+
+ /**
+ * Retrieves the given property as a big integer.
+ * <P>
+ * @param name The property name
+ * @return int The default value to return as a big integer
+ * @exception EBaseException If the value cannot be converted to a
+ * integer
+ */
+ public BigInteger getBigInteger(String name, BigInteger defval)
+ throws EBaseException;
+
+ /**
+ * Sets a property and its value as an integer.
+ * <P>
+ * @param name parameter name
+ * @param value big integer value
+ */
+ public void putBigInteger(String name, BigInteger value);
+
+ /**
+ * Creates a nested sub-store with the specified name.
+ * <P>
+ * @param name The name of the sub-store
+ * @return The sub-store created
+ */
+ public IConfigStore makeSubStore(String name);
+
+ /**
+ * Retrieves the given sub-store.
+ * <P>
+ * @param name The name of the sub-store
+ * @return The sub-store
+ */
+ public IConfigStore getSubStore(String name);
+
+ /**
+ * Removes sub-store with the given name.
+ * (Removes all properties and sub-stores under this sub-store.)
+ * <P>
+ * @param name The name of the sub-store to remove
+ */
+ public void removeSubStore(String name);
+
+ public void remove(String name);
+
+ /**
+ * Retrives and enumeration of all properties in this config-store.
+ * @return An enumeration of all properties in this config-store
+ */
+ public Enumeration getPropertyNames();
+
+ /**
+ * Returns an enumeration of the names of the substores of
+ * this config-store.
+ * <P>
+ * @return An enumeration of the names of the sub-stores of this
+ * config-store
+ */
+ public Enumeration getSubStoreNames();
+
+ /**
+ * Commits all the data into file immediately.
+ *
+ * @param createBackup true if a backup file should be created
+ * @exception EBaseException failed to commit
+ */
+ public void commit(boolean createBackup) throws EBaseException;
+
+ /**
+ * Return the number of items in this substore
+ */
+ public int size();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java b/pki/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java
new file mode 100644
index 000000000..f2b6a03d4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.base;
+
+
+import java.util.Hashtable;
+
+
+/**
+ * ConfigStore Parameters Event Notification.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConfigStoreEventListener {
+
+ /**
+ * Called to validate the config store parameters that changed
+ *
+ * @param action action
+ * @param params configuration parameters changed
+ * @exception EBaseException failed to validate
+ */
+ public void validateConfigParams(String action,
+ Hashtable params) throws EBaseException;
+
+ /**
+ * Validates the config store parameters that changed
+ *
+ * @param action action
+ * @param params configuration parameters changed
+ * @exception EBaseException failed to validate
+ */
+ public void doConfigParams(String action,
+ Hashtable params) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java b/pki/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java
new file mode 100644
index 000000000..00f9c8460
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.base;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.math.BigInteger;
+import java.security.cert.*;
+import java.security.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IExtPrettyPrint {
+
+ /**
+ * Retrieves the printable extension string.
+ *
+ * @return printable extension string
+ */
+ public String toString();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java b/pki/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java
new file mode 100644
index 000000000..ac98c6c36
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java
@@ -0,0 +1,84 @@
+// --- 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.certsrv.base;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * Plugin which can return extended information to console
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IExtendedPluginInfo {
+
+ public static final String HELP_TOKEN = "HELP_TOKEN";
+ public static final String HELP_TEXT = "HELP_TEXT";
+
+ /**
+ * This method returns an array of strings. Each element of the
+ * array represents a configurable parameter, or some other
+ * meta-info (such as help-token)
+ *
+ * there is an entry indexed on that parameter name
+ * <param-name>;<type_info>[,required];<description>;...
+ *
+ * Where:
+ *
+ * type_info is either 'string', 'number', 'boolean', 'password' or
+ * 'choice(ch1,ch2,ch3,...)'
+ *
+ * If the marker 'required' is included after the type_info,
+ * the parameter will has some visually distinctive marking in
+ * the UI.
+ *
+ * 'description' is a short sentence describing the parameter
+ * 'choice' is rendered as a drop-down list. The first parameter in the
+ * list will be activated by default
+ * 'boolean' is rendered as a checkbox. The resulting parameter will be
+ * either 'true' or 'false'
+ * 'string' allows any characters
+ * 'number' allows only numbers
+ * 'password' is rendered as a password field (the characters are replaced
+ * with *'s when being types. This parameter is not passed through to
+ * the plugin. It is instead inserted directly into the password cache
+ * keyed on the instance name. The value of the parameter
+ * 'bindPWPrompt' (see example below) is set to the key.
+ *
+ * In addition to the configurable parameters, the following magic parameters
+ * may be defined:
+ *
+ * HELP_TOKEN;helptoken - a pointer to the online manual section for this plugin
+ * HELP_TEXT;helptext - a general help string describing the plugin
+ *
+ * For example:
+ * "username;string;The username you wish to login as"
+ * "bindPWPrompt;password;Enter password to bind as above user with"
+ * "algorithm;choice(RSA,DSA);Which algorithm do you want to use"
+ * "enable;boolean;Do you want to run this plugin"
+ * "port;number;Which port number do you want to use"
+ *
+ */
+ public String[] getExtendedPluginInfo(Locale locale);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IPluginImpl.java b/pki/base/common/src/com/netscape/certsrv/base/IPluginImpl.java
new file mode 100644
index 000000000..a32dfc2ea
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IPluginImpl.java
@@ -0,0 +1,107 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+/**
+ * This interface represents a plugin instance.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPluginImpl {
+
+ public static final String PROP_IMPLNAME = "implName";
+
+ /**
+ * Gets the description for this plugin instance.
+ * <P>
+ * @return The Description for this plugin instance.
+ */
+ public String getDescription();
+
+ /**
+ * Returns the name of the plugin class.
+ * <P>
+ *
+ * @return The name of the plugin class.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the name of the plugin instance.
+ * <P>
+ *
+ * @return The name of the plugin instance. If none is set
+ * the name of the implementation will be returned.xxxx
+ */
+ public String getInstanceName();
+
+ /**
+ * Initializes this plugin instance.
+ *
+ * @param sys parent subsystem
+ * @param instanceName instance name of this plugin
+ * @param className class name of this plugin
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem sys, String instanceName, String className,
+ IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Shutdowns this plugin.
+ */
+ public void shutdown();
+
+ /**
+ * Retrieves the configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Return configured parameters for a plugin instance.
+ *
+ * @return nvPairs A Vector of name/value pairs. Each name/value
+ * pair is constructed as a String in name=value format.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * Retrieves a list of configuration parameter names.
+ *
+ * @return a list of parameter names
+ */
+ public String[] getConfigParams();
+
+ /**
+ * Return default parameters for a plugin implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs. Each name/value
+ * pair is constructed as a String in name=value.
+ */
+ public Vector getDefaultParams();
+
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java b/pki/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java
new file mode 100644
index 000000000..4c9626806
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java
@@ -0,0 +1,72 @@
+// --- 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.certsrv.base;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPrettyPrintFormat {
+
+ /**
+ * Retrieves a pretty print string of the given byte array.
+ *
+ * @param in byte array
+ * @param indentSize indentation size
+ * @param lineLen length of line
+ * @param separator separator string
+ * @return pretty print string
+ */
+ public String toHexString(byte[] in, int indentSize,
+ int lineLen, String separator);
+
+ /**
+ * Retrieves a pretty print string of the given byte array.
+ *
+ * @param in byte array
+ * @param indentSize indentation size
+ * @param lineLen length of line
+ * @return pretty print string
+ */
+ public String toHexString(byte[] in, int indentSize, int lineLen);
+
+ /**
+ * Retrieves a pretty print string of the given byte array.
+ *
+ * @param in byte array
+ * @param indentSize indentation size
+ * @return pretty print string
+ */
+ public String toHexString(byte[] in, int indentSize);
+
+ /**
+ * Retrieves a pretty print string of the given byte array.
+ *
+ * @param in byte array
+ * @return pretty print string
+ */
+ public String toHexString(byte[] in);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java b/pki/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java
new file mode 100644
index 000000000..64aad508f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java
@@ -0,0 +1,40 @@
+// --- 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.certsrv.base;
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.BaseResources;
+
+
+/**
+ * This interface defines the abstraction for the cookie table.
+ **/
+public interface ISecurityDomainSessionTable {
+ public void addEntry(String cookieId, String ip, String uid, String group);
+ public void removeEntry(String sessionId);
+ public boolean isSessionIdExist(String sessionId);
+ public String getIP(String sessionId);
+ public String getUID(String sessionId);
+ public String getGroup(String sessionId);
+ public long getBeginTime(String sessionId);
+ public int getSize();
+ public long getTimeToLive();
+ public Enumeration getSessionIds();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java b/pki/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java
new file mode 100644
index 000000000..7a500bde6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java
@@ -0,0 +1,82 @@
+// --- 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.certsrv.base;
+
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+
+/**
+ * An interface that represents the source that creates the configuration
+ * store tree. Note that the tree can be built based on the information
+ * from a text file or ldap entries.
+ * @see com.netscape.certsrv.base.IConfigStore
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISourceConfigStore extends Serializable {
+
+ /**
+ * Gets a property.
+ * <P>
+ *
+ * @param name The property name
+ * @return property value
+ */
+ public Object get(String name);
+
+ /**
+ * Retrieves a property.
+ * <P>
+ *
+ * @param name The property name
+ * @param value The property value
+ */
+ public void put(String name, Object value);
+
+ /**
+ * Returns an enumeration of the config store's keys.
+ * <P>
+ *
+ * @return a list of keys
+ * @see java.util.Hashtable#elements
+ * @see java.util.Enumeration
+ */
+ public Enumeration keys();
+
+ /**
+ * Reads a config store from an input stream.
+ *
+ * @param in input stream where the properties are located
+ * @exception IOException If an IO error occurs while loading from input.
+ */
+ public void load(InputStream in) throws IOException;
+
+ /**
+ * Stores this config store to the specified output stream.
+ *
+ * @param out output stream where the properties should be serialized
+ * @param header optional header to be serialized
+ */
+ public void save(OutputStream out, String header);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ISubsystem.java b/pki/base/common/src/com/netscape/certsrv/base/ISubsystem.java
new file mode 100644
index 000000000..d23895088
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ISubsystem.java
@@ -0,0 +1,82 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * An interface represents a CMS subsystem. CMS is made up of a list
+ * subsystems. Each subsystem is responsible for a set of
+ * speciailized functions.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISubsystem {
+
+ /**
+ * Retrieves the name of this subsystem.
+ *
+ * @return subsystem identifier
+ */
+ public String getId();
+
+ /**
+ * Sets specific to this subsystem.
+ *
+ * @param id subsystem identifier
+ * @exception EBaseException failed to set id
+ */
+ public void setId(String id) throws EBaseException;
+
+ /**
+ * Initializes this subsystem with the given configuration
+ * store.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ *
+ * @exception EBaseException failed to start up
+ */
+ public void startup() throws EBaseException;
+
+ /**
+ * Stops this system. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown();
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java b/pki/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java
new file mode 100644
index 000000000..ad89cc72b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java
@@ -0,0 +1,40 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * An interface represents a subsystem source. A subsystem
+ * source is a container that manages multiple subsystems.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISubsystemSource {
+
+ /**
+ * Retrieves subsystem from the source.
+ *
+ * @param sid subsystem identifier
+ * @return subsystem
+ */
+ public ISubsystem getSubsystem(String sid);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/ITimeSource.java b/pki/base/common/src/com/netscape/certsrv/base/ITimeSource.java
new file mode 100644
index 000000000..86ca5912e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/ITimeSource.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * This interface represents a time source where
+ * current time can be retrieved. CMS is installed
+ * with a default time source that returns
+ * current time based on the system time. It is
+ * possible to register a time source that returns
+ * the current time from a NTP server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ITimeSource {
+
+ /**
+ * Retrieves current time and date.
+ *
+ * @return current time and date
+ */
+ public Date getCurrentDate();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java b/pki/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java
new file mode 100644
index 000000000..634b5d90e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java
@@ -0,0 +1,225 @@
+// --- 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.certsrv.base;
+
+
+import java.lang.*;
+import java.io.IOException;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+
+
+/**
+ *
+ * The <code>KeyGenInfo</code> represents the information generated by
+ * the KeyGen tag of the HTML forms. It provides the parsing and accessing
+ * mechanisms.<p>
+ *
+ * <pre>
+ * SignedPublicKeyAndChallenge ::= SEQUENCE {
+ * publicKeyAndChallenge PublicKeyAndChallenge,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ *
+ * PublicKeyAndChallenge ::= SEQUENCE {
+ * spki SubjectPublicKeyInfo,
+ * challenge IA5STRING
+ * }
+ *</pre>
+ *
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class KeyGenInfo {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String mSPKACString;
+ private byte mPKAC[];
+ private byte mSPKAC[];
+ private X509Key mSPKI;
+ private DerValue mDerSPKI;
+ private String mChallenge;
+ private DerValue mDerChallenge;
+ private byte mSignature[];
+ private AlgorithmId mAlgId;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Construct empty KeyGenInfo. Need to call decode function
+ * later to initialize.
+ */
+ public KeyGenInfo() {
+
+ }
+
+ /**
+ * Construct KeyGenInfo using the SignedPublicKeyAndChallenge
+ * string representation.
+ *
+ * @param spkac SignedPublicKeyAndChallenge string representation
+ */
+ public KeyGenInfo(String spkac)
+ throws IOException {
+ decode(spkac);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Initialize using the SPKAC string
+ *
+ * @param spkac SPKAC string from the end user
+ */
+ public void decode(String spkac) throws IOException {
+ mSPKACString = spkac;
+ mSPKAC = base64Decode(spkac);
+ derDecode(mSPKAC);
+ }
+
+ /**
+ * Der encoded into buffer
+ *
+ * @return Der encoded buffer
+ */
+ public byte[] encode() {
+ return mSPKAC;
+ }
+
+ /**
+ * Get SPKI in DerValue form
+ *
+ * @return SPKI in DerValue form
+ */
+ public DerValue getDerSPKI() {
+ return mDerSPKI;
+ }
+
+ /**
+ * Get SPKI as X509Key
+ *
+ * @return SPKI in X509Key form
+ */
+ public X509Key getSPKI() {
+ return mSPKI;
+ }
+
+ /**
+ * Get Challenge phrase in DerValue form
+ *
+ * @return Challenge in DerValue form. null if none.
+ */
+ public DerValue getDerChallenge() {
+ return mDerChallenge;
+ }
+
+ /**
+ * Get Challenge phrase in string format
+ *
+ * @return challenge phrase. null if none.
+ */
+ public String getChallenge() {
+ return mChallenge;
+ }
+
+ /**
+ * Get Signature
+ * @return signature
+ */
+ public byte[] getSignature() {
+ return mSignature;
+ }
+
+ /**
+ * Get Algorithm ID
+ * @return the algorithm id
+ */
+ public AlgorithmId getAlgorithmId() {
+ return mAlgId;
+ }
+
+ /**
+ * Validate Signature and Challenge Phrase
+ *
+ * @param challenge phrase; null if none
+ * @return true if validated; otherwise, false
+ */
+ public boolean validateChallenge(String challenge) {
+ if (challenge != null) {
+ if (!challenge.equals(mChallenge)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * String representation of KenGenInfo
+ *
+ * @return string representation of KeGenInfo
+ */
+ public String toString() {
+ if (mSPKACString != null)
+ return mSPKACString;
+ return "";
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private byte[] base64Decode(String spkac)
+ throws IOException {
+
+ return com.netscape.osutil.OSUtil.AtoB(spkac);
+ }
+
+ private void derDecode(byte spkac[])
+ throws IOException {
+ DerInputStream derIn = new DerInputStream(spkac);
+
+ /* get SPKAC Algorithm & Signature */
+ DerValue derSPKACContent[] = derIn.getSequence(3);
+
+ mAlgId = AlgorithmId.parse(derSPKACContent[1]);
+ mSignature = derSPKACContent[2].getBitString();
+
+ /* get PKAC SPKI & Challenge */
+ mPKAC = derSPKACContent[0].toByteArray();
+ derIn = new DerInputStream(mPKAC);
+ DerValue derPKACContent[] = derIn.getSequence(2);
+
+ mDerSPKI = derPKACContent[0];
+ mSPKI = X509Key.parse(derPKACContent[0]);
+
+ mDerChallenge = derPKACContent[1];
+ if (mDerChallenge.length() != 0)
+ mChallenge = derPKACContent[1].getIA5String();
+
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/MessageFormatter.java b/pki/base/common/src/com/netscape/certsrv/base/MessageFormatter.java
new file mode 100644
index 000000000..796c4255b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/MessageFormatter.java
@@ -0,0 +1,155 @@
+// --- 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.certsrv.base;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.reflect.*;
+
+
+/**
+ * Factors out common function of formatting internatinalized
+ * messages taking arguments and using java.util.ResourceBundle
+ * and java.text.MessageFormat mechanism.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see java.util.ResourceBundle
+ */
+public class MessageFormatter {
+
+ private static final Class[] toStringSignature = { Locale.class };
+
+ /**
+ * Retrieves the localized string.
+ *
+ * @param locale end user locale
+ * @param resourceBundleBaseName resource bundle class name
+ * @param formatString format string
+ * @return localized string
+ */
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String formatString) {
+ return getLocalizedString(locale, resourceBundleBaseName,
+ formatString, null);
+ }
+
+ /**
+ * Retrieves the localized string.
+ *
+ * @param locale end user locale
+ * @param resourceBundleBaseName resource bundle class name
+ * @param formatString format string
+ * @param params parameters to be substituted
+ * @return localized string
+ */
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String formatString, Object params) {
+ Object o[] = new Object[1];
+
+ o[0] = params;
+ return getLocalizedString(locale, resourceBundleBaseName,
+ formatString, o);
+ }
+
+ /**
+ * Retrieves the localized string.
+ *
+ * @param locale end user locale
+ * @param resourceBundleBaseName resource bundle class name
+ * @param formatString format string
+ * @param params parameters to be substituted
+ * @return localized string
+ */
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String formatString, Object[] params) {
+
+ String localizedFormat = null;
+
+ try {
+ try {
+ // if you are worried about the efficiency of the
+ // following line, dont worry. ResourceBundle has
+ // an internal cache. So resource bundle wont be
+ // instantiated everytime you call toString().
+
+ localizedFormat = ResourceBundle.getBundle(
+ resourceBundleBaseName, locale).getString(formatString);
+ } catch (MissingResourceException e) {
+ return formatString;
+
+ }
+ Object[] localizedParams = params;
+ Object[] localeArg = null;
+
+ if (params != null) {
+ for (int i = 0; i < params.length; ++i) {
+ if (!(params[i] instanceof String) ||
+ !(params[i] instanceof Date) ||
+ !(params[i] instanceof Number)) {
+ if (localizedParams == params) {
+
+ // only done once
+ // NB if the following variant of cloning code is used
+ // localizedParams = (Object [])mParams.clone();
+ // it causes ArrayStoreException in
+ // localizedParams[i] = params[i].toString();
+ // below
+
+ localizedParams = new Object[params.length];
+ System.arraycopy(params, 0, localizedParams, 0,
+ params.length);
+ }
+ try {
+ Method toStringMethod = params[i].getClass().getMethod(
+ "toString", toStringSignature);
+
+ if (localeArg == null) {
+ // only done once
+ localeArg = new Object[] { locale };
+ }
+ localizedParams[i] = toStringMethod.invoke(
+ params[i], localeArg);
+ } catch (Exception e) {
+ // no method for localization, fall back
+ localizedParams[i] = params[i].toString();
+ }
+ }
+ }
+ }
+ try {
+ // XXX - runtime exception may be raised by the following function
+ MessageFormat format = new MessageFormat(localizedFormat);
+
+ return format.format(localizedParams);
+ } catch (IllegalArgumentException e) {
+ // XXX - for now, we just print the unformatted message
+ // if the exception is raised
+ return localizedFormat;
+ }
+ } catch (Exception e) {
+ return localizedFormat;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java b/pki/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java
new file mode 100644
index 000000000..fc8c8ec8a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java
@@ -0,0 +1,198 @@
+// --- 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.certsrv.base;
+
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import netscape.security.util.ObjectIdentifier;
+
+
+/**
+ * A class representing a meta attribute defintion.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class MetaAttributeDef {
+
+ private String mName;
+ private ObjectIdentifier mOid;
+ private Class mValueClass;
+ private static Hashtable mNameToAttrDef = new Hashtable();
+ private static Hashtable mOidToAttrDef = new Hashtable();
+
+ private MetaAttributeDef() {
+ }
+
+ /**
+ * Constructs a MetaAttribute defintion
+ * <P>
+ *
+ * @param name attribute name
+ * @param valueClass attribute value class
+ * @param oid attribute object identifier
+ */
+ private MetaAttributeDef(String name, Class valueClass,
+ ObjectIdentifier oid) {
+ mName = name;
+ mValueClass = valueClass;
+ mOid = oid;
+ }
+
+ /**
+ * Gets an attribute OID.
+ * <P>
+ *
+ * @return returns attribute OID or null if not defined.
+ */
+ public ObjectIdentifier getOID() {
+ return mOid;
+ }
+
+ /**
+ * Gets an Java class for the attribute values
+ * <P>
+ *
+ * @return returns Java class for the attribute values
+ */
+ public Class getValueClass() {
+ return mValueClass;
+ }
+
+ /**
+ * Gets attribute name
+ * <P>
+ *
+ * @return returns attribute name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Registers new MetaAttribute defintion
+ * Attribute is defined by name, Java class for attribute values and
+ * optional object identifier
+ * <P>
+ *
+ * @param name attribute name
+ * @param valueClass attribute value class
+ * @param oid attribute object identifier
+ * @exception IllegalArgumentException if name or valueClass are null, or
+ * conflicting attribute definition already exists
+ */
+ public static MetaAttributeDef register(String name, Class valueClass,
+ ObjectIdentifier oid) {
+ if (name == null) {
+ throw new IllegalArgumentException(
+ "Attribute name must not be null");
+ }
+ if (valueClass == null) {
+ throw new IllegalArgumentException(
+ "Attribute value class must not be null");
+ }
+
+ MetaAttributeDef newDef = new MetaAttributeDef(name, valueClass, oid);
+ MetaAttributeDef oldDef;
+
+ if ((oldDef = (MetaAttributeDef) mNameToAttrDef.get(name)) != null &&
+ !oldDef.equals(newDef)) {
+ throw new IllegalArgumentException(
+ "Attribute \'" + name + "\' is already defined");
+ }
+ if (oid != null &&
+ (oldDef = (MetaAttributeDef) mOidToAttrDef.get(oid)) != null &&
+ !oldDef.equals(newDef)) {
+ throw new IllegalArgumentException(
+ "OID \'" + oid + "\' is already in use");
+ }
+ mNameToAttrDef.put(name, newDef);
+ if (oid != null) {
+ mOidToAttrDef.put(oid, newDef);
+ }
+ return newDef;
+ }
+
+ /**
+ * Compares this attribute definition with another, for equality.
+ * <P>
+ *
+ * @return true iff names, valueClasses and object identifiers
+ * are identical.
+ */
+ public boolean equals(Object other) {
+ if (other == this)
+ return true;
+
+ if (other instanceof MetaAttributeDef) {
+ MetaAttributeDef otherDef = (MetaAttributeDef) other;
+
+ if ((mOid != null && otherDef.mOid != null &&
+ !mOid.equals(otherDef.mOid)) ||
+ (mOid == null && otherDef.mOid != null) ||
+ !mName.equals(otherDef.mName) ||
+ !mValueClass.equals(otherDef.mValueClass)) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves attribute definition by name
+ * <P>
+ *
+ * @param name attribute name
+ * @return attribute definition or null if not found
+ */
+ public static MetaAttributeDef forName(String name) {
+ return (MetaAttributeDef) mNameToAttrDef.get(name);
+ }
+
+ /**
+ * Retrieves attribute definition by object identifier
+ * <P>
+ *
+ * @param oid attribute object identifier
+ * @return attribute definition or null if not found
+ */
+ public static MetaAttributeDef forOID(ObjectIdentifier oid) {
+ return (MetaAttributeDef) mOidToAttrDef.get(oid);
+ }
+
+ /**
+ * Returns enumeration of the registered attribute names
+ * <P>
+ *
+ * @return returns enumeration of the registered attribute names
+ */
+ public static Enumeration getAttributeNames() {
+ return mNameToAttrDef.keys();
+ }
+
+ /**
+ * Returns enumeration of the registered attribute object identifiers
+ * <P>
+ *
+ * @return returns enumeration of the attribute object identifiers
+ */
+ public static Enumeration getAttributeNameOids() {
+ return mOidToAttrDef.keys();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/MetaInfo.java b/pki/base/common/src/com/netscape/certsrv/base/MetaInfo.java
new file mode 100644
index 000000000..7db522547
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/MetaInfo.java
@@ -0,0 +1,116 @@
+// --- 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.certsrv.base;
+
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.base.AttributeNameHelper;
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * A class represents meta information. A meta information
+ * object is just a generic hashtable that is embedded into
+ * a request object.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class MetaInfo implements IAttrSet {
+
+ public static final String REQUEST_ID = "requestId";
+ public static final String IN_LDAP_PUBLISH_DIR = "inLdapPublishDir";
+
+ private Hashtable content = new Hashtable();
+
+ /**
+ * Constructs a meta information.
+ * <P>
+ */
+ public MetaInfo() {
+ }
+
+ /**
+ * Returns a short string describing this certificate attribute.
+ * <P>
+ *
+ * @return information about this certificate attribute.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("[\n");
+ sb.append(" Meta information:\n");
+ Enumeration enum1 = content.keys();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ sb.append(" " + key + " : " + content.get(key) + "\n");
+ }
+ sb.append("]\n");
+ return sb.toString();
+ }
+
+ /**
+ * Gets an attribute value.
+ * <P>
+ *
+ * @param name the name of the attribute to return.
+ * @exception EBaseException on attribute handling errors.
+ */
+ public Object get(String name) throws EBaseException {
+ return content.get(name);
+ }
+
+ /**
+ * Sets an attribute value.
+ *
+ * @param name the name of the attribute
+ * @param obj the attribute object.
+ *
+ * @exception EBaseException on attribute handling errors.
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ content.put(name, obj);
+ }
+
+ /**
+ * Deletes an attribute value from this CertAttrSet.
+ * <P>
+ *
+ * @param name the name of the attribute to delete.
+ * @exception EBaseException on attribute handling errors.
+ */
+ public void delete(String name) throws EBaseException {
+ content.remove(name);
+ }
+
+ /**
+ * Returns an enumeration of the names of the attributes existing within
+ * this attribute.
+ * <P>
+ *
+ * @return an enumeration of the attribute names.
+ */
+ public Enumeration getElements() {
+ return content.keys();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/Nonces.java b/pki/base/common/src/com/netscape/certsrv/base/Nonces.java
new file mode 100644
index 000000000..e1d992e40
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/Nonces.java
@@ -0,0 +1,128 @@
+// --- 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.certsrv.base;
+
+import java.util.*;
+import java.security.cert.X509Certificate;
+
+
+/**
+ * This class manages nonces sometimes used to control request state flow.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class Nonces implements IAuthInfo {
+
+ private Hashtable mNonces = new Hashtable();
+ private Vector mNonceList = new Vector();
+ private int mNonceLimit;
+
+ /**
+ * Constructs nonces.
+ */
+ public Nonces() {
+ mNonceLimit = 100;
+ Vector mNonceList = new Vector();
+ Hashtable mNonces = new Hashtable();
+ }
+
+ public Nonces(int limit) {
+ mNonceLimit = limit;
+ Vector mNonceList = new Vector();
+ Hashtable mNonces = new Hashtable();
+ }
+
+ public long addNonce(long nonce, X509Certificate cert) {
+ long i;
+ long k = 0;
+ long n = nonce;
+ long m = (long)((mNonceLimit / 2) + 1);
+
+ for (i = 0; i < m; i++) {
+ k = n + i;
+ // avoid collisions
+ if (!mNonceList.contains((Object)k)) {
+ break;
+ }
+ k = n - i;
+ // avoid collisions
+ if (!mNonceList.contains((Object)k)) {
+ break;
+ }
+ }
+ if (i < m) {
+ mNonceList.add(k);
+ mNonces.put(k, cert);
+ if (mNonceList.size() > mNonceLimit) {
+ n = ((Long)(mNonceList.firstElement())).longValue();
+ mNonceList.remove(0);
+ mNonces.remove((Object)n);
+ }
+ } else {
+ // failed to resolved collision
+ k = -nonce;
+ }
+ return k;
+ }
+
+ public X509Certificate getCertificate(long nonce) {
+ X509Certificate cert = (X509Certificate)mNonces.get(nonce);
+ return cert;
+ }
+
+ public X509Certificate getCertificate(int index) {
+ X509Certificate cert = null;
+ if (index >= 0 && index < mNonceList.size()) {
+ long nonce = ((Long)(mNonceList.elementAt(index))).longValue();
+ cert = (X509Certificate)mNonces.get(nonce);
+ }
+ return cert;
+ }
+
+ public long getNonce(int index) {
+ long nonce = 0;
+ if (index >= 0 && index < mNonceList.size()) {
+ nonce = ((Long)(mNonceList.elementAt(index))).longValue();
+ }
+ return nonce;
+ }
+
+ public void removeNonce(long nonce) {
+ mNonceList.remove((Object)nonce);
+ mNonces.remove((Object)nonce);
+ }
+
+
+ public int size() {
+ return mNonceList.size();
+ }
+
+ public int maxSize() {
+ return mNonceLimit;
+ }
+
+ public void clear() {
+ mNonceList.clear();
+ mNonces.clear();
+ }
+
+ public boolean isInSync() {
+ return (mNonceList.size() == mNonces.size());
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/PasswordResources.java b/pki/base/common/src/com/netscape/certsrv/base/PasswordResources.java
new file mode 100644
index 000000000..e0cfe429b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/PasswordResources.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the password checker.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class PasswordResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /*
+ * Constants. The suffix represents the number of possible parameters.
+ */
+ static final Object[][] contents = {};
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/base/Plugin.java b/pki/base/common/src/com/netscape/certsrv/base/Plugin.java
new file mode 100644
index 000000000..0b7d7ee86
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/Plugin.java
@@ -0,0 +1,65 @@
+// --- 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.certsrv.base;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * This represents a generici CMS plugin.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class Plugin {
+
+ private String mId = null;
+ private String mClassPath = null;
+
+ /**
+ * Constructs a plugin.
+ *
+ * @param id plugin implementation name
+ * @param classPath class path
+ */
+ public Plugin(String id, String classPath) {
+ mId = id;
+ mClassPath = classPath;
+ }
+
+ /**
+ * Returns the plugin identifier.
+ *
+ * @return plugin id
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns the plugin classpath.
+ *
+ * @return plugin classpath
+ */
+ public String getClassPath() {
+ return mClassPath;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/base/SessionContext.java b/pki/base/common/src/com/netscape/certsrv/base/SessionContext.java
new file mode 100644
index 000000000..79d429d71
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/base/SessionContext.java
@@ -0,0 +1,163 @@
+// --- 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.certsrv.base;
+
+
+import java.util.*;
+
+
+/**
+ * This class specifies the context object that includes
+ * authentication environment and connection information.
+ * This object is later used in access control evaluation.
+ * This is a global object that can be accessible
+ * throughout the server. It is useful for passing
+ * global and per-thread infomration in methods.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SessionContext extends Hashtable implements IAuthInfo {
+
+ /**
+ * End user locale of the current processing request in the current thread.
+ */
+ public static final String LOCALE = "locale"; // Locale
+
+ /**
+ * Authentication token in the current thread.
+ */
+ public static final String AUTH_TOKEN = "AuthToken"; // IAuthToken
+
+ /**
+ * ID of the authentication manager in the current thread.
+ */
+ public static final String AUTH_MANAGER_ID = "authManagerId"; // String
+
+ /**
+ * User object of the authenticated user in the current thread.
+ */
+ public static final String USER = "user"; // IUser
+
+ /**
+ * User ID of the authenticated user in the current thread.
+ */
+ public static final String USER_ID = "userid"; // String
+
+ /**
+ * Group ID of the authenticated user in the current thread.
+ */
+ public static final String GROUP_ID = "groupid"; //String
+
+ /**
+ * ID of the processing request in the current thread.
+ */
+ public static final String REQUESTER_ID = "requesterID"; // String
+
+ /**
+ * Recovery ID of a recovery operation in KRA in the current thread.
+ */
+ public static final String RECOVERY_ID = "recoveryID"; // String
+
+ /**
+ * IP Address of the requestor of the request in the current thread.
+ */
+ public static final String IPADDRESS = "ipAddress";
+
+ private static Hashtable mContexts = new Hashtable();
+
+ /**
+ * Constructs a session context.
+ */
+ public SessionContext() {
+ super();
+ }
+
+ /**
+ * Creates a new context and associates it with
+ * the current thread. If the current thread is
+ * also associated with a old context, the old
+ * context will be replaced.
+ */
+ private static SessionContext createContext() {
+ SessionContext sc = new SessionContext();
+
+ setContext(sc);
+ return sc;
+ }
+
+ /**
+ * Sets the current context. This allows the
+ * caller to associate a specific session context
+ * with the current thread.
+ * This methods makes custom session context
+ * possible.
+ *
+ * @param sc session context
+ */
+ public static void setContext(SessionContext sc) {
+ mContexts.put(Thread.currentThread(), sc);
+ }
+
+ /**
+ * Retrieves the session context associated with
+ * the current thread. If no context is associated,
+ * a context is created.
+ *
+ * @return sesssion context
+ */
+ public static SessionContext getContext() {
+ SessionContext sc = (SessionContext) mContexts.get(
+ Thread.currentThread());
+
+ if (sc == null) {
+ sc = createContext();
+ }
+ return sc;
+ }
+
+ /**
+ * Retrieves the session context associated with
+ * the current thread. If no context is associated,
+ * null is returned.
+ *
+ * @return sesssion context
+ */
+ public static SessionContext getExistingContext() {
+ SessionContext sc = (SessionContext)
+ mContexts.get(Thread.currentThread());
+
+ if (sc == null) {
+ return null;
+ }
+
+ return sc;
+ }
+
+ /**
+ * Releases the current session context.
+ */
+ public static void releaseContext() {
+ SessionContext sc = (SessionContext) mContexts.get(
+ Thread.currentThread());
+
+ if (sc != null) {
+ mContexts.remove(Thread.currentThread());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/CAResources.java b/pki/base/common/src/com/netscape/certsrv/ca/CAResources.java
new file mode 100644
index 000000000..912d48f69
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/CAResources.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.ca;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for CA subsystem.
+ * <P>
+ *
+ * @version $Revision$ $Date$
+ */
+public class CAResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ECAException.java b/pki/base/common/src/com/netscape/certsrv/ca/ECAException.java
new file mode 100644
index 000000000..1d60e3b07
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ECAException.java
@@ -0,0 +1,86 @@
+// --- 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.certsrv.ca;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a CA exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ECAException extends EBaseException {
+
+ /**
+ * CA resource class name.
+ */
+ private static final String CA_RESOURCES = CAResources.class.getName();
+
+ /**
+ * Constructs a CA exception.
+ * <P>
+ * @param msgFormat constant from CAResources.
+ */
+ public ECAException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a CA exception.
+ * <P>
+ * @param msgFormat constant from CAResources.
+ * @param param additional parameters to the message.
+ */
+ public ECAException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a CA exception.
+ * <P>
+ * @param msgFormat constant from CAResources.
+ * @param e embedded exception.
+ */
+ public ECAException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a CA exception.
+ * <P>
+ * @param msgFormat constant from CAResources.
+ * @param params additional parameters to the message.
+ */
+ public ECAException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Returns the bundle file name.
+ * <P>
+ * @return name of bundle class associated with this exception.
+ */
+ protected String getBundleName() {
+ return CA_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java b/pki/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java
new file mode 100644
index 000000000..75800304c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java
@@ -0,0 +1,37 @@
+// --- 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.certsrv.ca;
+
+
+/**
+ * A class represents a CA exception associated with publishing error.
+ * <P>
+ *
+ * @version $Revision$ $Date$
+ */
+public class EErrorPublishCRL extends ECAException {
+
+ /**
+ * Constructs a CA exception caused by publishing error.
+ * <P>
+ * @param errorString Detailed error message.
+ */
+ public EErrorPublishCRL(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICAService.java b/pki/base/common/src/com/netscape/certsrv/ca/ICAService.java
new file mode 100644
index 000000000..d4a4c1278
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ICAService.java
@@ -0,0 +1,101 @@
+// --- 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.certsrv.ca;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+
+/**
+ * An interface representing a CA request services.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICAService {
+
+ /**
+ * Marks certificate record as revoked by adding revocation information.
+ * Updates CRL cache.
+ *
+ * @param crlentry revocation information obtained from revocation request
+ * @exception EBaseException failed to mark certificate record as revoked
+ */
+ public void revokeCert(RevokedCertImpl crlentry)
+ throws EBaseException;
+
+ /**
+ * Marks certificate record as revoked by adding revocation information.
+ * Updates CRL cache.
+ *
+ * @param crlentry revocation information obtained from revocation request
+ * @param requestId revocation request id
+ * @exception EBaseException failed to mark certificate record as revoked
+ */
+ public void revokeCert(RevokedCertImpl crlentry, String requestId)
+ throws EBaseException;
+
+ /**
+ * Issues certificate base on enrollment information,
+ * creates certificate record, and stores all necessary data.
+ *
+ * @param certi information obtain from revocation request
+ * @exception EBaseException failed to issue certificate or create certificate record
+ */
+ public X509CertImpl issueX509Cert(X509CertInfo certi)
+ throws EBaseException;
+
+ public X509CertImpl issueX509Cert(X509CertInfo certi, String profileId, String rid)
+ throws EBaseException;
+
+ /**
+ * Services profile request.
+ *
+ * @param request profile enrollment request information
+ * @exception EBaseException failed to service profile enrollment request
+ */
+ public void serviceProfileRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Returns KRA-CA connector.
+ *
+ * @return KRA-CA connector
+ */
+ public IConnector getKRAConnector();
+
+ public void setKRAConnector(IConnector c);
+
+ public IConnector getConnector(IConfigStore cs) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java b/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java
new file mode 100644
index 000000000..3470b206d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java
@@ -0,0 +1,74 @@
+// --- 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.certsrv.ca;
+
+
+import netscape.security.x509.Extension;
+import netscape.security.x509.CRLExtensions;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+
+
+/**
+ * An interface representing a CRL extension plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICMSCRLExtension {
+
+ /**
+ * Returns CRL extension OID string.
+ *
+ * @return OID of CRL extension
+ */
+ public String getCRLExtOID();
+
+ /**
+ * Sets extension criticality and returns extension
+ * with new criticality.
+ *
+ * @param ext CRL extension that will change criticality
+ * @param critical new criticality to be assigned to CRL extension
+ * @return extension with new criticality
+ */
+ Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical);
+
+ /**
+ * Builds new CRL extension based on configuration data,
+ * issuing point information, and criticality.
+ *
+ * @param config configuration store
+ * @param crlIssuingPoint CRL issuing point
+ * @param critical criticality to be assigned to CRL extension
+ * @return extension new CRL extension
+ */
+ Extension getCRLExtension(IConfigStore config,
+ Object crlIssuingPoint,
+ boolean critical);
+
+ /**
+ * Reads configuration data and converts them to name value pairs.
+ *
+ * @param config configuration store
+ * @param nvp name value pairs obtained from configuration data
+ */
+ public void getConfigParams(IConfigStore config,
+ NameValuePairs nvp);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java b/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java
new file mode 100644
index 000000000..6e6a47c9f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java
@@ -0,0 +1,59 @@
+// --- 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.certsrv.ca;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * An interface representing a list of CRL extensions.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICMSCRLExtensions {
+
+ /**
+ * Updates configuration store for extension identified by id
+ * with data delivered in name value pairs.
+ *
+ * @param id extension id
+ * @param nvp name value pairs with new configuration data
+ * @param config configuration store
+ */
+ public void setConfigParams(String id, NameValuePairs nvp, IConfigStore config);
+
+ /**
+ * Reads configuration data and returns them as name value pairs.
+ *
+ * @param id extension id
+ * @return name value pairs with configuration data
+ */
+ public NameValuePairs getConfigParams(String id);
+
+ /**
+ * Returns class name with its path.
+ *
+ * @param name extension id
+ * @return class name with its path
+ */
+ public String getClassPath(String name);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java b/pki/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java
new file mode 100644
index 000000000..97f9792fb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java
@@ -0,0 +1,546 @@
+// --- 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.certsrv.ca;
+
+
+import java.util.*;
+import java.math.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * This class encapsulates CRL issuing mechanism. CertificateAuthority
+ * contains a map of CRLIssuingPoint indexed by string ids. Each issuing
+ * point contains information about CRL issuing and publishing parameters
+ * as well as state information which includes last issued CRL, next CRL
+ * serial number, time of the next update etc.
+ * If autoUpdateInterval is set to non-zero value then worker thread
+ * is created that will perform CRL update at scheduled intervals. Update
+ * can also be triggered by invoking updateCRL method directly. Another
+ * parameter minUpdateInterval can be used to prevent CRL
+ * from being updated too often
+ *
+ * @version $Revision$, $Date$
+ */
+
+public interface ICRLIssuingPoint {
+
+ public static final String PROP_PUBLISH_DN = "publishDN";
+ public static final String PROP_PUBLISH_ON_START = "publishOnStart";
+ public static final String PROP_MIN_UPDATE_INTERVAL = "minUpdateInterval";
+ public static final String PROP_BEGIN_SERIAL = "crlBeginSerialNo";
+ public static final String PROP_END_SERIAL = "crlEndSerialNo";
+
+ public static final String SC_ISSUING_POINT_ID = "issuingPointId";
+ public static final String SC_IS_DELTA_CRL = "isDeltaCRL";
+ public static final String SC_CRL_COUNT = "crlCount";
+
+ /**
+ * for manual updates - requested by agent
+ */
+ public static final int CRL_UPDATE_DONE = 0;
+ public static final int CRL_UPDATE_STARTED = 1;
+ public static final int CRL_PUBLISHING_STARTED = 2;
+
+ public static final int CRL_IP_NOT_INITIALIZED = 0;
+ public static final int CRL_IP_INITIALIZED = 1;
+ public static final int CRL_IP_INITIALIZATION_FAILED = -1;
+
+ /**
+ * Returns true if CRL issuing point is enabled.
+ *
+ * @return true if CRL issuing point is enabled
+ */
+ public boolean isCRLIssuingPointEnabled();
+
+ /**
+ * Returns true if CRL generation is enabled.
+ *
+ * @return true if CRL generation is enabled
+ */
+ public boolean isCRLGenerationEnabled();
+
+ /**
+ * Enables or disables CRL issuing point according to parameter.
+ *
+ * @param enable if true enables CRL issuing point
+ */
+ public void enableCRLIssuingPoint(boolean enable);
+
+ /**
+ * Returns CRL update status.
+ *
+ * @return CRL update status
+ */
+ public String getCrlUpdateStatusStr();
+
+ /**
+ * Returns CRL update error.
+ *
+ * @return CRL update error
+ */
+ public String getCrlUpdateErrorStr();
+
+ /**
+ * Returns CRL publishing status.
+ *
+ * @return CRL publishing status
+ */
+ public String getCrlPublishStatusStr();
+
+ /**
+ * Returns CRL publishing error.
+ *
+ * @return CRL publishing error
+ */
+ public String getCrlPublishErrorStr();
+
+ /**
+ * Returns CRL issuing point initialization status.
+ *
+ * @return status of CRL issuing point initialization
+ */
+ public int isCRLIssuingPointInitialized();
+
+ /**
+ * Checks if manual update is set.
+ *
+ * @return true if manual update is set
+ */
+ public boolean isManualUpdateSet();
+
+ /**
+ * Checks if expired certificates are included in CRL.
+ *
+ * @return true if expired certificates are included in CRL
+ */
+ public boolean areExpiredCertsIncluded();
+
+ /**
+ * Checks if CRL includes CA certificates only.
+ *
+ * @return true if CRL includes CA certificates only
+ */
+ public boolean isCACertsOnly();
+
+ /**
+ * Checks if CRL includes profile certificates only.
+ *
+ * @return true if CRL includes profile certificates only
+ */
+ public boolean isProfileCertsOnly();
+
+ /**
+ * Checks if CRL issuing point includes this profile.
+ *
+ * @return true if CRL issuing point includes this profile
+ */
+ public boolean checkCurrentProfile(String id);
+
+ /**
+ * Initializes CRL issuing point.
+ *
+ * @param ca certificate authority that holds CRL issuing point
+ * @param id CRL issuing point id
+ * @param config configuration sub-store for CRL issuing point
+ * @exception EBaseException thrown if initialization failed
+ */
+ public void init(ISubsystem ca, String id, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * This method is called during shutdown.
+ * It updates CRL cache and stops thread controlling CRL updates.
+ */
+ public void shutdown();
+
+ /**
+ * Returns internal id of this CRL issuing point.
+ *
+ * @return internal id of this CRL issuing point
+ */
+ public String getId();
+
+ /**
+ * Returns internal description of this CRL issuing point.
+ *
+ * @return internal description of this CRL issuing point
+ */
+ public String getDescription();
+
+ /**
+ * Sets internal description of this CRL issuing point.
+ *
+ * @param description description for this CRL issuing point.
+ */
+ public void setDescription(String description);
+
+ /**
+ * Returns DN of the directory entry where CRLs from this issuing point
+ * are published.
+ *
+ * @return DN of the directory entry where CRLs are published.
+ */
+ public String getPublishDN();
+
+ /**
+ * Returns signing algorithm.
+ *
+ * @return signing algorithm
+ */
+ public String getSigningAlgorithm();
+
+ /**
+ * Returns signing algorithm used in last signing operation..
+ *
+ * @return last signing algorithm
+ */
+ public String getLastSigningAlgorithm();
+
+ /**
+ * Returns current CRL generation schema for this CRL issuing point.
+ * <P>
+ *
+ * @return current CRL generation schema for this CRL issuing point
+ */
+ public int getCRLSchema();
+
+ /**
+ * Returns current CRL number of this CRL issuing point.
+ *
+ * @return current CRL number of this CRL issuing point
+ */
+ public BigInteger getCRLNumber();
+
+ /**
+ * Returns current delta CRL number of this CRL issuing point.
+ * <P>
+ *
+ * @return current delta CRL number of this CRL issuing point
+ */
+ public BigInteger getDeltaCRLNumber();
+
+ /**
+ * Returns next CRL number of this CRL issuing point.
+ *
+ * @return next CRL number of this CRL issuing point
+ */
+ public BigInteger getNextCRLNumber();
+
+ /**
+ * Returns number of entries in the current CRL.
+ *
+ * @return number of entries in the current CRL
+ */
+ public long getCRLSize();
+
+ /**
+ * Returns number of entries in delta CRL
+ *
+ * @return number of entries in delta CRL
+ */
+ public long getDeltaCRLSize();
+
+ /**
+ * Returns time of the last update.
+ *
+ * @return last CRL update time
+ */
+ public Date getLastUpdate();
+
+ /**
+ * Returns time of the next update.
+ *
+ * @return next CRL update time
+ */
+ public Date getNextUpdate();
+
+ /**
+ * Returns time of the next delta CRL update.
+ *
+ * @return next delta CRL update time
+ */
+ public Date getNextDeltaUpdate();
+
+ /**
+ * Returns all the revoked certificates from the CRL cache.
+ *
+ * @param start first requested CRL entry
+ * @param end next after last requested CRL entry
+ * @return set of all the revoked certificates or null if there are none.
+ */
+ public Set getRevokedCertificates(int start, int end);
+
+ /**
+ * Returns certificate authority.
+ *
+ * @return certificate authority
+ */
+ public ISubsystem getCertificateAuthority();
+
+ /**
+ * Schedules immediate CRL manual-update
+ * and sets signature algorithm to be used for signing.
+ *
+ * @param signatureAlgorithm signature algorithm to be used for signing
+ */
+ public void setManualUpdate(String signatureAlgorithm);
+
+ /**
+ * Returns auto update interval in milliseconds.
+ *
+ * @return auto update interval in milliseconds
+ */
+ public long getAutoUpdateInterval();
+
+ /**
+ * Returns true if CRL is updated for every change
+ * of revocation status of any certificate.
+ *
+ * @return true if CRL update is always triggered by revocation operation
+ */
+ public boolean getAlwaysUpdate();
+
+ /**
+ * Returns next update grace period in minutes.
+ *
+ * @return next update grace period in minutes
+ */
+ public long getNextUpdateGracePeriod();
+
+ /**
+ * Returns filter used to build CRL based on information stored
+ * in local directory.
+ *
+ * @return filter used to search local directory
+ */
+ public String getFilter();
+
+ /**
+ * Builds a list of revoked certificates to put them into CRL.
+ * Calls certificate record processor to get necessary data
+ * from certificate records.
+ * This also regenerates CRL cache.
+ *
+ * @param cp certificate record processor
+ * @exception EBaseException if an error occurred in the database.
+ */
+ public void processRevokedCerts(IElementProcessor cp)
+ throws EBaseException;
+
+ /**
+ * Returns date of revoked certificate or null
+ * if certificated is not listed as revoked.
+ *
+ * @param serialNumber serial number of certificate to be checked
+ * @param checkDeltaCache true if delta CRL cache suppose to be
+ * included in checking process
+ * @param includeExpiredCerts true if delta CRL cache with expired
+ * certificates suppose to be included in checking process
+ * @return date of revoked certificate or null
+ */
+ public Date getRevocationDateFromCache(BigInteger serialNumber,
+ boolean checkDeltaCache,
+ boolean includeExpiredCerts);
+ /**
+ * Returns split times from CRL generation.
+ *
+ * @return split times from CRL generation in milliseconds
+ */
+ public Vector getSplitTimes();
+
+ /**
+ * Generates CRL now based on cache or local directory if cache
+ * is not available. It also publishes CRL if it is required.
+ *
+ * @param signingAlgorithm signing algorithm to be used for CRL signing
+ * @exception EBaseException if an error occurred during
+ * CRL generation or publishing
+ */
+ public void updateCRLNow(String signingAlgorithm)
+ throws EBaseException;
+
+ /**
+ * Clears CRL cache
+ */
+ public void clearCRLCache();
+
+ /**
+ * Clears delta-CRL cache
+ */
+ public void clearDeltaCRLCache();
+
+ /**
+ * Returns number of recently revoked certificates.
+ *
+ * @return number of recently revoked certificates
+ */
+ public int getNumberOfRecentlyRevokedCerts();
+
+ /**
+ * Returns number of recently unrevoked certificates.
+ *
+ * @return number of recently unrevoked certificates
+ */
+ public int getNumberOfRecentlyUnrevokedCerts();
+
+ /**
+ * Returns number of recently expired and revoked certificates.
+ *
+ * @return number of recently expired and revoked certificates
+ */
+ public int getNumberOfRecentlyExpiredCerts();
+
+ /**
+ * Converts list of extensions supplied by revocation request
+ * to list of extensions required to be placed in CRL.
+ *
+ * @param exts list of extensions supplied by revocation request
+ * @return list of extensions required to be placed in CRL
+ */
+ public CRLExtensions getRequiredEntryExtensions(CRLExtensions exts);
+
+ /**
+ * Adds revoked certificate to delta-CRL cache.
+ *
+ * @param serialNumber serial number of revoked certificate
+ * @param revokedCert revocation information supplied by revocation request
+ */
+ public void addRevokedCert(BigInteger serialNumber, RevokedCertImpl revokedCert);
+
+ /**
+ * Adds revoked certificate to delta-CRL cache.
+ *
+ * @param serialNumber serial number of revoked certificate
+ * @param revokedCert revocation information supplied by revocation request
+ * @param requestId revocation request id
+ */
+ public void addRevokedCert(BigInteger serialNumber, RevokedCertImpl revokedCert,
+ String requestId);
+
+ /**
+ * Adds unrevoked certificate to delta-CRL cache.
+ *
+ * @param serialNumber serial number of unrevoked certificate
+ */
+ public void addUnrevokedCert(BigInteger serialNumber);
+
+ /**
+ * Adds unrevoked certificate to delta-CRL cache.
+ *
+ * @param serialNumber serial number of unrevoked certificate
+ * @param requestId unrevocation request id
+ */
+ public void addUnrevokedCert(BigInteger serialNumber, String requestId);
+
+ /**
+ * Adds expired and revoked certificate to delta-CRL cache.
+ *
+ * @param serialNumber serial number of expired and revoked certificate
+ */
+ public void addExpiredCert(BigInteger serialNumber);
+
+ /**
+ * Updates CRL cache into local directory.
+ */
+ public void updateCRLCacheRepository();
+
+ /**
+ * Updates issuing point configuration according to supplied data
+ * in name value pairs.
+ *
+ * @param params name value pairs defining new issuing point configuration
+ * @return true if configuration is updated successfully
+ */
+ public boolean updateConfig(NameValuePairs params);
+
+ /**
+ * Returns true if delta-CRL is enabled.
+ *
+ * @return true if delta-CRL is enabled
+ */
+ public boolean isDeltaCRLEnabled();
+
+ /**
+ * Returns true if CRL cache is enabled.
+ *
+ * @return true if CRL cache is enabled
+ */
+ public boolean isCRLCacheEnabled();
+
+ /**
+ * Returns true if CRL cache is empty.
+ *
+ * @return true if CRL cache is empty
+ */
+ public boolean isCRLCacheEmpty();
+
+ /**
+ * Returns true if CRL cache testing is enabled.
+ *
+ * @return true if CRL cache testing is enabled
+ */
+ public boolean isCRLCacheTestingEnabled();
+
+ /**
+ * Returns true if supplied delta-CRL is matching current delta-CRL.
+ *
+ * @param deltaCRL delta-CRL to verify against current delta-CRL
+ * @return true if supplied delta-CRL is matching current delta-CRL
+ */
+ public boolean isThisCurrentDeltaCRL(X509CRLImpl deltaCRL);
+
+ /**
+ * Returns status of CRL generation.
+ *
+ * @return one of the following according to CRL generation status:
+ * CRL_UPDATE_DONE, CRL_UPDATE_STARTED, and CRL_PUBLISHING_STARTED
+ */
+ public int isCRLUpdateInProgress();
+
+ /**
+ * Generates CRL now based on cache or local directory if cache
+ * is not available. It also publishes CRL if it is required.
+ * CRL is signed by default signing algorithm.
+ *
+ * @exception EBaseException if an error occurred during
+ * CRL generation or publishing
+ */
+ public void updateCRLNow() throws EBaseException;
+
+ /**
+ * Returns list of CRL extensions.
+ *
+ * @return list of CRL extensions
+ */
+ public ICMSCRLExtensions getCRLExtensions();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
new file mode 100644
index 000000000..bc545a9ba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -0,0 +1,497 @@
+// --- 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.certsrv.ca;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import org.mozilla.jss.crypto.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+
+
+/**
+ * An interface represents a Certificate Authority that is
+ * responsible for certificate specific operations.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertificateAuthority extends ISubsystem {
+
+ public static final String ID = "ca";
+
+ public static final String PROP_CERTDB_INC = "certdbInc";
+ public static final String PROP_CRLDB_INC = "crldbInc";
+ public static final String PROP_REGISTRATION = "Registration";
+ public static final String PROP_POLICY = "Policy";
+ public static final String PROP_GATEWAY = "gateway";
+ public static final String PROP_CLASS = "class";
+ public static final String PROP_TYPE = "type";
+ public static final String PROP_IMPL = "impl";
+ public static final String PROP_PLUGIN = "plugin";
+ public static final String PROP_INSTANCE = "instance";
+ public static final String PROP_LISTENER_SUBSTORE = "listener";
+ public final static String PROP_LDAP_PUBLISH_SUBSTORE = "ldappublish";
+ public final static String PROP_PUBLISH_SUBSTORE = "publish";
+ public final static String PROP_ENABLE_PUBLISH = "enablePublish";
+ public final static String PROP_ENABLE_LDAP_PUBLISH = "enableLdapPublish";
+
+ public final static String PROP_X509CERT_VERSION = "X509CertVersion";
+ public final static String PROP_ENABLE_PAST_CATIME = "enablePastCATime";
+ public final static String PROP_DEF_VALIDITY = "DefaultIssueValidity";
+ public final static String PROP_FAST_SIGNING = "fastSigning";
+ public static final String PROP_ENABLE_ADMIN_ENROLL =
+ "enableAdminEnroll";
+
+ public final static String PROP_CRL_SUBSTORE = "crl";
+ // make this public so agent gateway can access for now.
+ public final static String PROP_CRL_PAGE_SIZE = "pageSize";
+ public final static String PROP_MASTER_CRL = "MasterCRL";
+ public final static String PROP_CRLEXT_SUBSTORE = "extension";
+ public final static String PROP_ISSUING_CLASS =
+ "com.netscape.cmscore.ca.CRLIssuingPoint";
+ public final static String PROP_EXPIREDCERTS_CLASS =
+ "com.netscape.cmscore.ca.CRLWithExpiredCerts";
+
+ public final static String PROP_NOTIFY_SUBSTORE = "notification";
+ public final static String PROP_CERT_ISSUED_SUBSTORE = "certIssued";
+ public final static String PROP_CERT_REVOKED_SUBSTORE = "certRevoked";
+ public final static String PROP_REQ_IN_Q_SUBSTORE = "requestInQ";
+ public final static String PROP_PUB_QUEUE_SUBSTORE = "publishingQueue";
+
+ public final static String PROP_ISSUER_NAME = "name";
+ public final static String PROP_CA_NAMES = "CAs";
+ public final static String PROP_DBS_SUBSTORE = "dbs";
+ public final static String PROP_SIGNING_SUBSTORE = "signing";
+ public final static String PROP_CA_CHAIN_NUM = "certchainNum";
+ public final static String PROP_CA_CHAIN = "certchain";
+ public final static String PROP_CA_CERT = "cert";
+ public final static String PROP_ENABLE_OCSP = "ocsp";
+ public final static String PROP_OCSP_SIGNING_SUBSTORE = "ocsp_signing";
+ public final static String PROP_CRL_SIGNING_SUBSTORE = "crl_signing";
+ public final static String PROP_ID = "id";
+
+ public final static String PROP_CERTDB_TRANS_MAXRECORDS = "transitMaxRecords";
+ public final static String PROP_CERTDB_TRANS_PAGESIZE = "transitRecordPageSize";
+
+ /**
+ * Retrieves the certificate repository where all the locally
+ * issued certificates are kept.
+ *
+ * @return CA's certificate repository
+ */
+ public ICertificateRepository getCertificateRepository();
+
+ /**
+ * Retrieves the request queue of this certificate authority.
+ *
+ * @return CA's request queue
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Retrieves the policy processor of this certificate authority.
+ *
+ * @return CA's policy processor
+ */
+ public IPolicyProcessor getPolicyProcessor();
+
+ public boolean noncesEnabled();
+ public Nonces getNonces();
+
+ /**
+ * Retrieves the publishing processor of this certificate authority.
+ *
+ * @return CA's publishing processor
+ */
+ public IPublisherProcessor getPublisherProcessor();
+
+ /**
+ * Retrieves the next available serial number.
+ *
+ * @return next available serial number
+ */
+ public String getStartSerial();
+
+ /**
+ * Sets the next available serial number.
+ *
+ * @param serial next available serial number
+ * @exception EBaseException failed to set next available serial number
+ */
+ public void setStartSerial(String serial) throws EBaseException;
+
+ /**
+ * Retrieves the last serial number that can be used for
+ * certificate issuance in this certificate authority.
+ *
+ * @return the last serial number
+ */
+ public String getMaxSerial();
+
+ /**
+ * Sets the last serial number that can be used for
+ * certificate issuance in this certificate authority.
+ *
+ * @param serial the last serial number
+ * @exception EBaseException failed to set the last serial number
+ */
+ public void setMaxSerial(String serial) throws EBaseException;
+
+ /**
+ * Retrieves the default signature algorithm of this certificate authority.
+ *
+ * @return the default signature algorithm of this CA
+ */
+ public SignatureAlgorithm getDefaultSignatureAlgorithm();
+
+ /**
+ * Retrieves the default signing algorithm of this certificate authority.
+ *
+ * @return the default signing algorithm of this CA
+ */
+ public String getDefaultAlgorithm();
+
+ /**
+ * Sets the default signing algorithm of this certificate authority.
+ *
+ * @param algorithm new default signing algorithm
+ * @exception EBaseException failed to set the default signing algorithm
+ */
+ public void setDefaultAlgorithm(String algorithm) throws EBaseException;
+
+ /**
+ * Retrieves the supported signing algorithms of this certificate authority.
+ *
+ * @return the supported signing algorithms of this CA
+ */
+ public String[] getCASigningAlgorithms();
+
+ /**
+ * Allows certificates to have validities that are longer
+ * than this certificate authority's.
+ *
+ * @param enableCAPast if equals "true", it allows certificates
+ * to have validity longer than CA's certificate validity
+ * @exception EBaseException failed to set above option
+ */
+ public void setValidity(String enableCAPast) throws EBaseException;
+
+ /**
+ * Retrieves the default validity period.
+ *
+ * @return the default validity length in days
+ */
+ public long getDefaultValidity();
+
+ /**
+ * Retrieves all the CRL issuing points.
+ *
+ * @return enumeration of all the CRL issuing points
+ */
+ public Enumeration getCRLIssuingPoints();
+
+ /**
+ * Retrieves CRL issuing point with the given identifier.
+ *
+ * @param id CRL issuing point id
+ * @return CRL issuing point with given id
+ */
+ public ICRLIssuingPoint getCRLIssuingPoint(String id);
+
+ /**
+ * Adds CRL issuing point with the given identifier and description.
+ *
+ * @param crlSubStore sub-store with all CRL issuing points
+ * @param id CRL issuing point id
+ * @param description CRL issuing point description
+ * @return true if CRL issuing point was successfully added
+ */
+ public boolean addCRLIssuingPoint(IConfigStore crlSubStore, String id,
+ boolean enable, String description);
+
+ /**
+ * Deletes CRL issuing point with the given identifier.
+ *
+ * @param crlSubStore sub-store with all CRL issuing points
+ * @param id CRL issuing point id
+ */
+ public void deleteCRLIssuingPoint(IConfigStore crlSubStore, String id);
+
+ /**
+ * Retrieves the CRL repository.
+ *
+ * @return CA's CRL repository
+ */
+ public ICRLRepository getCRLRepository();
+
+ /**
+ * Retrieves the Replica ID repository.
+ *
+ * @return CA's Replica ID repository
+ */
+ public IReplicaIDRepository getReplicaRepository();
+
+ /**
+ * Retrieves the request in queue listener.
+ *
+ * @return the request in queue listener
+ */
+ public IRequestListener getRequestInQListener();
+
+ /**
+ * Retrieves all request listeners.
+ *
+ * @return name enumeration of all request listeners
+ */
+ public Enumeration getRequestListenerNames();
+
+ /**
+ * Retrieves the request listener for issued certificates.
+ *
+ * @return the request listener for issued certificates
+ */
+ public IRequestListener getCertIssuedListener();
+
+ /**
+ * Retrieves the request listener for revoked certificates.
+ *
+ * @return the request listener for revoked certificates
+ */
+ public IRequestListener getCertRevokedListener();
+
+ /**
+ * Retrieves the CA certificate chain.
+ *
+ * @return the CA certificate chain
+ */
+ public CertificateChain getCACertChain();
+
+ /**
+ * Retrieves the CA certificate.
+ *
+ * @return the CA certificate
+ */
+ public org.mozilla.jss.crypto.X509Certificate getCaX509Cert();
+
+ /**
+ * Retrieves the CA certificate.
+ *
+ * @return the CA certificate
+ */
+ public X509CertImpl getCACert();
+
+ /**
+ * Updates the CRL immediately for MasterCRL issuing point if it exists.
+ *
+ * @exception EBaseException failed to create or publish CRL
+ */
+ public void updateCRLNow() throws EBaseException;
+
+ /**
+ * Publishes the CRL immediately for MasterCRL issuing point if it exists.
+ *
+ * @exception EBaseException failed to publish CRL
+ */
+ public void publishCRLNow() throws EBaseException;
+
+ /**
+ * Retrieves the signing unit that manages the CA signing key for
+ * signing certificates.
+ *
+ * @return the CA signing unit for certificates
+ */
+ public ISigningUnit getSigningUnit();
+
+ /**
+ * Retrieves the signing unit that manages the CA signing key for
+ * signing CRL.
+ *
+ * @return the CA signing unit for CRLs
+ */
+ public ISigningUnit getCRLSigningUnit();
+
+ /**
+ * Retrieves the signing unit that manages the CA signing key for
+ * signing OCSP response.
+ *
+ * @return the CA signing unit for OCSP responses
+ */
+ public ISigningUnit getOCSPSigningUnit();
+
+ /**
+ * Sets the maximium path length in the basic constraint extension.
+ *
+ * @param num the maximium path length
+ */
+ public void setBasicConstraintMaxLen(int num);
+
+ /**
+ * Is this a clone CA?
+ *
+ * @return true if this is a clone CA
+ */
+ public boolean isClone();
+
+ /**
+ * Retrieves the request listener by name.
+ *
+ * @param name request listener name
+ * @return the request listener
+ */
+ public IRequestListener getRequestListener(String name);
+
+ /**
+ * get request notifier
+ */
+ public IRequestNotifier getRequestNotifier();
+
+ /**
+ * Registers a request listener.
+ *
+ * @param listener request listener to be registered
+ */
+ public void registerRequestListener(IRequestListener listener);
+
+ /**
+ * Registers a request listener.
+ *
+ * @param name under request listener is going to be registered
+ * @param listener request listener to be registered
+ */
+ public void registerRequestListener(String name, IRequestListener listener);
+
+ /**
+ * Retrieves the issuer name of this certificate authority.
+ *
+ * @return the issuer name of this certificate authority
+ */
+ public X500Name getX500Name();
+
+ /**
+ * Retrieves the issuer name of this certificate authority issuing point.
+ *
+ * @return the issuer name of this certificate authority issuing point
+ */
+ public X500Name getCRLX500Name();
+
+ /**
+ * Signs the given CRL with the specific algorithm.
+ *
+ * @param crl CRL to be signed
+ * @param algname algorithm used for signing
+ * @return signed CRL
+ * @exception EBaseException failed to sign CRL
+ */
+ public X509CRLImpl sign(X509CRLImpl crl, String algname)
+ throws EBaseException;
+
+ /**
+ * Logs a message to this certificate authority.
+ *
+ * @param level logging level
+ * @param msg logged message
+ */
+ public void log(int level, String msg);
+
+ /**
+ * Returns the nickname for the CA signing certificate.
+ *
+ * @return the nickname for the CA signing certificate
+ */
+ public String getNickname();
+
+ /**
+ * Signs a X.509 certificate template.
+ *
+ * @param certInfo X.509 certificate template
+ * @param algname algorithm used for signing
+ * @return signed certificate
+ * @exception EBaseException failed to sign certificate
+ */
+ public X509CertImpl sign(X509CertInfo certInfo, String algname)
+ throws EBaseException;
+
+ /**
+ * Retrieves the default certificate version.
+ *
+ * @return the default version certificate
+ */
+ public CertificateVersion getDefaultCertVersion();
+
+ /**
+ * Is this CA allowed to issue certificate that has longer
+ * validty than the CA's.
+ *
+ * @return true if allows certificates to have validity longer than CA's
+ */
+ public boolean isEnablePastCATime();
+
+ /**
+ * Retrieves the CA service object that is responsible for
+ * processing requests.
+ *
+ * @return CA service object
+ */
+ public IService getCAService();
+
+ /**
+ * Returns the in-memory count of the processed OCSP requests.
+ *
+ * @return number of processed OCSP requests in memory
+ */
+ public long getNumOCSPRequest();
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the processed time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPRequestTotalTime();
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the signing time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalSignTime();
+
+ /**
+ * Returns the total data signed
+ * for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalData();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java b/pki/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java
new file mode 100644
index 000000000..81d5cbefb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java
@@ -0,0 +1,58 @@
+// --- 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.certsrv.cert;
+
+
+import com.netscape.certsrv.base.*;
+import java.security.cert.*;
+
+
+/**
+ * Interface for handling cross certs
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICrossCertPairSubsystem extends ISubsystem {
+
+ /**
+ * "import" the CA cert cross-signed by another CA (potentially a
+ * bridge CA) into internal ldap db.
+ * If publishing is turned on, and
+ * if matches up a pair, then publish to publishing directory
+ * otherwise, leave in internal ldap db and wait for it's matching
+ * pair
+ * @param certBytes binary byte array of the cert
+ * @exception EBaseException when certBytes conversion to X509
+ * certificate fails
+ */
+ public void importCert(byte[] certBytes) throws EBaseException;
+
+ /**
+ * publish all cert pairs, if publisher is on
+ * @exception EBaseException when publishing fails
+ */
+ public void publishCertPairs() throws EBaseException;
+
+ /**
+ * convert byte array to X509Certificate
+ * @return X509Certificate the X509Certificate class
+ * representation of the certificate byte array
+ * @exception CertificateException when conversion fails
+ */
+ public X509Certificate byteArray2X509Cert(byte[] certBytes) throws CertificateException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/client/IDataProcessor.java b/pki/base/common/src/com/netscape/certsrv/client/IDataProcessor.java
new file mode 100644
index 000000000..3bce367d9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/client/IDataProcessor.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.client;
+
+
+/**
+ * this class represents the callback interface between
+ * the client package and the data storage object (data model)
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDataProcessor {
+
+ /**
+ * This method will be callby the client package each time
+ * data object arrived from the server side.
+ * @param data data object expected by the interface implementor
+ */
+ public void processData(Object data);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java b/pki/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java
new file mode 100644
index 000000000..139585f2c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java
@@ -0,0 +1,29 @@
+// --- 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.certsrv.client.connection;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * An interface represents authentiator.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthenticator {
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/client/connection/IConnection.java b/pki/base/common/src/com/netscape/certsrv/client/connection/IConnection.java
new file mode 100644
index 000000000..18bd35183
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/client/connection/IConnection.java
@@ -0,0 +1,51 @@
+// --- 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.certsrv.client.connection;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+/**
+ * Interface for all connection objects.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConnection {
+
+ /**
+ * Send request to the server using this connection
+ */
+ public int sendRequest(String req) throws IOException;
+
+ /**
+ * Returns the response in byte array format
+ */
+ public byte[] getResponse();
+
+ /**
+ * Close the connection
+ */
+ public void disconnect();
+
+ /**
+ * SetTimeout
+ */
+ public void setSoTimeout(int timeout) throws SocketException;
+
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java b/pki/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java
new file mode 100644
index 000000000..b4fecd155
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.client.connection;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * Interface for all connection factory. Primarily act as
+ * the abstraction layer for different kind of connection factory.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConnectionFactory {
+
+ /**
+ * Creates connection using the host and port
+ * @param host The host to connect to
+ * @param port The port to connect to
+ * @return The created connection
+ * @throws IOException On an IO Error
+ * @throws UnknownHostException If the host can't be resolved
+ */
+ public IConnection create(String host, int port)
+ throws IOException, UnknownHostException;
+
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/common/ConfigConstants.java b/pki/base/common/src/com/netscape/certsrv/common/ConfigConstants.java
new file mode 100644
index 000000000..9f892cd25
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/ConfigConstants.java
@@ -0,0 +1,334 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface contains constants that are used
+ * in the protocol between the configuration daemon
+ * and UI configuration wizard.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ConfigConstants {
+
+ public static final String TRUE = "true";
+ public static final String FALSE = "false";
+ public static final String OPTYPE = "opType";
+ public static final String TASKID = "taskID";
+
+ // Stages
+ public static final String STAGES = "stages";
+ public static final String STAGE_INTERNAL_DB = "stageInternalDB";
+ public static final String STAGE_CONNECT_DB = "stageConnectDB";
+ public static final String STAGE_SETUP_PORTS = "stageSetupPorts";
+ public static final String STAGE_SETUP_ADMINISTRATOR = "stageSetupAdmin";
+ public static final String STAGE_SETUP_SUBSYSTEMS = "stageSubsystems";
+ public static final String STAGE_DATA_MIGRATION = "stageDataMigration";
+ public static final String STAGE_CA_SELFSIGNED_CERT = "stageCASelfSignedCert";
+ public static final String STAGE_CA_CERT_REQUEST = "stageCACertRequest";
+ public static final String STAGE_CA_CERT_INSTALL = "stageCACertInstall";
+ public static final String STAGE_RA_LOCAL_CERT = "stageRALocalCert";
+ public static final String STAGE_RA_CERT_REQUEST = "stageRACertRequest";
+ public static final String STAGE_RA_CERT_INSTALL = "stageRACertInstall";
+ public static final String STAGE_KRA_LOCAL_CERT = "stageKRALocalCert";
+ public static final String STAGE_KRA_CERT_REQUEST = "stageKRACertRequest";
+ public static final String STAGE_KRA_CERT_INSTALL = "stageKRACertInstall";
+ public static final String STAGE_SSL_LOCAL_CERT = "stageSSLLocalCert";
+ public static final String STAGE_SSL_CERT_REQUEST = "stageSSLCertRequest";
+ public static final String STAGE_SSL_CERT_INSTALL = "stageSSLCertInstall";
+ public static final String STAGE_OCSP_LOCAL_CERT = "stageOCSPLocalCert";
+ public static final String STAGE_OCSP_CERT_REQUEST = "stageOCSPCertRequest";
+ public static final String STAGE_OCSP_CERT_INSTALL = "stageOCSPCertInstall";
+ public static final String STAGE_CA_CERTCHAIN_IMPORT = "stageCACertChain";
+ public static final String STAGE_RA_CERTCHAIN_IMPORT = "stageRACertChain";
+ public static final String STAGE_OCSP_CERTCHAIN_IMPORT = "stageOCSPCertChain";
+ public static final String STAGE_KRA_CERTCHAIN_IMPORT = "stageKRACertChain";
+ public static final String STAGE_SSL_CERTCHAIN_IMPORT = "stageSSLCertChain";
+ public static final String STAGE_OCSP_SERVICE_ADDED = "stageOCSPService";
+ public static final String STAGE_CONFIG_WEBSERVER = "stageConfigWebserver";
+ public static final String STAGE_REPLICATION_AGREEMENT = "stageReplicationAgreement";
+ public static final String PR_ENABLE_REPLICATION = "enableReplication";
+
+ public static final String CA_CERT_REQUEST = "CACertRequest";
+ public static final String RA_CERT_REQUEST = "RACertRequest";
+ public static final String OCSP_CERT_REQUEST = "OCSPCertRequest";
+ public static final String KRA_CERT_REQUEST = "KRACertRequest";
+ public static final String SSL_CERT_REQUEST = "SSLCertRequest";
+ public static final String STAGE_CA_REQ_SUCCESS = "stageCAReqSuccess";
+ public static final String STAGE_RA_REQ_SUCCESS = "stageRAReqSuccess";
+ public static final String STAGE_KRA_REQ_SUCCESS = "stageKRAReqSuccess";
+ public static final String STAGE_SSL_REQ_SUCCESS = "stageSSLReqSuccess";
+ public static final String STAGE_OCSP_REQ_SUCCESS = "stageOCSPReqSuccess";
+
+ public static final String STAGE_KRA_NM_SCHEME = "stageKRANMScheme";
+ public static final String STAGE_CACLONING = "stageCACloning";
+ public static final String STAGE_RACLONING = "stageRACloning";
+ public static final String STAGE_KRACLONING = "stageKRACloning";
+ public static final String STAGE_TKSCLONING = "stageTKSCloning";
+ public static final String STAGE_SSLCLONING = "stageSSLCloning";
+ public static final String STAGE_OCSPCLONING = "stageOCSPCloning";
+ public static final String STAGE_CLONEMASTER = "stageCloneMaster";
+ public static final String STAGE_UPDATE_DB_INFO = "stageUpdateDBInfo";
+
+ public static final String CA_CERT_REQUEST_BACK = "CACertRequestBack";
+ public static final String RA_CERT_REQUEST_BACK = "RACertRequestBack";
+ public static final String OCSP_CERT_REQUEST_BACK = "OCSPCertRequestBack";
+ public static final String KRA_CERT_REQUEST_BACK = "KRACertRequestBack";
+ public static final String SSL_CERT_REQUEST_BACK = "SSLCertRequestBack";
+
+ // Error messages
+ public static final String PR_ERROR_MESSAGE = "errorMsg";
+
+ // Certificate server instance
+ public static final String PR_CERT_INSTANCE_NAME = "instanceID";
+
+ // Admin server info
+ public static final String PR_HOST = "host";
+ public static final String PR_LDAP_DB_NAME = "ldapServerDB";
+ public static final String PR_SERVER_ROOT = "serverRoot";
+ public static final String PR_SIE_URL = "sieURL";
+ public static final String PR_ADMIN_PASSWD = "AdminUserPassword";
+ public static final String PR_ADMIN_UID = "adminUID";
+ public static final String PR_ADMIN_DOMAIN = "adminDomain";
+ public static final String PR_MACHINE_NAME = "machineName";
+
+ public static final String PR_CA_OCSP_SERVICE = "CAOCSPService";
+
+ // Daemon
+ public static final String PR_DAEMON_PORT = "daemonPort";
+ public static final String PR_DELETE_PASSWD_CONF = "deletePasswdConf";
+
+ // Internal Database
+ public static final String PR_DB_SCHEMA = "db.schema";
+ public static final String PR_DB_MODE = "db.mode";
+ public static final String PR_DB_PORT = "internaldb.ldapconn.port";
+ public static final String PR_DB_HOST = "internaldb.ldapconn.host";
+ public static final String PR_DB_BINDDN = "internaldb.ldapauth.bindDN";
+ public static final String PR_DB_BINDPWD = "internaldb.ldapauth.bindPWPrompt";
+ public static final String PR_DB_PWD = "db.password";
+ public static final String PR_DB_LOCAL = "db.local";
+ public static final String PR_DB_NAME = "db.instanceName";
+ public static final String PR_CLONEDDB_NAME = "db.cloned.instanceName";
+ public static final String PR_IS_DBCREATED = "db.isCreated";
+ public static final String PR_IS_CLONEDDB_CREATED = "db.cloned.isCreated";
+ public static final String PR_NEXT_AVAIL_PORT = "nextAvailPort";
+
+ // Network Ports
+ public static final String PR_ENABLE = "enabled";
+ public static final String PR_EE_PORT = "eeGateway.http.port";
+ public static final String PR_EE_SECURE_PORT = "eeGateway.https.port";
+ public static final String PR_AGENT_PORT = "agentGateway.https.port";
+ public static final String PR_RADM_PORT = "radm.https.port";
+ public static final String PR_RADM_PORT_SETUP="radm.port";
+ public static final String PR_EE_PORT_ENABLE = "eeGateway.http.enable";
+ public static final String PR_EE_PORTS_ENABLE = "eePortsEnable";
+
+ // Certificate server administrator
+ public static final String PR_CERT_ADMINNAME = "cert.admin.name";
+ public static final String PR_CERT_ADMINUID = "cert.admin.uid";
+ public static final String PR_CERT_ADMINPASSWD = "cert.admin.passwd";
+
+ // Subsystems
+ public static final String PR_SUBSYSTEMS = "subsystems";
+ public static final String PR_CA = "ca";
+ public static final String PR_RA = "ra";
+ public static final String PR_KRA = "kra";
+ public static final String PR_TKS = "tks";
+ public static final String PR_OCSP = "ocsp";
+ public static final String CA_HOST = "caHostname";
+ public static final String CA_PORT = "caPortnum";
+ public static final String CA_TIMEOUT = "caTimeout";
+ public static final String KRA_HOST = "kraHostname";
+ public static final String KRA_PORT = "kraPortnum";
+ public static final String KRA_TIMEOUT = "kraTimeout";
+ public static final String REMOTE_KRA_ENABLED = "remoteKRA";
+
+ // Clone Master (CLA)
+ public static final String CLA_HOST = "claHostname";
+ public static final String CLA_PORT = "claPortnum";
+ public static final String CLA_PORT_EE = "claPortnumEE";
+ public static final String CLA_TIMEOUT = "claTimeout";
+ public static final String CLONE_CA = "cloning";
+ public static final String PR_CLONE_SETTING_DONE = "cloneSettingDone";
+
+ // Data Migration
+ public static final String PR_ENABLE_MIGRATION = "migrationEnable";
+ public static final String PR_OUTPUT_PATH = "outputPath";
+ public static final String PR_ADD_LDIF_PATH = "addLdifPath";
+ public static final String PR_MOD_LDIF_PATH = "modLdifPath";
+ public static final String PR_SIGNING_KEY_MIGRATION_TOKEN =
+ "signingKeyMigrationToken";
+ public static final String PR_SSL_KEY_MIGRATION_TOKEN =
+ "sslKeyMigrationToken";
+ public static final String PR_SIGNING_KEY_MIGRATION_TOKEN_PASSWD =
+ "signingKeyMigrationTokenPasswd";
+ public static final String PR_SIGNING_KEY_MIGRATION_TOKEN_SOPPASSWD =
+ "signingKeyMigrationTokenSOPPasswd";
+ public static final String PR_SSL_KEY_MIGRATION_TOKEN_PASSWD =
+ "sslKeyMigrationTokenPasswd";
+ public static final String PR_SSL_KEY_MIGRATION_TOKEN_SOPPASSWD =
+ "sslKeyMigrationTokenSOPPasswd";
+ public static final String PR_NUM_MIGRATION_WARNINGS =
+ "numMigrationWarnings";
+ public static final String PR_MIGRATION_WARNING = "migrationWarning";
+ public static final String PR_CA_KEY_TYPE = "caKeyType";
+ public static final String PR_LDAP_PASSWORD = "ldapPassword";
+ public static final String PR_MIGRATION_PASSWORD = "migrationPassword";
+
+ // Key and Cert
+ public static final String PR_HARDWARE_SPLIT = "hardwareSplit";
+ public static final String PR_TOKEN_LIST = "tokenList";
+ public static final String PR_TOKEN_NAME = "tokenName";
+ public static final String PR_SUBJECT_NAME = "subjectName";
+ public static final String PR_CA_SUBJECT_NAME = "caSubjectName";
+ public static final String PR_RA_SUBJECT_NAME = "raSubjectName";
+ public static final String PR_OCSP_SUBJECT_NAME = "ocspSubjectName";
+ public static final String PR_KRA_SUBJECT_NAME = "kraSubjectName";
+ public static final String PR_SSL_SUBJECT_NAME = "sslSubjectName";
+ public static final String PR_KEY_TYPE = "keyType";
+ public static final String PR_KEY_LENGTH = "keyLength";
+ public static final String PR_CERT_REQUEST = "certReq";
+ public static final String PR_REQUEST_ID = "ReqID";
+ public static final String PR_REQUEST_FORMAT = "ReqFormat";
+ public static final String PR_REQUEST_PKCS10 = "PKCS10";
+ public static final String PR_REQUEST_CMC = "CMC";
+ public static final String PR_CERTIFICATE_TYPE = "certType";
+ public static final String PR_CACERT_LOCALCA = "ca_isLocalCA";
+ public static final String PR_RACERT_LOCALCA = "ra_isLocalCA";
+ public static final String PR_KRACERT_LOCALCA = "kra_isLocalCA";
+ public static final String PR_SSLCERT_LOCALCA = "ssl_isLocalCA";
+ public static final String PR_OCSPCERT_LOCALCA = "ocsp_isLocalCA";
+ public static final String PR_CERT_CONTENT_ORDER = "contentOrder";
+ public static final String PR_CERTIFICATE_EXTENSION = "certificateExtension";
+ public static final String CA_REQUEST_DISPLAYED = "caReqDisplayed";
+ public static final String RA_REQUEST_DISPLAYED = "raReqDisplayed";
+ public static final String OCSP_REQUEST_DISPLAYED = "ocspReqDisplayed";
+ public static final String KRA_REQUEST_DISPLAYED = "kraReqDisplayed";
+ public static final String SSL_REQUEST_DISPLAYED = "sslReqDisplayed";
+
+ // KRA Storage Key Generation
+ public static final String PR_KEY_LEN = "keyLength";
+ public static final String PR_KEY_ALG = "keyAlg";
+ public static final String PR_STORAGE_TOKEN_PWD = "storageTokenPwd";
+ public static final String PR_STORAGE_HARDWARE = "storageHardware";
+
+ // KRA Agents
+ public static final String PR_AGENT_N = "n";
+ public static final String PR_AGENT_M = "m";
+ public static final String PR_AGENT_UID = "uid";
+ public static final String PR_AGENT_PWD = "pwd";
+
+ // Token Info
+ public static final String PR_TOKEN_NAMES = "tokenNames";
+ public static final String PR_TOKEN_INITIALIZED = "tokenInitialized";
+ public static final String PR_TOKEN_LOGGED_IN = "tokenLoggedIn";
+ public static final String PR_TOKEN_PASSWD = "tokenPasswd";
+ public static final String PR_TOKEN_SOP = "sopPasswd";
+ public static final String PR_CLONE_SUBSYSTEM = "cloneSubsystem";
+ public static final String PR_CLONE_CA_TOKEN_NAME = "cloneCATokenName";
+ public static final String PR_CLONE_OCSP_TOKEN_NAME = "cloneOCSPTokenName";
+ public static final String PR_CLONE_RA_TOKEN_NAME = "cloneRATokenName";
+ public static final String PR_CLONE_KRA_TOKEN_NAME = "cloneKRATokenName";
+ public static final String PR_CLONE_STORAGE_TOKEN_NAME = "cloneStorageTokenName";
+ public static final String PR_CLONE_SSL_TOKEN_NAME = "cloneSSLTokenName";
+ public static final String PR_CLONE_CA_NICKNAME = "cloneCANickname";
+ public static final String PR_CLONE_OCSP_NICKNAME = "cloneOCSPNickname";
+ public static final String PR_CLONE_RA_NICKNAME = "cloneRANickname";
+ public static final String PR_CLONE_KRA_NICKNAME = "cloneKRANickname";
+ public static final String PR_CLONE_STORAGE_NICKNAME = "cloneStorageNickname";
+ public static final String PR_CLONE_SSL_NICKNAME = "cloneSSLNickname";
+ public static final String PR_TOKEN_LOGONLIST = "tokenLogonList";
+ public static final String PR_TOKEN_LOGON_PWDS = "tokenLogonPasswords";
+ public static final String PR_SUBSYSTEM = "subsystem";
+
+ // Single Signon
+ public static final String PR_SINGLE_SIGNON = "singleSignon";
+ public static final String PR_SINGLE_SIGNON_PASSWORD = "singleSignonPwd";
+ public static final String PR_SINGLE_SIGNON_PW_TAGS = "singleSignonPWTags";
+
+ public static final String PR_CERT_CHAIN = "certChain";
+
+ // Token Subsystem Info
+ public static final String PR_CA_TOKEN = "caToken";
+ public static final String PR_RA_TOKEN = "raToken";
+ public static final String PR_KRA_TOKEN = "kraToken";
+ public static final String PR_SSL_TOKEN = "sslToken";
+ //public static final String PR_SUBSYSTEMS = "subsystems";
+
+ // Key Length
+ public static final String PR_RSA_MIN_KEYLENGTH = "RSAMinKeyLength";
+ public static final String PR_CA_KEYTYPE = "ca_keyType";
+ public static final String PR_HASH_TYPE = "hashType";
+ public static final String PR_NOTAFTER = "notAfter";
+ public static final String PR_CA_O_COMPONENT = "caOComponent";
+ public static final String PR_CA_C_COMPONENT = "caCComponent";
+ public static final String PR_RA_O_COMPONENT = "raOComponent";
+ public static final String PR_RA_C_COMPONENT = "raCComponent";
+ public static final String PR_OCSP_O_COMPONENT = "ocspOComponent";
+ public static final String PR_OCSP_C_COMPONENT = "ocspCComponent";
+
+ // Subject DN
+ public static final String PR_OU_COMPONENT = "OU_Component";
+ public static final String PR_O_COMPONENT = "O_Component";
+ public static final String PR_L_COMPONENT = "L_Component";
+ public static final String PR_ST_COMPONENT = "ST_Component";
+ public static final String PR_C_COMPONENT = "C_Component";
+
+ // CA serial number
+ public static final String PR_CA_SERIAL_NUMBER = "caSerialNumber";
+ public static final String PR_CA_ENDSERIAL_NUMBER = "caEndSerialNumber";
+
+ // KRA number
+ public static final String PR_REQUEST_NUMBER = "requestNumber";
+ public static final String PR_ENDREQUEST_NUMBER = "endRequestNumber";
+ public static final String PR_SERIAL_REQUEST_NUMBER = "serialRequestNumber";
+
+ // Cloning
+ public static final String PR_CLONING_INSTANCE = "cloningInstance";
+ public static final String PR_CLONE_CERTIFICATES = "clonedCertificates";
+
+ // Cert request
+ public static final String CA_EEPORT = "caEEPort";
+ public static final String CA_EETYPE = "caEEType";
+
+ // Certificate chain
+ public static final String NOT_IMPORT_CHAIN = "notImportChain";
+
+ public static final String OVERRIDE_VALIDITY = "overrideValidity";
+
+ // request status: should be consistent with RequestStatus.java
+ public static String BEGIN_STRING = "begin";
+ public static String PENDING_STRING = "pending";
+ public static String APPROVED_STRING = "approved";
+ public static String SVC_PENDING_STRING = "svc_pending";
+ public static String CANCELED_STRING = "canceled";
+ public static String REJECTED_STRING = "rejected";
+ public static String COMPLETE_STRING = "complete";
+
+ public static String PR_CMS_SEED = "cmsSeed";
+
+ public static String PR_WEB_SERVERROOT = "webServerRoot";
+ public static String PR_USER_ID = "webUserId";
+
+ public static final String PR_AGREEMENT_NAME_1 = "agreementName1";
+ public static final String PR_REPLICATION_MANAGER_PASSWD_1 = "replicationManagerPwd1";
+ public static final String PR_AGREEMENT_NAME_2 = "agreementName2";
+ public static final String PR_REPLICATION_MANAGER_PASSWD_2 = "replicationManagerPwd2";
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/common/Constants.java b/pki/base/common/src/com/netscape/certsrv/common/Constants.java
new file mode 100644
index 000000000..c85034918
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/Constants.java
@@ -0,0 +1,750 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface contains constants that are shared
+ * by certificate server and its client SDK.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface Constants {
+
+ /*=======================================================
+ * MESSAGE FORMAT CONSTANTS
+ *=======================================================*/
+ public static final String PASSWORDTYPE = "PasswordField";
+ public static final String TEXTTYPE = "TextField";
+ public static final String CHECKBOXTYPE = "CheckBox";
+ public static final String COMBOTYPE = "ComboBox";
+ public final static String TRUE = "true";
+ public final static String FALSE = "false";
+ public final static String VIEW = "view";
+ public final static String EDIT = "edit";
+
+ public final static String OP_TYPE = "OP_TYPE";
+ public final static String OP_SCOPE = "OP_SCOPE";
+
+ //STATIC RESOURCE IDENTIFIERS
+ public final static String RS_ID = "RS_ID";
+ public final static String RS_ID_CONFIG = "RS_ID_CONFIG";
+ public final static String RS_ID_ORDER = "RS_ID_ORDER";
+
+ //STATIC UI TYPE
+ public final static String TYPE_PASSWORD = "password";
+
+ /**********************************************************
+ * PROPERTY NAME LISTED BELOW
+ **********************************************************/
+
+ /*========================================================
+ * General
+ *========================================================*/
+ public final static String PR_PORT = "port";
+ public final static String PR_SSLPORT = "sslPort";
+
+ /*========================================================
+ * Tasks
+ *========================================================*/
+ public final static String PR_SERVER_START = "start";
+ public final static String PR_SERVER_STOP = "stop";
+ public final static String PR_SERVER_RESTART = "restart";
+
+ /*========================================================
+ * Networks
+ *========================================================*/
+ public final static String PR_ADMIN_S_PORT = "admin.https.port";
+ public final static String PR_AGENT_S_PORT = "agent.https.port";
+ public final static String PR_GATEWAY_S_PORT = "gateway.https.port";
+ public final static String PR_GATEWAY_PORT = "gateway.http.port";
+ public final static String PR_DOC_ROOT = "docroot";
+ public final static String PR_ADMIN_S_BACKLOG = "admin.https.backlog";
+ public final static String PR_AGENT_S_BACKLOG = "agent.https.backlog";
+ public final static String PR_GATEWAY_S_BACKLOG = "gateway.https.backlog";
+ public final static String PR_GATEWAY_BACKLOG = "gateway.http.backlog";
+ public final static String PR_GATEWAY_PORT_ENABLED =
+ "gateway.http.enable";
+ public final static String PR_MASTER_AGENT_PORT = "master.ca.agent.port";
+ public final static String PR_MASTER_AGENT_HOST = "master.ca.agent.host";
+
+ /*========================================================
+ * SMTP
+ *========================================================*/
+ public final static String PR_SERVER_NAME = "server";
+
+ /*========================================================
+ * SNMP
+ *========================================================*/
+ public final static String PR_SNMP_ENABLED = "on";
+ public final static String PR_SNMP_MASTER_HOST = "master.host";
+ public final static String PR_SNMP_MASTER_PORT = "master.port";
+ public final static String PR_SNMP_DESC = "desc";
+ public final static String PR_SNMP_ORGN = "orgn";
+ public final static String PR_SNMP_LOC = "loc";
+ public final static String PR_SNMP_CONTACT = "contact";
+
+ /*========================================================
+ * Self Tests
+ *========================================================*/
+ public final static String PR_RUN_SELFTESTS_ON_DEMAND = "run";
+ public final static String PR_RUN_SELFTESTS_ON_DEMAND_CLASS = "class";
+ public final static String PR_RUN_SELFTESTS_ON_DEMAND_CONTENT = "runContent";
+
+ /*========================================================
+ * Users and Groups
+ *========================================================*/
+
+ //group properties
+ public final static String PR_GROUP_DESC = "desc";
+ public final static String PR_GROUP_USER = "user";
+ public final static String PR_GROUP_GROUP = "group";
+
+ //user properties
+ public final static String PR_USER_FULLNAME = "fullname";
+ public final static String PR_USER_PASSWORD = "password";
+ public final static String PR_USER_EMAIL = "email";
+ public final static String PR_USER_PHONE = "phone";
+ public final static String PR_USER_STATE = "state";
+ public final static String PR_USER_CERT = "cert";
+ public final static String PR_USER_GROUP = "groups";
+ public final static String PR_MULTIROLES = "multiroles";
+
+ /*========================================================
+ * Authentication
+ *========================================================*/
+ public final static String PR_PING = "ping";
+ public final static String PR_AUTH_CLASS = "class";
+ public final static String PR_AUTH_IMPL_NAME = "implName";
+ public final static String PR_AUTH_HOST = "ldapconn.host";
+ public final static String PR_AUTH_PORT = "ldapconn.port";
+ public final static String PR_AUTH_BASEDN = "basedn";
+ public final static String PR_AUTH_ADMIN_DN = "ldapauth.bindDN";
+ public final static String PR_AUTH_ADMIN_PWD = "ldapauth.bindPassword";
+
+ /*========================================================
+ * Job Scheduler
+ *========================================================*/
+ public final static String PR_JOBS_CLASS = "class";
+ public final static String PR_JOBS_IMPL_NAME = "implName";
+ public final static String PR_JOBS_FREQUENCY = "frequency";
+
+ /*========================================================
+ * Notification
+ *========================================================*/
+ public final static String PR_NOTIFICATION_FORM_NAME = "emailTemplate";
+ public final static String PR_NOTIFICATION_SUBJECT =
+ "emailSubject";
+ public final static String PR_NOTIFICATION_SENDER = "senderEmail";
+ public final static String PR_NOTIFICATION_RECEIVER = "recipientEmail";
+
+ /*========================================================
+ * Logs
+ *========================================================*/
+ public static final String PR_LOG_IMPL_NAME = "implName";
+ public static final String PR_EXT_PLUGIN_IMPLTYPE_LOG = "log";
+ public final static String PR_LOG_CLASS = "class";
+ public final static String PR_LOG_INSTANCE = "instanceName";
+ public final static String PR_LOG_ONE = "entry";
+ public final static String PR_LOG_ENTRY = "maxentry";
+ public final static String PR_LOG_SOURCE = "source";
+ public final static String PR_LOG_LEVEL = "level";
+ public final static String PR_LOG_ENABLED = "on";
+ public final static String PR_LOG_BUFFERSIZE = "bufferSize";
+ public final static String PR_LOG_EXPIRED_TIME = "expirationTime";
+ public final static String PR_LOG_FILENAME = "fileName";
+ public final static String PR_LOG_FLUSHINTERVAL = "flushInterval";
+ public final static String PR_LOG_MAXFILESIZE = "maxFileSize";
+ public final static String PR_LOG_ROLLEROVER_INTERVAL = "rolloverInterval";
+ public final static String PR_LOG_TYPE = "type";
+ public static final String PR_LOGSOURCE_KRA = "KRA";
+ public static final String PR_LOGSOURCE_RA = "RA";
+ public static final String PR_LOGSOURCE_CA = "CA";
+ public static final String PR_LOGSOURCE_HTTP = "HTTP";
+ public static final String PR_LOGSOURCE_DB = "DB";
+ public static final String PR_LOGSOURCE_AUTH = "AUTH";
+ public static final String PR_LOGSOURCE_ADMIN = "ADMIN";
+ public static final String PR_LOG_NAME = "logname";
+ public static final String PR_CURRENT_LOG = "current";
+
+ public static final String PR_AUTO_CRL = "auto";
+ public static final String PR_LOG_SIGNED_AUDIT = "SignedAudit";
+ public static final String PR_LOG_TRANSACTIONS = "Transactions";
+ public static final String PR_LOG_SYSTEM = "System";
+
+ public static final String PR_DEBUG_LOG_SHOWCALLER = "debug.showcaller";
+ public static final String PR_DEBUG_LOG_ENABLE = "debug.enabled";
+ public static final String PR_DEBUG_LOG_LEVEL = "debug.level";
+
+ /*========================================================
+ * LDAP Publishing
+ *========================================================*/
+
+ // publishing properties
+ public final static String PR_BASIC_AUTH = "BasicAuth";
+ public final static String PR_SSL_AUTH = "SslClientAuth";
+ public final static String PR_AUTH_TYPE = "ldapauth.authtype";
+ public final static String PR_BINDPWD_PROMPT = "ldapauth.bindPWPrompt";
+ public final static String PR_CERT_NAMES = "ldapauth.nicknames";
+ public final static String PR_LDAP_CLIENT_CERT = "ldapauth.clientCertNickname";
+ public final static String PR_DIRECTORY_MANAGER_PWD = "directoryManagerPwd";
+
+ // crl settings
+ public final static String PR_ENABLE_CRL = "enableCRLUpdates";
+ public final static String PR_UPDATE_SCHEMA = "updateSchema";
+ public final static String PR_EXTENDED_NEXT_UPDATE = "extendedNextUpdate";
+ public final static String PR_UPDATE_ALWAYS = "alwaysUpdate";
+ public final static String PR_ENABLE_DAILY = "enableDailyUpdates";
+ public final static String PR_DAILY_UPDATES = "dailyUpdates";
+ public final static String PR_ENABLE_FREQ = "enableUpdateInterval";
+ public final static String PR_UPDATE_FREQ = "autoUpdateInterval";
+ public final static String PR_GRACE_PERIOD = "nextUpdateGracePeriod";
+ public final static String PR_ENABLE_CACHE = "enableCRLCache";
+ public final static String PR_CACHE_FREQ = "cacheUpdateInterval";
+ public final static String PR_CACHE_RECOVERY = "enableCacheRecovery";
+ public final static String PR_CACHE_TESTING = "enableCacheTesting";
+ public final static String PR_EXTENSIONS = "allowExtensions";
+ public final static String PR_INCLUDE_EXPIREDCERTS = "includeExpiredCerts";
+ public final static String PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME = "includeExpiredCertsOneExtraTime";
+ public final static String PR_CA_CERTS_ONLY = "caCertsOnly";
+ public final static String PR_PROFILE_CERTS_ONLY = "profileCertsOnly";
+ public final static String PR_PROFILE_LIST = "profileList";
+ public final static String PR_SIGNING_ALGORITHM = "signingAlgorithm";
+ public final static String PR_MD2_RSA = "MD2withRSA";
+ public final static String PR_MD5_RSA = "MD5withRSA";
+ public final static String PR_SHA1_RSA = "SHA1withRSA";
+ public final static String PR_SHA1_DSA = "SHA1withDSA";
+ public final static String PR_DESCRIPTION = "description";
+ public final static String PR_CLASS = "class";
+
+ // ldap settings
+ public final static String PR_ENABLE = "enable";
+ public final static String PR_PUBLISHING_ENABLE = "publishingEnable";
+ public final static String PR_HOST_NAME = "ldapconn.host";
+ public final static String PR_SECURE_PORT_ENABLED = "ldapconn.secureConn";
+ public final static String PR_LDAP_PORT = "ldapconn.port";
+ public final static String PR_LDAP_VERSION = "ldapconn.version";
+ public final static String PR_BIND_DN = "ldapauth.bindDN";
+ public final static String PR_BIND_PASSWD = "ldapauth.bindPassword";
+ public final static String PR_BIND_PASSWD_AGAIN = "bindPasswdAgain";
+ public final static String PR_LDAP_MAX_CONNS = "maxConns";
+ public final static String PR_LDAP_MIN_CONNS = "minConns";
+ public final static String PR_PUBLISHING_QUEUE_ENABLE = "queue.enable";
+ public final static String PR_PUBLISHING_QUEUE_THREADS = "queue.maxNumberOfThreads";
+ public final static String PR_PUBLISHING_QUEUE_PAGE_SIZE = "queue.pageSize";
+ public final static String PR_PUBLISHING_QUEUE_PRIORITY = "queue.priorityLevel";
+ public final static String PR_PUBLISHING_QUEUE_STATUS = "queue.saveStatus";
+
+ public final static String PR_BASE_DN = "baseDN";
+ public final static String PR_DNCOMPS = "dnComps";
+ public final static String PR_FILTERCOMPS = "filterComps";
+
+ // ldap connection test
+ public final static String PR_CONN_INITED = "connInited";
+ public final static String PR_CONN_INIT_FAIL = "connInitFail";
+ public final static String PR_CONN_OK = "connOk";
+ public final static String PR_CONN_FAIL = "connFail";
+ public final static String PR_AUTH_OK = "authOk";
+ public final static String PR_AUTH_FAIL = "authFail";
+ public final static String PR_SAVE_OK = "saveOk";
+ public final static String PR_SAVE_NOT = "saveOrNot";
+
+ /*========================================================
+ * Plugin
+ *========================================================*/
+ public final static String PR_PLUGIN_IMP = "imp";
+ public final static String PR_PLUGIN_INSTANCE = "instance";
+
+ /*========================================================
+ * Policy
+ *========================================================*/
+ public final static String PR_POLICY_CLASS = "class";
+ public final static String PR_POLICY_IMPL_NAME = "implName";
+ public final static String PR_CRLDP_NAME = "crldpName";
+ public final static String PR_POLICY_DESC = "desc";
+ public final static String PR_POLICY_ORDER = "order";
+ public final static String PR_POLICY_ENABLE = "enable";
+ public final static String PR_POLICY_PREDICATE = "predicate";
+
+ /*========================================================
+ * Publish
+ *========================================================*/
+ public final static String PR_PUBLISHER = "publisher";
+ public final static String PR_PUBLISHER_CLASS = "class";
+ public final static String PR_PUBLISHER_IMPL_NAME = "implName";
+ public final static String PR_PUBLISHER_DESC = "desc";
+ public final static String PR_PUBLISHER_ORDER = "order";
+ public final static String PR_PUBLISHER_ENABLE = "enable";
+
+ public final static String PR_MAPPER = "mapper";
+ public final static String PR_MAPPER_CLASS = "class";
+ public final static String PR_MAPPER_IMPL_NAME = "implName";
+ public final static String PR_MAPPER_DESC = "desc";
+ public final static String PR_MAPPER_ORDER = "order";
+ public final static String PR_MAPPER_ENABLE = "enable";
+
+ public final static String PR_RULE = "rule";
+ public final static String PR_RULE_CLASS = "class";
+ public final static String PR_RULE_IMPL_NAME = "implName";
+ public final static String PR_RULE_DESC = "desc";
+ public final static String PR_RULE_ORDER = "order";
+ public final static String PR_RULE_ENABLE = "enable";
+
+ public final static String PR_CRLEXT = "crlExt";
+ public final static String PR_CRLEXT_CLASS = "class";
+ public final static String PR_CRLEXT_IMPL_NAME = "implName";
+ public final static String PR_CRLEXT_DESC = "desc";
+ public final static String PR_CRLEXT_ORDER = "order";
+ public final static String PR_CRLEXT_ENABLE = "enable";
+
+ public final static String PR_OCSPSTORE_IMPL_NAME = "implName";
+
+ /*========================================================
+ * Registration Authority
+ *========================================================*/
+ public final static String PR_EE_ENABLED = "eeEnabled";
+ public final static String PR_OCSP_ENABLED = "ocspEnabled";
+ public final static String PR_RA_ENABLED = "raEnabled";
+ public final static String PR_RENEWAL_ENABLED = "renewal.enabled";
+ public final static String PR_RENEWAL_VALIDITY = "renewal.validity";
+ public final static String PR_RENEWAL_EMAIL = "renewal.email";
+ public final static String PR_RENEWAL_EXPIREDNOTIFIEDENABLED =
+ "renewal.expired.notification.enabled";
+ public final static String PR_RENEWAL_NUMNOTIFICATION =
+ "renewal.numNotification";
+ public final static String PR_RENEWAL_INTERVAL = "renewal.interval";
+ public final static String PR_SERVLET_CLASS = "class";
+ public final static String PR_SERVLET_URI = "uri";
+ public final static String PR_IMPL_NAME = "implName";
+ public final static String PR_LOCAL = "local";
+ public final static String PR_ID = "id";
+ public final static String PR_HOST = "host";
+ public final static String PR_URI = "uri";
+ public final static String PR_ENABLED = "enable";
+
+ /*========================================================
+ * Certificate Authority
+ *========================================================*/
+ public final static String PR_VALIDITY = "validity";
+ public final static String PR_DEFAULT_ALGORITHM = "defaultSigningAlgorithm";
+ public final static String PR_ALL_ALGORITHMS = "allSigningAlgorithms";
+ public final static String PR_SERIAL = "startSerialNumber";
+ public final static String PR_MAXSERIAL = "maxSerialNumber";
+
+ /*========================================================
+ * Access Control
+ *========================================================*/
+ public final static String PR_ACL_OPS = "aclOperations";
+ public final static String PR_ACI = "aci";
+ public final static String PR_ACL_CLASS = "class";
+ public final static String PR_ACL_DESC = "desc";
+ public final static String PR_ACL_RIGHTS = "rights";
+
+ /*========================================================
+ * Key Recovery
+ *========================================================*/
+ public final static String PR_AUTO_RECOVERY_ON = "autoRecoveryOn";
+ public final static String PR_RECOVERY_N = "recoveryN";
+ public final static String PR_RECOVERY_M = "recoveryM";
+ public final static String PR_OLD_RECOVERY_AGENT = "oldRecoveryAgent";
+ public final static String PR_RECOVERY_AGENT = "recoveryAgent";
+ public final static String PR_OLD_AGENT_PWD = "oldAgentPwd";
+ public final static String PR_AGENT_PWD = "agentPwd";
+ public final static String PR_NO_OF_REQUIRED_RECOVERY_AGENTS = "noOfRequiredRecoveryAgents";
+
+ /*========================================================
+ * Status
+ *========================================================*/
+ public final static String PR_STAT_STARTUP = "startup";
+ public final static String PR_STAT_TIME = "time";
+ public final static String PR_STAT_VERSION = "cms.version";
+ public final static String PR_STAT_INSTALLDATE = "installDate";
+ public final static String PR_STAT_INSTANCEID = "instanceId";
+
+ /*========================================================
+ * Server Instance
+ *========================================================*/
+ public final static String PR_INSTALL = "install";
+ public final static String PR_INSTANCES_INSTALL = "instancesInstall";
+ public final static String PR_CA_INSTANCE = "ca";
+ public final static String PR_OCSP_INSTANCE = "ocsp";
+ public final static String PR_RA_INSTANCE = "ra";
+ public final static String PR_KRA_INSTANCE = "kra";
+ public final static String PR_TKS_INSTANCE = "tks";
+
+ /*
+ * Certificate info
+ */
+ public final static String PR_CA_SIGNING_NICKNAME = "caSigningCert";
+ public final static String PR_PKCS10 = "pkcs10";
+ public final static String PR_CERT_SUBJECT_NAME = "certSubjectName";
+ public final static String PR_ISSUER_NAME = "issuerName";
+ public final static String PR_SERIAL_NUMBER = "serialNumber";
+ public final static String PR_BEFORE_VALIDDATE = "beforeValidDate";
+ public final static String PR_AFTER_VALIDDATE = "afterValidDate";
+ public final static String PR_CERT_FINGERPRINT = "certFingerPrint";
+ public final static String PR_SIGNATURE_ALGORITHM = "signatureAlg";
+ public final static String PR_ALGORITHM_ID = "algorithmId";
+ public final static String PR_NICKNAME = "nickname";
+ public final static String PR_ADD_CERT = "addCert";
+ public final static String PR_CERT_CONTENT = "certContent";
+
+ /*
+ * Certificate type
+ */
+ public final static String PR_CERTIFICATE_TYPE = "certType";
+ public final static String PR_CERTIFICATE_SUBTYPE = "certSubType";
+ public final static String PR_CA_SIGNING_CERT = "caSigningCert";
+ public final static String PR_RA_SIGNING_CERT = "raSigningCert";
+ public final static String PR_OCSP_SIGNING_CERT = "ocspSigningCert";
+ public final static String PR_KRA_TRANSPORT_CERT = "kraTransportCert";
+ public final static String PR_SERVER_CERT = "serverCert";
+ public final static String PR_SUBSYSTEM_CERT = "subsystemCert";
+ public final static String PR_SERVER_CERT_RADM = "serverCertRadm";
+ public final static String PR_CROSS_CERT = "crossCert";
+ public final static String PR_OTHER_CERT = "otherCert";
+ public final static String PR_SERVER_CERT_CHAIN = "serverCertChain";
+ public final static String PR_TRUSTED_CA_CERT = "trustedCACert";
+ public final static String PR_TRUSTED_CERT = "trustedCert";
+ public final static String PR_AUDIT_SIGNING_CERT = "auditSigningCert";
+
+ /*
+ * Extensions
+ */
+ public final static String PR_VALIDITY_PERIOD = "validityPeriod";
+ public final static String PR_BEGIN_YEAR = "beginYear";
+ public final static String PR_BEGIN_MONTH = "beginMonth";
+ public final static String PR_BEGIN_DATE = "beginDate";
+ public final static String PR_BEGIN_HOUR = "beginHour";
+ public final static String PR_BEGIN_MIN = "beginMin";
+ public final static String PR_BEGIN_SEC = "beginSec";
+ public final static String PR_AFTER_YEAR = "afterYear";
+ public final static String PR_AFTER_MONTH = "afterMonth";
+ public final static String PR_AFTER_DATE = "afterDate";
+ public final static String PR_AFTER_HOUR = "afterHour";
+ public final static String PR_AFTER_MIN = "afterMin";
+ public final static String PR_AFTER_SEC = "afterSec";
+ public final static String PR_AIA = "aia";
+ public final static String PR_AKI = "aki";
+ public final static String PR_OCSP_SIGNING = "ocspSigning";
+ public final static String PR_OCSP_NOCHECK = "ocspNoCheck";
+ public final static String PR_SKI = "ski";
+ public final static String PR_KEY_USAGE = "keyUsage";
+ public final static String PR_DER_EXTENSION = "derExtension";
+ public final static String PR_IS_CA = "isCA";
+ public final static String PR_CERT_LEN = "certLen";
+ public final static String PR_SSL_CLIENT_BIT = "sslClientBit";
+ public final static String PR_SSL_SERVER_BIT = "sslServerBit";
+ public final static String PR_SSL_MAIL_BIT = "sslMailBit";
+ public final static String PR_SSL_CA_BIT = "sslCABit";
+ public final static String PR_OBJECT_SIGNING_BIT = "objectSigningBit";
+ public final static String PR_MAIL_CA_BIT = "mailCABit";
+ public final static String PR_OBJECT_SIGNING_CA_BIT = "objectSigningCABit";
+ public final static String PR_TIMESTAMPING_BIT = "timeStampingBit";
+ public final static String PR_CA_KEYID = "caKeyid";
+ public final static String PR_CA_KEYPAIR = "caKeyPair";
+
+ /**
+ * Trust database
+ */
+ public final static String PR_TRUST = "trust";
+
+ /*========================================================
+ * Security
+ *========================================================*/
+
+ //functionality
+ public final static String PR_CERT_SERVER = "SERVER";
+ public final static String PR_CERT_ADMIN = "ADMIN";
+ public final static String PR_CERT_AGENT = "AGENT";
+ public final static String PR_CERT_EE = "EE";
+ public final static String PR_CERT_CA = "CA";
+ public final static String PR_CERT_RA = "RA";
+ public final static String PR_CERT_POA = "POA";
+ public final static String PR_CERT_TRANS = "TRANS";
+
+ // key and certificate management
+ public final static String PR_OPERATION_TYPE = "operationtype";
+ public final static String PR_INSTALL_TYPE = "install";
+ public final static String PR_REQUEST_TYPE = "request";
+ //public final static String PR_CA_SIGNING_CERT = "cacert";
+ //public final static String PR_SERVER_CERT = "servercert";
+ public final static String PR_CLIENT_CERT = "clientcert";
+ public final static String PR_FULL_INTERNAL_TOKEN_NAME="Internal Key Storage Token";
+ public final static String PR_INTERNAL_TOKEN_NAME =
+ "internal";
+ public final static String PR_TOKEN_NAME = "tokenName";
+ public final static String PR_TOKEN_PASSWD = "tokenPwd";
+ public final static String PR_KEY_LENGTH = "keyLength";
+ public final static String PR_KEY_CURVENAME = "keyCurveName";
+ public static final String PR_SIGNEDBY_TYPE = "signedBy";
+ public final static String PR_KEY_TYPE = "keyType";
+ public final static String PR_PQGPARAMS = "pqgParams";
+ public final static String PR_CERT_REQUEST = "certReq";
+ public final static String PR_CERT_REQUEST_DIR = "certReqDir";
+ public final static String PR_CERT_CONFIG_DIR = "certConfigDir";
+ public final static String PR_IMPORT_CERT = "importCert";
+ public final static String PR_SUBJECT_NAME = "subjectName";
+ public final static String PR_CSR = "csr";
+
+ //encryption
+
+ /* Cipher Version: domestic or export */
+ public final static String PR_CIPHER_VERSION = "cipherversion";
+ public final static String PR_CIPHER_VERSION_DOMESTIC = "cipherdomestic";
+ public final static String PR_CIPHER_VERSION_EXPORT = "cipherexport";
+
+ /* Cipher Fortezza: true, false */
+ public final static String PR_CIPHER_FORTEZZA = "cipherfortezza";
+
+ /* Token and Certificates */
+ public final static String PR_TOKEN_LIST = "tokenlist";
+ public final static String PR_TOKEN_PREFIX = "token_";
+ public final static String PR_INTERNAL_TOKEN = "internal";
+ public final static String PR_KEY_LIST = "keylist";
+
+ /* SSL Cipher Preferences */
+ public final static String PR_CIPHER_PREF = "cipherpref";
+
+ /* SSL EC Type */
+ public final static String PR_ECTYPE = "ectype";
+
+ /* values for SSL cipher preferences */
+ public final static String
+ PR_SSL2_RC4_128_WITH_MD5 = "rc4";
+ public final static String
+ PR_SSL2_RC4_128_EXPORT40_WITH_MD5 = "rc4export";
+ public final static String
+ PR_SSL2_RC2_128_CBC_WITH_MD5 = "rc2";
+ public final static String
+ PR_SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 = "rc2export";
+ public final static String
+ PR_SSL2_DES_64_CBC_WITH_MD5 = "des";
+ public final static String
+ PR_SSL2_DES_192_EDE3_CBC_WITH_MD5 = "desede3";
+ public final static String
+ PR_SSL3_RSA_WITH_NULL_MD5 = "rsa_null_md5";
+ public final static String
+ PR_SSL3_RSA_EXPORT_WITH_RC4_40_MD5 = "rsa_rc4_40_md5";
+ public final static String
+ PR_SSL3_RSA_WITH_RC4_128_MD5 = "rsa_rc4_128_md5";
+ public final static String
+ PR_SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = "rsa_rc2_40_md5";
+ public final static String
+ PR_SSL3_RSA_WITH_DES_CBC_SHA = "rsa_des_sha";
+ public final static String
+ PR_SSL3_RSA_WITH_3DES_EDE_CBC_SHA = "rsa_3des_sha";
+ public final static String
+ PR_SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA = "fortezza";
+ public final static String
+ PR_SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA = "fortezza_rc4_128_sha";
+ public final static String
+ PR_SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA = "rsa_fips_3des_sha";
+ public final static String
+ PR_SSL_RSA_FIPS_WITH_DES_CBC_SHA = "rsa_fips_des_sha";
+ public final static String
+ PR_TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = "tls_rsa_rc4_56_sha";
+ public final static String
+ PR_TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = "tls_rsa_des_sha";
+
+ /*========================================================
+ * Watchdog and Server State Messages
+ *========================================================*/
+
+ public final static String SERVER_STARTUP_WARNING_MESSAGE = "CMS Warning: ";
+ public final static String SERVER_STARTUP_MESSAGE = "Server is started.";
+ public final static String SERVER_SHUTDOWN_MESSAGE = "Shutting down.";
+ public final static String SERVER_SHUTDOWN_ERROR_MESSAGE = "Error Starting CMS: ";
+ public final static String SERVER_SHUTDOWN_EXTENDED_ERROR_MESSAGE = "Extended error information: ";
+
+ /*============================================================
+ * THE FOLLOWING LIST WILL BE REMOVED
+ *============================================================*/
+
+ // parameter types
+ public final static String PT_OP = "op";
+ public final static String PT_MOD_TYPE = "modType";
+ public final static String PT_MOD_OP = "modOp";
+ public final static String MOD_REPLACE = "modOpReplace";
+ public final static String MOD_ADD = "modOpAdd";
+ public final static String MOD_DELETE = "modOpDelete";
+ public final static String PT_MOD_VALUE = "modValue";
+
+ // generic operations
+ public final static String OP_SET = "set";
+ public final static String OP_GET = "get";
+ public final static String OP_LIST = "list";
+
+ // certificate server operations
+ public final static String CERTSRV_ID = "certsrv";
+
+ public final static String PT_PORT = "http.http.port";
+ public final static String PT_SSL_PORT = "http.https.port";
+ public final static String PT_MAPPING = "mapping";
+ public final static String PT_DN = "dn";
+
+ public final static String PV_SYSTEM_ADMINISTRATORS =
+ "SystemAdministrators";
+ public final static String PV_CERTIFICATE_ADMINISTRATORS =
+ "CertificateAdministrators";
+
+ public final static String OP_AUTHENTICATE = "authenticate";
+ public final static String OP_RESTART = "restart";
+ public final static String OP_STOP = "stop";
+
+ // access manager operation
+ public final static String PT_ACLS = "acls";
+ public final static String OP_GET_ACLS = "getACLs";
+
+ // authentication operations
+ public final static String AUTH_ID = "auth";
+ public final static String OP_FIND_USERS = "findUsers";
+ public final static String OP_FIND_GROUPS = "findGroups";
+ public final static String OP_GET_USER = "getUser";
+ public final static String OP_GET_GROUP = "getGroup";
+ public final static String OP_ADD_USER = "addUser";
+ public final static String OP_ADD_GROUP = "addGroup";
+ public final static String OP_MODIFY_USER = "modifyUser";
+ public final static String OP_MODIFY_GROUP = "modifyGroup";
+
+ public final static String PT_USER = "user";
+ public final static String PT_GROUP = "group";
+
+ // common operations
+ public final static String OP_LOCK_REQUEST = "lockRequest";
+ public final static String OP_MODIFY_REQUEST = "modifyRequest";
+ public final static String OP_EXECUTE_REQUEST = "executeRequest";
+ public final static String OP_ACCEPT_REQUEST = "acceptRequest";
+ public final static String OP_REJECT_REQUEST = "rejectRequest";
+ public final static String OP_CANCEL_REQUEST = "cancelRequest";
+
+ // certificate authority operations
+ public final static String PT_PUBLISH_DN = "ldappublish.ldap.admin-dn";
+ public final static String PT_PUBLISH_PWD =
+ "ldappublish.ldap.admin-password";
+ public final static String PT_PUBLISH_FREQ =
+ "crl.crl0.autoUpdateInterval";
+ public final static String PT_SERIALNO = "serialno";
+ public final static String PT_NAMES = "names";
+ public final static String PT_CERTIFICATES = "certificates";
+ public final static String PT_CERT_RECORDS = "certRecords";
+ public final static String PT_REQUESTS = "requests";
+ public final static String PT_REQUEST = "request";
+ public final static String PT_EXTENSIONS = "extensions";
+ public final static String PT_FILTER = "filter";
+ public final static String PT_ATTRS = "attrs";
+ public final static String PT_RESULT_ID = "resultId";
+ public final static String PT_START_NO = "startNo";
+ public final static String PT_END_NO = "endNo";
+ public final static String PT_SIZE = "size";
+ public final static String PT_RELEASE = "release";
+ public final static String PT_CERTREC = "certrec";
+ public final static String PT_COMMENT = "comment";
+ public final static String PT_REASON_NO = "reasonNo";
+
+ public final static String OP_CRL_PUBLISH = "publish_now";
+ public final static String OP_FIND_CERTIFICATES = "findCertificates";
+ public final static String OP_FIND_CERT_RECORDS = "findCertRecords";
+ public final static String OP_FIND_REQUESTS = "findRequests";
+ public final static String OP_LOCK_CERT_RECORD = "lockCertRecord";
+ public final static String OP_MODIFY_CERT_RECORD = "modifyCertRecord";
+ public final static String OP_GET_EXTENSIONS = "getExtensions";
+ public final static String OP_REVOKE_CERT = "revokeCert";
+ public final static String OP_RENEW_CERT = "renewCert";
+ public final static String OP_GET_CACERT_CHAIN = "getCACertChain";
+
+ // escrow authority operations
+ public final static String PT_OLD_PASSWORD = "oldpassword";
+ public final static String PT_NEW_PASSWORD = "newpassword";
+ public final static String PT_KEY_RECORD = "keyRecord";
+
+ public final static String OP_FIND_KEY_RECORDS = "findKeyRecords";
+ public final static String OP_LOCK_KEY_RECORD = "lockKeyRecord";
+ public final static String OP_MODIFY_KEY_RECORD = "modifyKeyRecord";
+ public final static String OP_RECOVER_KEY = "recoverKey";
+
+ // centralized cetificate management operations
+ public final static String PT_NOTIF_EMAIL = "notificationEmail";
+ public final static String PT_NOTIF_ENABLE = "notificationEnable";
+ public final static String PT_NOTIF_EXPIRE = "notificationExpiration";
+ public final static String PT_NOTIF_RENEWAL = "notificationRewnewal";
+ public final static String PT_DIST_STORE = "storeUserPassword";
+ public final static String PT_DIST_EMAIL = "emailUserPassword";
+ public final static String PT_REQUEST_LOG = "requestLog";
+ public final static String PT_ACCESS_LOG = "accessLog";
+ public final static String PT_ERROR_LOG = "errorLog";
+ public final static String PR_NT_EVENT_SOURCE = "NTEventSourceName";
+ public final static String PR_NT_LOG_LEVEL = "level";
+ public final static String PR_NT_LOG_ENABLED = "on";
+
+ public final static String OP_GET_ACCESS_LOG = "getAccessLog";
+ public final static String OP_GET_ERROR_LOG = "getErrorLog";
+ public final static String OP_GET_REQUEST_LOG = "getRequestLog";
+
+ public final static String PR_NICK_NAME = "nickName"; // capital N
+ public final static String PR_LOGGED_IN = "isLoggedIn";
+
+ // User Type
+ public final static String PR_USER_TYPE = "userType";
+ public final static String PR_ADMIN_TYPE = "adminType";
+ public final static String PR_AGENT_TYPE = "agentType";
+ public final static String PR_SUBSYSTEM_TYPE = "subsystemType";
+
+ // Extended plugin information
+ public final static String PR_EXT_PLUGIN_IMPLNAME = "implName";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE = "implType";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_POLICY = "policy";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_JOBS = "jobs";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_AUTH = "auth";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_LISTENER = "listener";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_PUBLISHRULE = "publishrule";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_PUBLISHER = "publisher";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_MAPPER = "mapperrule";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_CRLEXTSRULE = "crlExtensions";
+ public final static String PR_EXT_PLUGIN_IMPLTYPE_OCSPSTORESRULE = "ocspStores";
+
+ // Miscellaneous
+ public final static String PR_CERT_FILEPATH = "certFilePath";
+ public final static String PR_SERVER_ROOT = "serverRoot";
+ public final static String PR_SERVER_ID = "serverID";
+ public final static String PR_NT = "NT";
+ public final static String PR_TIMEOUT = "timeout";
+ public final static String PR_ALL_NICKNAMES = "allNicknames";
+
+ // request status
+ public final static String PR_REQUEST_SUCCESS = "2";
+ public final static String PR_REQUEST_PENDING = "3";
+ public final static String PR_REQUEST_SVC_PENDING = "4";
+ public final static String PR_REQUEST_REJECTED = "5";
+
+ //Profile
+ public final static String PR_CONSTRAINTS_LIST = "constraintPolicy";
+
+ //Replication
+ public final static String PR_REPLICATION_ENABLED = "replication.enabled";
+ public final static String PR_REPLICATION_AGREEMENT_NAME_1 = "replication.master1.name";
+ public final static String PR_REPLICATION_HOST_1 = "replication.master1.hostname";
+ public final static String PR_REPLICATION_PORT_1 = "replication.master1.port";
+ public final static String PR_REPLICATION_BINDDN_1 = "replication.master1.binddn";
+ public final static String PR_REPLICATION_CHANGELOGDB_1 = "replication.master1.changelogdb";
+ public final static String PR_REPLICATION_AGREEMENT_NAME_2 = "replication.master2.name";
+ public final static String PR_REPLICATION_HOST_2 = "replication.master2.hostname";
+ public final static String PR_REPLICATION_PORT_2 = "replication.master2.port";
+ public final static String PR_REPLICATION_BINDDN_2 = "replication.master2.binddn";
+ public final static String PR_REPLICATION_CHANGELOGDB_2 = "replication.master2.changelogdb";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/DestDef.java b/pki/base/common/src/com/netscape/certsrv/common/DestDef.java
new file mode 100644
index 000000000..1d3eaff14
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/DestDef.java
@@ -0,0 +1,57 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface defines all the operation destination
+ * used in the administration protocol between the
+ * console and the server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface DestDef {
+
+ public final static String DEST_CA_ADMIN = "caadmin";
+ public final static String DEST_OCSP_ADMIN = "ocsp";
+ public final static String DEST_RA_ADMIN = "ra";
+ public final static String DEST_KRA_ADMIN = "kra";
+ public final static String DEST_CA_SERVLET_ADMIN = "caservlet";
+ public final static String DEST_KRA_SERVLET_ADMIN = "kraservlet";
+ public final static String DEST_RA_SERVLET_ADMIN = "raservlet";
+ public final static String DEST_REGISTRY_ADMIN = "registry";
+ public final static String DEST_CA_PROFILE_ADMIN = "caprofile";
+ public final static String DEST_RA_PROFILE_ADMIN = "raprofile";
+ public final static String DEST_CA_POLICY_ADMIN = "capolicy";
+ public final static String DEST_RA_POLICY_ADMIN = "rapolicy";
+ public final static String DEST_KRA_POLICY_ADMIN = "krapolicy";
+ public final static String DEST_LOG_ADMIN = "log";
+ public final static String DEST_GROUP_ADMIN = "ug";
+ public final static String DEST_USER_ADMIN = "ug";
+ public final static String DEST_AUTH_ADMIN = "auths";
+ public final static String DEST_JOBS_ADMIN = "jobsScheduler";
+ public final static String DEST_NOTIFICATION_ADMIN = "notification";
+ public final static String DEST_SERVER_ADMIN = "server";
+ public final static String DEST_ACL_ADMIN = "acl";
+ public final static String DEST_CA_PUBLISHER_ADMIN = "capublisher";
+ public final static String DEST_RA_PUBLISHER_ADMIN = "rapublisher";
+ public final static String DEST_CA_MAPPER_ADMIN = "camapper";
+ public final static String DEST_RA_MAPPER_ADMIN = "ramapper";
+ public final static String DEST_CA_RULE_ADMIN = "carule";
+ public final static String DEST_RA_RULE_ADMIN = "rarule";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/NameValuePair.java b/pki/base/common/src/com/netscape/certsrv/common/NameValuePair.java
new file mode 100644
index 000000000..92466d30d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/NameValuePair.java
@@ -0,0 +1,77 @@
+// --- 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.certsrv.common;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+
+
+/**
+ * A class represents a name value pair. A name value
+ * pair consists of a name and a value.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NameValuePair {
+
+ private String mName = null;
+ private String mValue = null;
+
+ /**
+ * Constructs value pair object.
+ *
+ * @param name name
+ * @param value value
+ */
+ public NameValuePair(String name, String value) {
+ mName = name;
+ mValue = value;
+ }
+
+ /**
+ * Retrieves the name.
+ *
+ * @return name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Retrieves the value.
+ *
+ * @return value
+ */
+ public String getValue() {
+ return mValue;
+ }
+
+ /**
+ * Sets the value
+ *
+ * @param value value
+ */
+ public void setValue(String value) {
+ mValue = value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/NameValuePairs.java b/pki/base/common/src/com/netscape/certsrv/common/NameValuePairs.java
new file mode 100644
index 000000000..a2530521a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/NameValuePairs.java
@@ -0,0 +1,191 @@
+// --- 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.certsrv.common;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+
+
+/**
+ * A class represents an ordered list of name
+ * value pairs.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NameValuePairs {
+
+ private Vector mPairs = new Vector();
+
+ // an index to speed up searching
+ // The key is the name. The element is the NameValuePair.
+ private Hashtable index = new Hashtable();
+
+ /**
+ * Constructs name value pairs.
+ */
+ public NameValuePairs() {
+ }
+
+ /**
+ * Adds a name value pair into this set.
+ * if the name already exist, the value will
+ * be replaced.
+ *
+ * @param name name
+ * @param value value
+ */
+ public void add(String name, String value) {
+ NameValuePair pair = getPair(name);
+
+ if (pair == null) {
+ pair = new NameValuePair(name, value);
+ mPairs.addElement(pair);
+ index.put(name, pair);
+ } else {
+ pair.setValue(value);
+ }
+ }
+
+ /**
+ * Retrieves name value pair from this set.
+ *
+ * @param name name
+ * @return name value pair
+ */
+ public NameValuePair getPair(String name) {
+ return (NameValuePair) index.get(name);
+ }
+
+ /**
+ * Returns number of pairs in this set.
+ *
+ * @return size
+ */
+ public int size() {
+ return mPairs.size();
+ }
+
+ /**
+ * Retrieves name value pairs in specific position.
+ *
+ * @param pos position of the value
+ * @return name value pair
+ */
+ public NameValuePair elementAt(int pos) {
+ return (NameValuePair) mPairs.elementAt(pos);
+ }
+
+ /**
+ * Removes all name value pairs in this set.
+ */
+ public void removeAllPairs() {
+ mPairs.removeAllElements();
+ index.clear();
+ }
+
+ /**
+ * Retrieves value of the name value pairs that matches
+ * the given name.
+ *
+ * @param name name
+ * @return value
+ */
+ public String getValue(String name) {
+ NameValuePair p = getPair(name);
+
+ if (p != null) {
+ return p.getValue();
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves a list of names.
+ *
+ * @return a list of names
+ */
+ public Enumeration getNames() {
+ Vector v = new Vector();
+ int size = mPairs.size();
+
+ for (int i = 0; i < size; i++) {
+ NameValuePair p = (NameValuePair) mPairs.elementAt(i);
+
+ v.addElement(p.getName());
+ }
+ //System.out.println("getNames: "+v.size());
+ return v.elements();
+ }
+
+ /**
+ * Show the content of this name value container as
+ * string representation.
+ *
+ * @return string representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 0; i < mPairs.size(); i++) {
+ NameValuePair p = (NameValuePair) mPairs.elementAt(i);
+
+ buf.append(p.getName() + "=" + p.getValue());
+ buf.append("\n");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Parses a string into name value pairs.
+ *
+ * @param s string
+ * @param nvp name value pairs
+ * @return true if successful
+ */
+ public static boolean parseInto(String s, NameValuePairs nvp) {
+ StringTokenizer st = new StringTokenizer(s, "&");
+
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ int i = t.indexOf("=");
+
+ if (i == -1) {
+ return false;
+ }
+ String n = t.substring(0, i);
+ String v = t.substring(i + 1);
+
+ nvp.add(n, v);
+ }
+ return true;
+ }
+
+ /**
+ * Returns a list of name value pair object.
+ *
+ * @return name value objects
+ */
+ public Enumeration elements() {
+ return mPairs.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/OpDef.java b/pki/base/common/src/com/netscape/certsrv/common/OpDef.java
new file mode 100644
index 000000000..9cfcab4a2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/OpDef.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface defines all the administration operations
+ * used in the administration protocol between the console
+ * and the server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface OpDef {
+
+ public final static String OP_ADD = "OP_ADD";
+ public final static String OP_DELETE = "OP_DELETE";
+ public final static String OP_MODIFY = "OP_MODIFY";
+ public final static String OP_READ = "OP_READ";
+ public final static String OP_SEARCH = "OP_SEARCH";
+ public final static String OP_AUTH = "OP_AUTH";
+ public final static String OP_JOBS = "OP_JOBS";
+ public final static String OP_PROCESS = "OP_PROCESS";
+ public final static String OP_VALIDATE = "OP_VALIDATE";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/PrefixDef.java b/pki/base/common/src/com/netscape/certsrv/common/PrefixDef.java
new file mode 100644
index 000000000..11a58c5d2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/PrefixDef.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface defines all the prefix tags
+ * used in the administration protocol between
+ * the console and the server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface PrefixDef {
+
+ //user and group
+ public final static String PX_GROUP = "group";
+ public final static String PX_USER = "user";
+ public final static String PX_CERT = "cert";
+ public final static String PX_SYS = "SYS_";
+ public final static String PX_DEF = "DEF_";
+ public final static String PX_PP = "CERT_PP";
+
+ //log content
+ public final static String PX_LOG = "log";
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/ScopeDef.java b/pki/base/common/src/com/netscape/certsrv/common/ScopeDef.java
new file mode 100644
index 000000000..0be3fdf0a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/ScopeDef.java
@@ -0,0 +1,193 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface defines all the operation scope
+ * used in the administration protocol between the
+ * console and the server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ScopeDef {
+
+ // users and groups
+ public final static String SC_GROUPS = "groups";
+ public final static String SC_USERS = "users";
+ public final static String SC_USER_CERTS = "certs";
+
+ public final static String SC_SNMP = "snmp";
+ public final static String SC_SMTP = "smtp";
+ public final static String SC_SUBSYSTEM = "subsystem";
+ public final static String SC_ENCRYPTION = "encryption";
+ public final static String SC_GATEWAY = "gateway";
+ public final static String SC_ADMIN = "admin";
+ public final static String SC_NETWORK = "network";
+
+ // profile
+ public final static String SC_PROFILE_IMPLS = "profile";
+ public final static String SC_PROFILE_RULES = "rules";
+ public final static String SC_PROFILE_DEFAULT_POLICY = "defaultPolicy";
+ public final static String SC_PROFILE_CONSTRAINT_POLICY = "constraintPolicy";
+ public final static String SC_PROFILE_POLICIES = "policies";
+ public final static String SC_PROFILE_POLICY_CONFIG = "config";
+ public final static String SC_PROFILE_INPUT = "profileInput";
+ public final static String SC_PROFILE_INPUT_CONFIG = "profileInputConfig";
+ public final static String SC_PROFILE_OUTPUT = "profileOutput";
+ public final static String SC_PROFILE_OUTPUT_CONFIG = "profileOutputConfig";
+
+ // policy management
+ public final static String SC_POLICY_RULES = "rules";
+ public final static String SC_POLICY_IMPLS = "impls";
+ public final static String SC_POLICY_CRLDPS = "crldps";
+
+ // publisher management
+ public final static String SC_PUBLISHER_RULES = "publisherRules";
+ public final static String SC_PUBLISHER_IMPLS = "publisherImpls";
+ public final static String SC_MAPPER_RULES = "mapperRules";
+ public final static String SC_MAPPER_IMPLS = "mapperImpls";
+ public final static String SC_RULE_RULES = "ruleRules";
+ public final static String SC_RULE_IMPLS = "ruleImpls";
+
+ // self tests
+ public final static String SC_SELFTESTS = "selftests";
+
+ // log config
+ public final static String SC_AUDITLOG = "transactionsLog";
+ public final static String SC_NTAUDITLOG = "ntTransactionsLog";
+ public final static String SC_ERRORLOG = "errorLog";
+ public final static String SC_SYSTEMLOG = "systemLog";
+ public final static String SC_NTSYSTEMLOG = "ntSystemLog";
+ public final static String SC_LOG_ARCH = "logArch";
+ public final static String SC_LOG_RULES = "logRule";
+ public final static String SC_LOG_IMPLS = "logImpls";
+
+ // log contents
+ public final static String SC_LOG_INSTANCES = "log_instances";
+ public final static String SC_LOG_CONTENT = "log_content";
+ public final static String SC_AUDITLOG_CONTENT = "transactionsLog_content";
+ public final static String SC_ERRORLOG_CONTENT = "errorLog_content";
+ public final static String SC_SYSTEMLOG_CONTENT = "systemLog_content";
+
+ //LDAP publishing
+ public final static String SC_LDAP = "ldap";
+ public final static String SC_CRL = "crl";
+ public final static String SC_USERCERT = "userCert";
+ public final static String SC_CACERT = "caCert";
+ public final static String SC_CAMAPPER = "caMapper";
+ public final static String SC_CAPUBLISHER = "caPublisher";
+ public final static String SC_USERMAPPER = "userMapper";
+ public final static String SC_USERPUBLISHER = "userPublisher";
+
+ // CRL issuing points
+ public final static String SC_CRLIPS = "crlIPs";
+
+ // CRL extensions
+ public final static String SC_CRLEXTS_RULES = "crlExtsRules";
+
+ public final static String SC_OCSPSTORES_RULES = "ocspStoresRules";
+ public final static String SC_OCSPSTORE_DEFAULT = "ocspStoreDef";
+
+ // KRA
+ public final static String SC_AUTO_RECOVERY = "autoRecovery";
+ public final static String SC_RECOVERY = "recovery";
+ public final static String SC_AGENT_PWD = "agentPwd";
+ public final static String SC_MNSCHEME = "mnScheme";
+
+ //stat
+ public final static String SC_STAT = "stat";
+
+ // RA
+ public final static String SC_GENERAL = "general";
+ public final static String SC_CLM = "clm";
+ public final static String SC_PKIGW = "pkigw";
+ public final static String SC_SERVLET = "servlet";
+ public final static String SC_CONNECTOR = "connector";
+
+ //tasks
+ public final static String SC_TASKS = "tasks";
+
+ //authentication
+ public final static String SC_AUTH = "auths";
+ public final static String SC_AUTHTYPE = "authType";
+ public final static String SC_AUTH_IMPLS = "impl";
+ public final static String SC_AUTH_MGR_INSTANCE = "instance";
+
+ //jobs scheduler
+ public final static String SC_JOBS = "jobScheduler";
+ public final static String SC_JOBS_IMPLS = "impl";
+ public final static String SC_JOBS_INSTANCE = "job";
+ public final static String SC_JOBS_RULES = "rules";
+
+ //notification
+ public final static String SC_NOTIFICATION_REQ_COMP = "notificationREQC";
+ public final static String SC_NOTIFICATION_REV_COMP = "notificationREVC";
+ public final static String SC_NOTIFICATION_RIQ = "notificationRIQ";
+
+ // acl
+ public final static String SC_ACL_IMPLS = "impl";
+ public final static String SC_ACL = "acls";
+ public final static String SC_EVALUATOR_TYPES = "evaluatorTypes";
+
+ // token
+ public final static String SC_TOKEN = "token";
+
+ // keycert
+ public final static String SC_CA_SIGNINGCERT = "caSigningCert";
+ public final static String SC_RA_SIGNINGCERT = "raSigningCert";
+ public final static String SC_KRA_TRANSPORTCERT = "kraTransportCert";
+ public final static String SC_SERVER_CERT = "serverCert";
+ public final static String SC_SERVER_CERTCHAIN = "serverCertChain";
+ public final static String SC_TRUSTED_CACERT = "trustedCACert";
+ public final static String SC_TRUSTED_CERT = "trustedCert";
+ public final static String SC_SUBJECT_NAME = "subjectName";
+ public final static String SC_CERTINFO = "certInfo";
+ public final static String SC_CERT_REQUEST = "certRequest";
+ public final static String SC_ISSUE_IMPORT_CERT = "issueImportCert";
+ public final static String SC_INSTALL_CERT = "installCert";
+ public final static String SC_IMPORT_CROSS_CERT = "importXCert";
+ public final static String SC_CA_CERTLIST = "caCertList";
+ public final static String SC_ALL_CERTLIST = "allCertList";
+ public final static String SC_DELETE_CERTS = "deleteCert";
+ public final static String SC_CERT_PRETTY_PRINT = "certPrint";
+ public final static String SC_TRUST = "trust";
+
+ // Key Pair
+ public final static String SC_KEY_LENGTH = "keyLength";
+ public final static String SC_KEY_CURVENAME = "keyCurveName";
+ public final static String SC_CERTIFICATE_EXTENSION = "certificateExt";
+ public final static String SC_TOKEN_STATUS = "tokenStatus";
+ public final static String SC_TOKEN_LOGON = "tokenLogon";
+
+ public final static String SC_EXTENDED_PLUGIN_INFO = "extendedPluginInfo";
+
+ public final static String SC_USER_TYPE = "userType";
+ public final static String SC_PLATFORM = "platform";
+
+ public final static String SC_GET_NICKNAMES = "getNicknames";
+
+ // Profile
+ public final static String SC_SUPPORTED_CONSTRAINTPOLICIES = "supportedConstraintPolicies";
+
+ // Manage certificate admin
+ public final static String SC_USERCERTSLIST = "userCertsList";
+ public final static String SC_TKSKEYSLIST = "tksKeysList";
+ public final static String SC_ROOTCERTSLIST = "rootCertsList";
+ public final static String SC_ROOTCERT_TRUSTBIT = "rootTrustBit";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/common/TaskId.java b/pki/base/common/src/com/netscape/certsrv/common/TaskId.java
new file mode 100644
index 000000000..458822ff5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/common/TaskId.java
@@ -0,0 +1,130 @@
+// --- 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.certsrv.common;
+
+
+/**
+ * This interface defines all the tasks used in
+ * the configuration protocol between the
+ * configuration wizard and the configuration
+ * daemon.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface TaskId {
+
+ // list out all the previously performed tasks
+ public final static String TASK_LIST_PREVIOUS_STAGES = "listPreviousStages";
+
+ // retrieve all information in the previously performed tasks
+ public final static String TASK_GET_DEFAULT_INFO = "getStagesInfo";
+
+ // retrieve all information to setup the wizardInfo
+ public final static String TASK_SETUP_WIZARDINFO = "setupWizardInfo";
+
+ // services to be installed: ca, kra, ra
+ public final static String TASK_INSTALL_SUBSYSTEMS = "installSubsystems";
+
+ // create the internal database
+ public final static String TASK_CREATE_INTERNALDB = "createInternalDB";
+
+ // configure network ports
+ public final static String TASK_CONFIGURE_NETWORK = "configureNetwork";
+
+ // setup certificate administrator
+ public final static String TASK_SETUP_ADMINISTRATOR = "setupAdmin";
+
+ // select subsystems
+ public final static String TASK_SELECT_SUBSYSTEMS = "selectSubsystems";
+
+ // data migration
+ public final static String TASK_MIGRATION = "migration";
+
+ // create certificate
+ public final static String TASK_CREATE_CERT = "createCert";
+
+ // kra storage key
+ public final static String TASK_STORAGE_KEY = "storageKey";
+
+ // kra agents
+ public final static String TASK_AGENTS = "agents";
+
+ // get information about all cryptotokens
+ public final static String TASK_TOKEN_INFO = "tokenInfo";
+
+ // server get master or clone setting
+ public final static String TASK_MASTER_OR_CLONE = "SetMasterOrClone";
+ // single signon
+ public final static String TASK_SINGLE_SIGNON = "singleSignon";
+
+ // init token
+ public final static String TASK_INIT_TOKEN = "initToken";
+
+ // certificate request
+ public final static String TASK_CERT_REQUEST = "certRequest";
+
+ // certificate request submited successfully
+ public final static String TASK_REQUEST_SUCCESS = "reqSuccess";
+
+ // certificate content
+ public final static String TASK_GET_CERT_CONTENT = "certContent";
+
+ public final static String TASK_IMPORT_CERT_CHAIN = "importCertChain";
+
+ // install certificate
+ public final static String TASK_INSTALL_CERT = "installCert";
+
+ public final static String TASK_CHECK_DN = "checkDN";
+
+ // miscellaneous things
+ public final static String TASK_MISCELLANEOUS = "doMiscStuffs";
+
+ // validate directory manager password
+ public final static String TASK_VALIDATE_DSPASSWD = "validateDSPassword";
+
+ // set CA starting serial number
+ public final static String TASK_SET_CA_SERIAL = "setCASerial";
+
+ // set CA starting serial number
+ public final static String TASK_SET_KRA_NUMBER = "setKRANumber";
+
+ // check key length
+ public final static String TASK_CHECK_KEYLENGTH = "checkKeyLength";
+
+ // check certificate extension
+ public final static String TASK_CHECK_EXTENSION = "checkExtension";
+
+ // check validity period: make sure the notAfterDate of the certificate
+ // will not go beyond the notAfterDate of the CA cert which signs the certificate.
+ public final static String TASK_VALIDITY_PERIOD = "checkValidityPeriod";
+
+ public final static String TASK_CLONING = "taskCloning";
+ public final static String TASK_CLONE_MASTER = "taskCloneMaster";
+
+ // daemon exit
+ public final static String TASK_EXIT = "exit";
+
+ public final static String TASK_ADD_OCSP_SERVICE = "addOCSPService";
+
+ public final static String TASK_CONFIG_WEB_SERVER = "configWebServer";
+
+ public final static String TASK_CREATE_REPLICATION_AGREEMENT = "createReplAgreement";
+ public final static String TASK_LOGON_ALL_TOKENS = "logonAllTokens";
+ public final static String TASK_UPDATE_DB_INFO = "updateDBInfo";
+ public final static String TASK_ADD_DBSCHEMA_INDEXES = "addDBSchemaIndexes";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IConnector.java b/pki/base/common/src/com/netscape/certsrv/connector/IConnector.java
new file mode 100644
index 000000000..e89c14f57
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IConnector.java
@@ -0,0 +1,62 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This interface represents a connector that forwards
+ * CMS requests to a remote authority.
+ *
+ * To register a connector, one can add the following
+ * to the CMS.cfg:
+ *
+ * <pre>
+ *
+ * Example for KRA type connector.
+ * ca.connector.KRA.enable=true
+ * ca.connector.KRA.host=thehost.netscape.com #Remote host.
+ * ca.connector.KRA.port=1974 #Remote host port.
+ * ca.connector.KRA.nickName="cert-kra" #Nickname of connector for identity purposes.
+ * ca.connector.KRA.uri="/kra/connector" #Uri of the KRA server.
+ * ca.connector.KRA.id="kra"
+ * ca.connector.KRA.minHttpConns=1 #Min connection pool connections.
+ * ca.connector.KRA.maxHttpConns=10 #Max connection pool connections.
+ * </pre>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConnector {
+
+ /**
+ * Sends the request to a remote authority.
+ * @param req Request to be forwarded to remote authority.
+ * @return true for success, otherwise false.
+ * @exception EBaseException Failure to send request to remote authority.
+ */
+ public boolean send(IRequest req)
+ throws EBaseException;
+
+ /**
+ * Starts this connector.
+ */
+ public void start();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java b/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java
new file mode 100644
index 000000000..a52d90e94
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.connector;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.connector.*;
+
+/**
+ * Maintains a pool of connections to to a Remote Authority.
+ * Utilized by the IHttpConnector interface.
+ * Multiple threads use this interface to utilize and release
+ * the Ldap connection resources. This factory will maintain a
+ * list of Http type connections to the remote host.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IHttpConnFactory {
+
+
+ /**
+ * Request access to a Ldap connection from the pool.
+ * @exception EBaseException if any error occurs, such as a
+ * @return Ldap connection object.
+ * connection is not available
+ */
+ public IHttpConnection getConn()
+ throws EBaseException;
+
+ /**
+ * Return connection to the factory. mandatory after a getConn().
+ * @param conn Ldap connection object to be returned to the free list of the pool.
+ * @exception EBaseException On any failure to return the connection.
+ */
+ public void returnConn(IHttpConnection conn)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java b/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java
new file mode 100644
index 000000000..610ab30ed
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java
@@ -0,0 +1,48 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import java.io.*;
+
+
+/**
+ * This represents a HTTP connection to a remote authority.
+ * Http connection is used by the connector to send
+ * PKI messages to a remote authority. The remote authority
+ * will reply with a PKI message as well. An example would
+ * be the communication between a CA and a KRA.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IHttpConnection {
+
+ /**
+ * Sends the PKI message to the remote authority.
+ * @param tomsg Message to forward to authority.
+ * @exception EBaseException Failed to send message.
+ */
+ public IPKIMessage send(IPKIMessage tomsg)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java b/pki/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java
new file mode 100644
index 000000000..83241170a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java
@@ -0,0 +1,59 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.connector.*;
+import java.util.*;
+import java.io.*;
+
+
+/**
+ * This represents a Http PKI message. It contains
+ * simple name/value pair values. Also maintains information
+ * about the status and type of the message.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IHttpPKIMessage extends IPKIMessage {
+
+ /**
+ * Retrieves the request type.
+ * @return String with the type of request.
+ */
+ public String getReqType();
+
+ /**
+ * Retrieves the request identifier.
+ * @return String of name of request.
+ */
+ public String getReqId();
+
+ /**
+ * Copies contents of request to make a simple name/value message.
+ * @param r Instance of IRequest to be copied from.
+ */
+ public void fromRequest(IRequest r);
+
+ /**
+ * Copies contents to request.
+ * @param r Instance of IRequest to be copied to.
+ */
+ public void toRequest(IRequest r);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java b/pki/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
new file mode 100644
index 000000000..593261d9e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
@@ -0,0 +1,68 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.certsrv.request.IRequest;
+import java.io.Serializable;
+
+
+/**
+ * Messages that are serialized and go over the wire.
+ * It must be serializable, and
+ * later will be inherited by CRMF message.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPKIMessage extends Serializable {
+
+ /**
+ *
+ * Returns status of request.
+ * @return String of request status.
+ */
+ public String getReqStatus();
+
+ /**
+ * Retrieves the request type.
+ * @return String of type of request.
+ */
+ public String getReqType();
+
+
+ /**
+ * Retrieves the request identifer.
+ * @return String of name of request.
+ */
+ public String getReqId();
+
+ /**
+ * Makes a PKIMessage from a request
+ * PKIMessage will be sent to wire.
+ * @param r Request to copy from.
+ */
+ public void fromRequest(IRequest r);
+
+ /**
+ * Copies contents of PKIMessage to the request
+ * PKIMessage is from the wire.
+ * @param r Request to copy to.
+ */
+ public void toRequest(IRequest r);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java b/pki/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java
new file mode 100644
index 000000000..90dcbaa26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java
@@ -0,0 +1,56 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This represents a remote authority that can be
+ * a certificate manager, or key recovery manager or
+ * some other manager.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRemoteAuthority {
+
+ /**
+ * Retrieves the host name of the remote Authority.
+ * @return String with the name of host of remote Authority.
+ */
+ public String getHost();
+
+ /**
+ * Retrieves the port number of the remote Authority.
+ * @return Int with port number of remote Authority.
+ */
+ public int getPort();
+
+ /**
+ * Retrieves the URI of the remote Authority.
+ * @return String with URI of remote Authority.
+ */
+ public String getURI();
+
+ /**
+ * Retrieves the timeout value for the connection to the remote Authority.
+ * @return In with remote Authority timeout value.
+ */
+ public int getTimeout();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java b/pki/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java
new file mode 100644
index 000000000..7838aa5eb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.connector;
+
+
+import java.io.IOException;
+
+
+/**
+ * This represents a rquest encoder that serializes and
+ * deserializes a request to a Remote Authority so that it can be sent through
+ * the connector.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRequestEncoder {
+
+ /**
+ * Encodes a request object.
+ * @param r Object to serve as the source of the message.
+ * @return String containing encoded message.
+ * @exception IOException Failure of the encoding operation due to IO error.
+ */
+ String encode(Object r)
+ throws IOException;
+
+ /**
+ * Dncodes a String into an object.
+ * @return Object which is the result of the decoded message.
+ * @exception IOException Failure of the decoding operation due to IO error.
+ */
+ Object decode(String s)
+ throws IOException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/connector/IResender.java b/pki/base/common/src/com/netscape/certsrv/connector/IResender.java
new file mode 100644
index 000000000..b9305816e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/connector/IResender.java
@@ -0,0 +1,51 @@
+// --- 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.certsrv.connector;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.http.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.*;
+
+
+/**
+ * Resend requests at intervals to the server to ensure completion of requests.
+ * Default interval is 5 minutes. The need to resend a message could arise
+ * due to an error or the fact that the message could not be serviced
+ * immediately.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IResender extends Runnable {
+
+ /**
+ * Adds the request to the resend queue.
+ * @param r Request to be placed on the resend queue.
+ */
+ public void addRequest(IRequest r);
+
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/DBResources.java b/pki/base/common/src/com/netscape/certsrv/dbs/DBResources.java
new file mode 100644
index 000000000..54e65ce30
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/DBResources.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for DBS subsystem.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class DBResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ static final Object[][] contents = {};
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/EDBException.java b/pki/base/common/src/com/netscape/certsrv/dbs/EDBException.java
new file mode 100644
index 000000000..b0fa4bff0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/EDBException.java
@@ -0,0 +1,84 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a database exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBException extends EBaseException {
+
+ /**
+ * Resource class name.
+ */
+ private static final String DB_RESOURCES = DBResources.class.getName();
+
+ /**
+ * Constructs a database exception.
+ * <P>
+ *
+ * @param msgFormat message format
+ */
+ public EDBException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a database exception.
+ * <P>
+ *
+ * @param msgFormat message format
+ * @param param parameter
+ */
+ public EDBException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a database exception.
+ * <P>
+ *
+ * @param msgFormat message format
+ * @param e exception as parameter
+ */
+ public EDBException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a database exception.
+ * <P>
+ *
+ * @param msgFormat message format
+ * @param params list of parameters
+ */
+ public EDBException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ protected String getBundleName() {
+ return DB_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java b/pki/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java
new file mode 100644
index 000000000..28709b705
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.dbs;
+
+
+/**
+ * Indicates internal db is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBNotAvailException extends EDBException {
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EDBNotAvailException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java b/pki/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java
new file mode 100644
index 000000000..28402dba7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.dbs;
+
+
+/**
+ * Indicates internal db is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBRecordNotFoundException extends EDBException {
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EDBRecordNotFoundException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java
new file mode 100644
index 000000000..d7b82f25d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java
@@ -0,0 +1,80 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents an attribute mapper. A mapper
+ * has knowledge on how to convert a db attribute into
+ * zero or more LDAP attribute, and vice versa.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBAttrMapper {
+
+ /**
+ * Retrieves a list of LDAP attributes that are used
+ * in the mapper. By having this, the framework can
+ * provide search on selective attributes.
+ *
+ * @return a list of supported attribute names
+ */
+ public Enumeration getSupportedLDAPAttributeNames();
+
+ /**
+ * Maps object attribute into LDAP attributes.
+ *
+ * @param parent parent object where the object comes from
+ * @param name name of db attribute
+ * @param obj object itself
+ * @param attrs LDAP attribute set where the result should be stored
+ * @exception EBaseException failed to map object
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException;
+
+ /**
+ * Maps LDAP attributes into object, and puts the object
+ * into 'parent'.
+ *
+ * @param attrs LDAP attribute set
+ * @param name name of db attribute to be processed
+ * @param parent parent object where the object should be added
+ * @exception EBaseException failed to map object
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException;
+
+ /**
+ * Maps search filters into LDAP search filter.
+ *
+ * @param name name of db attribute
+ * @param op filte operation (i.e. "=", ">=")
+ * @param value attribute value
+ * @exception EBaseException failed to map filter
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java
new file mode 100644
index 000000000..c1c8c3b39
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java
@@ -0,0 +1,22 @@
+package com.netscape.certsrv.dbs;
+
+/**
+ * An interface representing a dynamic attribute mapper.
+ * A dynamic mapper has knowledge on how to convert a set of dynamically
+ * assigned db attribute into zero or more dynamically assigned LDAP
+ * attributes, and vice versa.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBDynAttrMapper extends IDBAttrMapper {
+
+ /**
+ * Returns true if the LDAP attribute can be mapped by this
+ * dynamic mapper.
+ *
+ * @param attrName LDAP attribute name to check
+ * @return a list of supported attribute names
+ */
+ public boolean supportsLDAPAttributeName(String attrName);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBObj.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBObj.java
new file mode 100644
index 000000000..1616e7418
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBObj.java
@@ -0,0 +1,42 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents a database object
+ * that is serializable.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBObj extends IAttrSet {
+
+ /**
+ * Returns a list of serializable attribute
+ * names. This method should return the
+ * attribute name even if there is no attribute
+ * value for the attribute.
+ *
+ * @return a list of serializable attribute names
+ */
+ public Enumeration getSerializableAttrNames();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java
new file mode 100644
index 000000000..faf18a342
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a registry where all the
+ * schema (object classes and attribute) information
+ * is stored.
+ *
+ * Attribute mappers can be registered with this
+ * registry.
+ *
+ * Given the schema information stored, this registry
+ * has knowledge to convert a Java object into a
+ * LDAPAttributeSet or vice versa.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBRegistry extends ISubsystem {
+
+ /**
+ * Registers object class.
+ *
+ * @param className java class to create for the object classes
+ * @param ldapNames a list of LDAP object classes
+ * @exception EDBException failed to register
+ */
+ public void registerObjectClass(String className, String ldapNames[])
+ throws EDBException;
+
+ /**
+ * See if an object class is registered.
+ *
+ * @param className java class to create
+ * @return true if object class is registered already
+ */
+ public boolean isObjectClassRegistered(String className);
+
+ /**
+ * Registers attribute mapper.
+ *
+ * @param ufName LDAP attribute name
+ * @param mapper mapper to invoke for the attribute
+ * @exception EDBException failed to register
+ */
+ public void registerAttribute(String ufName, IDBAttrMapper mapper)
+ throws EDBException;
+
+ /**
+ * See if an attribute is registered.
+ *
+ * @param ufName attribute name
+ * @return true if attribute is registered already
+ */
+ public boolean isAttributeRegistered(String ufName);
+
+ /**
+ * Registers a dynamic attribute mapper.
+ * @param mapper The dynamic mapper to register
+ */
+ public void registerDynamicMapper(IDBDynAttrMapper mapper);
+
+ /**
+ * Creates LDAP-based search filters with help of
+ * registered mappers.
+ * Parses filter from filter string specified in RFC1558.
+ * <pre>
+ * <filter> ::= '(' <filtercomp> ')'
+ * <filtercomp> ::= <and> | <or> | <not> | <item>
+ * <and> ::= '&' <filterlist>
+ * <or> ::= '|' <filterlist>
+ * <not> ::= '!' <filter>
+ * <filterlist> ::= <filter> | <filter> <filterlist>
+ * <item> ::= <simple> | <present> | <substring>
+ * <simple> ::= <attr> <filtertype> <value>
+ * <filtertype> ::= <equal> | <approx> | <greater> | <less>
+ * <equal> ::= '='
+ * <approx> ::= '~='
+ * <greater> ::= '>='
+ * <less> ::= '<='
+ * <present> ::= <attr> '=*'
+ * <substring> ::= <attr> '=' <initial> <any> <final>
+ * <initial> ::= NULL | <value>
+ * <any> ::= '*' <starval>
+ * <starval> ::= NULL | <value> '*' <starval>
+ * <final> ::= NULL | <value>
+ * </pre>
+ *
+ * @param filter CMS-based filter
+ * @return LDAP-based filter string
+ * @exception EBaseException failed to convert filter
+ */
+ public String getFilter(String filter) throws EBaseException;
+
+ /**
+ * Creates LDAP-based search filters with help of
+ * registered mappers.
+ *
+ * @param filter CMS-based filter
+ * @param c filter converter
+ * @return LDAP-based filter string
+ * @exception EBaseException failed to convert filter
+ */
+ public String getFilter(String filter, IFilterConverter c)
+ throws EBaseException;
+
+ /**
+ * Maps object into LDAP attribute set.
+ *
+ * @param parent object's parent
+ * @param name name of the object
+ * @param obj object to be mapped
+ * @param attrs LDAP attribute set
+ * @exception EBaseException failed to map object
+ */
+ public void mapObject(IDBObj parent, String name, Object obj,
+ LDAPAttributeSet attrs) throws EBaseException;
+
+ /**
+ * Retrieves a list of LDAP attributes that are associated
+ * with the given attributes.
+ *
+ * @param attrs attributes
+ * @return LDAP-based attributes
+ * @exception EBaseException failed to map attributes
+ */
+ public String[] getLDAPAttributes(String attrs[])
+ throws EBaseException;
+
+ /**
+ * Creates attribute set from object.
+ *
+ * @param obj database object
+ * @return LDAP attribute set
+ * @exception EBaseException failed to create set
+ */
+ public LDAPAttributeSet createLDAPAttributeSet(IDBObj obj)
+ throws EBaseException;
+
+ /**
+ * Creates object from attribute set.
+ *
+ * @param attrs LDAP attribute set
+ * @return database object
+ * @exception EBaseException failed to create object
+ */
+ public IDBObj createObject(LDAPAttributeSet attrs)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java
new file mode 100644
index 000000000..09364dc69
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java
@@ -0,0 +1,211 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents the database session. Operations
+ * can be performed with a session.
+ *
+ * Transaction and Caching support can be integrated
+ * into session.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBSSession {
+
+ /**
+ * Returns database subsystem.
+ *
+ * @return subsystem
+ */
+ public ISubsystem getDBSubsystem();
+
+ /**
+ * Closes this session.
+ *
+ * @exception EDBException failed to close session
+ */
+ public void close() throws EDBException;
+
+ /**
+ * Adds object to backend database. For example,
+ * <PRE>
+ * session.add("cn=123459,o=certificate repository,o=airius.com",
+ * certRec);
+ * </PRE>
+ *
+ * @param name name of the object
+ * @param obj object to be added
+ * @exception EDBException failed to add object
+ */
+ public void add(String name, IDBObj obj) throws EBaseException;
+
+ /**
+ * Reads an object from the database.
+ *
+ * @param name name of the object that is to be read
+ * @return database object
+ * @exception EBaseException failed to read object
+ */
+ public IDBObj read(String name) throws EBaseException;
+
+ /**
+ * Reads an object from the database, and only populates
+ * the selected attributes.
+ *
+ * @param name name of the object that is to be read
+ * @param attrs selected attributes
+ * @return database object
+ * @exception EBaseException failed to read object
+ */
+ public IDBObj read(String name, String attrs[])
+ throws EBaseException;
+
+ /**
+ * Deletes object from database.
+ *
+ * @param name name of the object that is to be deleted
+ * @exception EBaseException failed to delete object
+ */
+ public void delete(String name) throws EBaseException;
+
+ /**
+ * Modify an object in the database.
+ *
+ * @param name name of the object that is to be modified
+ * @param mods modifications
+ * @exception EBaseException failed to modify
+ */
+ public void modify(String name, ModificationSet mods)
+ throws EBaseException;
+
+ /**
+ * Searchs for a list of objects that match the
+ * filter.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @return search results
+ * @exception EBaseException failed to search
+ */
+ public IDBSearchResults search(String base, String filter)
+ throws EBaseException;
+
+ /**
+ * Searchs for a list of objects that match the
+ * filter.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param maxSize max number of entries
+ * @return search results
+ * @exception EBaseException failed to search
+ */
+ public IDBSearchResults search(String base, String filter, int maxSize)
+ throws EBaseException;
+
+ /**
+ * Searchs for a list of objects that match the
+ * filter.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param maxSize max number of entries
+ * @param timeLimit timeout limit
+ * @return search results
+ * @exception EBaseException failed to search
+ */
+ public IDBSearchResults search(String base, String filter, int maxSize,
+ int timeLimit) throws EBaseException;
+
+ /**
+ * Retrieves a list of object that satifies the given
+ * filter.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param attrs selected attributes
+ * @return search results
+ * @exception EBaseException failed to search
+ */
+ public IDBSearchResults search(String base, String filter,
+ String attrs[]) throws EBaseException;
+
+ /**
+ * Retrieves a list of objects.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param attrs selected attributes
+ * @return search results in virtual list
+ * @exception EBaseException failed to search
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[]) throws EBaseException;
+
+ /**
+ * Sets persistent search to retrieve modified
+ * certificate records.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param attrs selected attributes
+ * @return LDAP search results
+ * @exception EBaseException failed to search
+ */
+ public LDAPSearchResults persistentSearch(String base, String filter,
+ String attrs[]) throws EBaseException;
+
+ /**
+ * Retrieves a list of objects.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param attrs selected attributes
+ * @param sortKey key used to sort the list
+ * @param pageSize page size in the virtual list
+ * @return search results in virtual list
+ * @exception EBaseException failed to search
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException;
+
+ /**
+ * Retrieves a list of objects.
+ *
+ * @param base starting point of the search
+ * @param filter search filter
+ * @param attrs selected attributes
+ * @param startFrom starting point
+ * @param sortKey key used to sort the list
+ * @param pageSize page size in the virtual list
+ * @return search results in virtual list
+ * @exception EBaseException failed to search
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String startFrom,
+ String sortKey, int pageSize)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java
new file mode 100644
index 000000000..71356eb4f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java
@@ -0,0 +1,49 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents the search results. A search
+ * results object contain a enumeration of
+ * Java objects that are just read from the database.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBSearchResults extends Enumeration {
+
+ /**
+ * Checks if any element is available.
+ *
+ * @return true if there is more elements
+ */
+ public boolean hasMoreElements();
+
+ /**
+ * Retrieves next element.
+ *
+ * @return next element
+ */
+ public Object nextElement();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java
new file mode 100644
index 000000000..e82a3a14c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java
@@ -0,0 +1,213 @@
+// --- 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.certsrv.dbs;
+
+
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents certificate server
+ * backend database.
+ * <P>
+ * This interface separate the database subsystem
+ * functionalities from internal implementation.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBSubsystem extends ISubsystem {
+
+ public static final String SUB_ID = "dbs";
+
+
+ // values for repos
+ public static final int CERTS = 0;
+ public static final int REQUESTS = 1;
+ public static final int REPLICA_ID = 2;
+ public static final int NUM_REPOS = 3;
+
+ /**
+ * Retrieves the base DN.
+ *
+ * @return base DN of the subsystem
+ */
+ public String getBaseDN();
+
+ /**
+ * Retrieves the registry.
+ *
+ * @return registry
+ */
+ public IDBRegistry getRegistry();
+
+ /**
+ * Creates a database session.
+ *
+ * @return database session
+ * @exception EDBException failed to create session
+ */
+ public IDBSSession createSession() throws EDBException;
+
+ /**
+ * Avoids losing serial number.
+ *
+ * @return true if serial number recovery option is enabled
+ */
+ public boolean enableSerialNumberRecovery();
+
+ /**
+ * Records next serial number in config file
+ *
+ * @param serial next serial number
+ * @exception EBaseException failed to set
+ */
+ public void setNextSerialConfig(BigInteger serial) throws EBaseException;
+
+ /**
+ * Gets the next serial number in config file
+ *
+ * @return next serial number
+ */
+ public BigInteger getNextSerialConfig();
+
+ /**
+ * Records maximum serial number limit in config file
+ *
+ * @param serial max serial number
+ * @param repo repo identifier
+ * @exception EBaseException failed to set
+ */
+ public void setMaxSerialConfig(int repo, String serial) throws EBaseException;
+
+ /**
+ * Records minimum serial number limit in config file
+ *
+ * @param serial min serial number
+ * @param repo repo identifier
+ * @exception EBaseException failed to set
+ */
+ public void setMinSerialConfig(int repo, String serial) throws EBaseException;
+
+ /**
+ * Records maximum serial number limit for the next range in config file
+ *
+ * @param serial max serial number
+ * @param repo repo identifier
+ * @exception EBaseException failed to set
+ */
+ public void setNextMaxSerialConfig(int repo, String serial) throws EBaseException;
+
+ /**
+ * Records minimum serial number limit for the next range in config file
+ *
+ * @param serial min serial number
+ * @param repo repo identifier
+ * @exception EBaseException failed to set
+ */
+ public void setNextMinSerialConfig(int repo, String serial) throws EBaseException;
+
+ /**
+ * Gets minimum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number
+ */
+ public String getMinSerialConfig(int repo);
+
+ /**
+ * Gets the maximum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number
+ */
+ public String getMaxSerialConfig(int repo);
+
+ /**
+ * Gets the maximum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number
+ */
+ public String getNextMaxSerialConfig(int repo);
+
+ /**
+ * Gets minimum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number
+ */
+ public String getNextMinSerialConfig(int repo);
+
+ /**
+ * Gets low water mark limit in config file
+ *
+ * @param repo repo identifier
+ * @return low water mark
+ */
+ public String getLowWaterMarkConfig(int repo);
+
+ /**
+ * Gets range increment limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @return range increment
+ */
+ public String getIncrementConfig(int repo);
+
+ /**
+ * Gets number corresponding to start of next range from database
+ *
+ * @param repo repo identifier
+ * @return start of next range
+ */
+ public String getNextRange(int repo);
+
+ /**
+ * Determines if a range conflict has been observed in database
+ *
+ * @param repo repo identifier
+ * @return true if range conflict, false otherwise
+ */
+ public boolean hasRangeConflict(int repo);
+
+ /**
+ * Determines if serial number management has been enabled
+ *
+ * @return true if enabled, false otherwise
+ */
+ public boolean getEnableSerialMgmt();
+
+ /**
+ * Sets whether serial number management is enabled for certs
+ * and requests.
+ *
+ * @param value true/false
+ * @exception EBaseException failed to set
+ */
+ public void setEnableSerialMgmt(boolean value) throws EBaseException;
+
+ /**
+ * Returns LDAP connection to connection pool.
+ *
+ * @param conn connection to be returned
+ */
+ public void returnConn(LDAPConnection conn);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java
new file mode 100644
index 000000000..93b1f87fb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java
@@ -0,0 +1,149 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.controls.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A interface represents a virtual list of search results.
+ * Note that this class must be used with DS4.0.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDBVirtualList {
+
+ /**
+ * Sets the paging size of this virtual list.
+ * The page size here is just a buffer size. A buffer is kept around
+ * that is three times as large as the number of visible entries.
+ * That way, you can scroll up/down several items(up to a page-full)
+ * without refetching entries from the directory.
+ *
+ * @param size the page size
+ */
+ public void setPageSize(int size);
+
+ /**
+ * Sets the sort key
+ *
+ * @param sortKey the attribute to sort by
+ * @exception EBaseException failed to set
+ */
+ public void setSortKey(String sortKey) throws EBaseException;
+
+ /**
+ * Sets the sort key
+ *
+ * @param sortKeys the attributes to sort by
+ * @exception EBaseException failed to set
+ */
+ public void setSortKey(String[] sortKeys) throws EBaseException;
+
+ /**
+ * Retrieves the size of this virtual list.
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ *
+ * @return current size in list
+ */
+ public int getSize();
+
+ /**
+ * Returns current index.
+ *
+ * @return current index
+ */
+
+ public int getSizeBeforeJumpTo();
+ public int getSizeAfterJumpTo();
+
+ public int getCurrentIndex();
+
+ /**
+ * Get a page starting at "first" (although we may also fetch
+ * some preceding entries)
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ *
+ * @param first the index of the first entry of the page you want to fetch
+ */
+ public boolean getPage(int first);
+
+ /**
+ * Called by application to scroll the list with initial letters.
+ * Consider text to be an initial substring of the attribute of the
+ * primary sorting key(the first one specified in the sort key array)
+ * of an entry.
+ * If no entries match, the one just before(or after, if none before)
+ * will be returned as mSelectedIndex
+ *
+ * @param text the prefix of the first entry of the page you want to fetch
+ */
+ public boolean getPage(String text);
+
+ /**
+ * Fetchs data of a single list item
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ * If the index is out of range of the virtual list, an exception
+ * will be thrown and return null
+ *
+ * @param index the index of the element to fetch
+ */
+ public Object getElementAt(int index);
+
+ /**
+ * Retrieves and jumps to element in the given position.
+ *
+ * @param i position
+ * @return object
+ */
+ public Object getJumpToElementAt(int i);
+
+ /**
+ * Processes elements as soon as it arrives. It is
+ * more memory-efficient.
+ *
+ * @param startidx starting index
+ * @param endidx ending index
+ * @param ep object to call
+ * @exception EBaseException failed to process elements
+ */
+ public void processElements(int startidx, int endidx, IElementProcessor ep)
+ throws EBaseException;
+
+ /**
+ * Gets the virutal selected index
+ *
+ * @return selected index
+ */
+ public int getSelectedIndex();
+
+ /**
+ * Gets the top of the buffer
+ *
+ * @return first index
+ */
+ public int getFirstIndex();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java b/pki/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java
new file mode 100644
index 000000000..d43145d8b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.dbs;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Processor handles object read from the session.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IElementProcessor {
+
+ /**
+ * Handles object
+ *
+ * @param o object to be processed
+ * @exception EBaseException failed to process object
+ */
+ public void process(Object o) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java b/pki/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java
new file mode 100644
index 000000000..d31ccd468
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents a filter converter
+ * that understands how to convert a attribute
+ * type from one defintion to another.
+ * For example,
+ * <PRE>
+ * (1) database layer need to convert
+ * registered attribute type to ldap attribute
+ * type.
+ * (2) high level subsystem need to convert
+ * locale specific attribute type to registered
+ * attribute type.
+ * </PRE>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IFilterConverter {
+
+ /**
+ * Converts attribute into LDAP attribute.
+ *
+ * @param attr attribute name
+ * @param op attribute operation
+ * @param value attribute value
+ * @return The LDAP attribute
+ */
+ public String convert(String attr, String op, String value);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/Modification.java b/pki/base/common/src/com/netscape/certsrv/dbs/Modification.java
new file mode 100644
index 000000000..3a28b1337
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/Modification.java
@@ -0,0 +1,91 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a modification. This is used by the
+ * database (dbs) framework for modification operations.
+ * It specifices the modification type and values.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Modification {
+
+ /**
+ * Add new value.
+ */
+ public static final int MOD_ADD = 0;
+
+ /**
+ * Deletes old value.
+ */
+ public static final int MOD_DELETE = 1;
+
+ /**
+ * Replace old value.
+ */
+ public static final int MOD_REPLACE = 2;
+
+ private String mName = null;
+ private int mOp;
+ private Object mValue = null;
+
+ /**
+ * Constructs a role modification.
+ *
+ * @param name attribute name
+ * @param op attribute operation (i.e. MOD_ADD, MOD_DELETE, or MOD_REPLACE)
+ * @param value attribute value
+ */
+ public Modification(String name, int op, Object value) {
+ mName = name;
+ mOp = op;
+ mValue = value;
+ }
+
+ /**
+ * Retrieves attribute name.
+ *
+ * @return attribute name
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Retrieves modification operation type.
+ *
+ * @return modification type
+ */
+ public int getOp() {
+ return mOp;
+ }
+
+ /**
+ * Retrieves attribute value.
+ *
+ * @return attribute value
+ */
+ public Object getValue() {
+ return mValue;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java b/pki/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java
new file mode 100644
index 000000000..0e3108182
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java
@@ -0,0 +1,62 @@
+// --- 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.certsrv.dbs;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a modification set. A modification
+ * set contains zero or more modifications.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ModificationSet {
+
+ /**
+ * A list of modifications
+ */
+ private Vector mods = new Vector();
+
+ /**
+ * Constructs modification set.
+ */
+ public ModificationSet() {
+ }
+
+ /**
+ * Adds modification to this set.
+ *
+ * @param name attribute name
+ * @param op modification operation
+ * @param value attribute value
+ */
+ public void add(String name, int op, Object value) {
+ mods.addElement(new Modification(name, op, value));
+ }
+
+ /**
+ * Retrieves a list of modifications.
+ *
+ * @return a list of Modifications
+ */
+ public Enumeration getModifications() {
+ return mods.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java
new file mode 100644
index 000000000..febb684cc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java
@@ -0,0 +1,176 @@
+// --- 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.certsrv.dbs.certdb;
+
+
+import java.util.Date;
+import java.math.BigInteger;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.base.MetaInfo;
+import netscape.security.x509.X509CertImpl;
+
+
+/**
+ * An interface contains constants for certificate record.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertRecord extends IDBObj {
+
+ public final static String ATTR_ID = "certRecordId";
+ public final static String ATTR_META_INFO = "certMetaInfo";
+ public final static String ATTR_REVO_INFO = "certRevoInfo";
+ public final static String ATTR_CERT_STATUS = "certStatus";
+ public final static String ATTR_CREATE_TIME = "certCreateTime";
+ public final static String ATTR_MODIFY_TIME = "certModifyTime";
+ public final static String ATTR_AUTO_RENEW = "certAutoRenew";
+ public final static String ATTR_ISSUED_BY = "certIssuedBy";
+ public final static String ATTR_REVOKED_BY = "certRevokedBy";
+ public final static String ATTR_REVOKED_ON = "certRevokedOn";
+ public final static String ATTR_X509CERT = "x509cert";
+
+ public static final String META_LDAPPUBLISH = "inLdapPublishDir";
+ public static final String META_REQUEST_ID = "requestId";
+ public static final String META_RENEWED_CERT = "renewedCertSerialNo";
+ public static final String META_OLD_CERT = "oldCertSerialNo";
+ public static final String META_CERT_TYPE = "certType";
+ public static final String META_CRMF_REQID = "crmfReqId";
+ public static final String META_CHALLENGE_PHRASE = "challengePhrase";
+ public static final String META_PROFILE_ID = "profileId";
+
+ public final static String STATUS_VALID = "VALID";
+ public final static String STATUS_INVALID = "INVALID";
+ public final static String STATUS_REVOKED = "REVOKED";
+ public final static String STATUS_EXPIRED = "EXPIRED";
+ public final static String STATUS_REVOKED_EXPIRED = "REVOKED_EXPIRED";
+
+ public final static String AUTO_RENEWAL_DISABLED = "DISABLED";
+ public final static String AUTO_RENEWAL_ENABLED = "ENABLED";
+ public final static String AUTO_RENEWAL_DONE = "DONE";
+ public final static String AUTO_RENEWAL_NOTIFIED = "NOTIFIED";
+
+ public final static String X509CERT_NOT_BEFORE = "notBefore";
+ public final static String X509CERT_NOT_AFTER = "notAfter";
+ public final static String X509CERT_DURATION = "duration";
+ public final static String X509CERT_EXTENSION = "extension";
+ public final static String X509CERT_SUBJECT = "subject";
+ public final static String X509CERT_PUBLIC_KEY_DATA ="publicKeyData";
+ public final static String X509CERT_VERSION = "version";
+ public final static String X509CERT_ALGORITHM = "algorithm";
+ public final static String X509CERT_SIGNING_ALGORITHM = "signingAlgorithm";
+ public final static String X509CERT_SERIAL_NUMBER = "serialNumber";
+
+ /* attribute type used the following with search filter */
+ public final static String ATTR_X509CERT_NOT_BEFORE =
+ ATTR_X509CERT + "." + X509CERT_NOT_BEFORE;
+ public final static String ATTR_X509CERT_NOT_AFTER =
+ ATTR_X509CERT + "." + X509CERT_NOT_AFTER;
+ public final static String ATTR_X509CERT_DURATION =
+ ATTR_X509CERT + "." + X509CERT_DURATION;
+ public final static String ATTR_X509CERT_EXTENSION =
+ ATTR_X509CERT + "." + X509CERT_EXTENSION;
+ public final static String ATTR_X509CERT_SUBJECT =
+ ATTR_X509CERT + "." + X509CERT_SUBJECT;
+ public final static String ATTR_X509CERT_VERSION =
+ ATTR_X509CERT + "." + X509CERT_VERSION;
+ public final static String ATTR_X509CERT_ALGORITHM =
+ ATTR_X509CERT + "." + X509CERT_ALGORITHM;
+ public final static String ATTR_X509CERT_SIGNING_ALGORITHM =
+ ATTR_X509CERT + "." + X509CERT_SIGNING_ALGORITHM;
+ public final static String ATTR_X509CERT_SERIAL_NUMBER =
+ ATTR_X509CERT + "." + X509CERT_SERIAL_NUMBER;
+ public final static String ATTR_X509CERT_PUBLIC_KEY_DATA =
+ ATTR_X509CERT + "." + X509CERT_PUBLIC_KEY_DATA;
+
+ /**
+ * Retrieves serial number from stored certificate.
+ *
+ * @return certificate serial number
+ */
+ public BigInteger getCertificateSerialNumber();
+
+ /**
+ * Retrieves serial number from certificate record.
+ *
+ * @return certificate serial number
+ */
+ public BigInteger getSerialNumber();
+
+ /**
+ * Retrieves certificate from certificate record.
+ *
+ * @return certificate
+ */
+ public X509CertImpl getCertificate();
+
+ /**
+ * Retrieves name of who issued this certificate.
+ *
+ * @return name of who issued this certificate
+ */
+ public String getIssuedBy();
+
+ /**
+ * Retrieves name of who revoked this certificate.
+ *
+ * @return name of who revoked this certificate
+ */
+ public String getRevokedBy();
+
+ /**
+ * Retrieves date when this certificate was revoked.
+ *
+ * @return date when this certificate was revoked
+ */
+ public Date getRevokedOn();
+
+ /**
+ * Retrieves meta info.
+ *
+ * @return meta info
+ */
+ public MetaInfo getMetaInfo();
+
+ /**
+ * Retrieves certificate status.
+ *
+ * @return certificate status
+ */
+ public String getStatus();
+
+ /**
+ * Retrieves time of creation of this certificate record.
+ *
+ * @return time of creation of this certificate record
+ */
+ public Date getCreateTime();
+
+ /**
+ * Retrieves time of modification of this certificate record.
+ *
+ * @return time of modification of this certificate record
+ */
+ public Date getModifyTime();
+
+ /**
+ * Retrieves revocation info.
+ *
+ * @return revocation info
+ */
+ public IRevocationInfo getRevocationInfo();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java
new file mode 100644
index 000000000..cc8c38187
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java
@@ -0,0 +1,97 @@
+// --- 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.certsrv.dbs.certdb;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a list of certificate records.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertRecordList {
+
+ /**
+ * Gets the current index.
+ *
+ * @return current index
+ */
+ public int getCurrentIndex();
+
+ /**
+ * Retrieves the size of request list.
+ *
+ * @return size
+ */
+ public int getSize();
+
+ /**
+ * Gets size before jump to index.
+ *
+ * @return size
+ */
+ public int getSizeBeforeJumpTo();
+
+ /**
+ * Gets size after jump to index.
+ *
+ * @return size
+ */
+ public int getSizeAfterJumpTo();
+
+ /**
+ * Process certificate record as soon as it is returned.
+ *
+ * @param startidx starting index
+ * @param endidx ending index
+ * @param ep element processor
+ * @exception EBaseException failed to process cert records
+ */
+ public void processCertRecords(int startidx, int endidx,
+ IElementProcessor ep) throws EBaseException;
+
+ /**
+ * Retrieves requests.
+ * It's no good to call this if you didnt check
+ * if the startidx, endidx are valid.
+ *
+ * @param startidx starting index
+ * @param endidx ending index
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getCertRecords(int startidx, int endidx)
+ throws EBaseException;
+
+ /**
+ * Gets one single record at a time similar to
+ * processCertRecords but no extra class needed.
+ *
+ * @param index position of the record to be retrieved
+ * @return object
+ * @exception EBaseException failed to retrieve
+ */
+ public Object getCertRecord(int index)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java
new file mode 100644
index 000000000..c036909de
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java
@@ -0,0 +1,512 @@
+// --- 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.certsrv.dbs.certdb;
+
+
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * An interface represents a CMS certificate repository.
+ * It stores all the issued certificate.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertificateRepository extends IRepository {
+
+ /**
+ * Adds a certificate record to the repository. Each certificate
+ * record contains four parts: certificate, meta-attributes,
+ * issue information and reovcation information.
+ * <P>
+ *
+ * @param record X.509 certificate
+ * @exception EBaseException failed to add new certificate to
+ * the repository
+ */
+ public void addCertificateRecord(ICertRecord record)
+ throws EBaseException;
+
+ /**
+ * Reads the certificate identified by the given serial no.
+ *
+ * @param serialNo serial number of certificate
+ * @return certificate
+ * @exception EBaseException failed to retrieve certificate
+ */
+ public X509CertImpl getX509Certificate(BigInteger serialNo)
+ throws EBaseException;
+
+ /**
+ * Reads certificate from repository.
+ *
+ * @param serialNo serial number of certificate
+ * @return certificate record
+ * @exception EBaseException failed to retrieve certificate
+ */
+ public ICertRecord readCertificateRecord(BigInteger serialNo)
+ throws EBaseException;
+
+ /**
+ * Sets certificate status update internal
+ *
+ * @param requestRepo request repository
+ * @param interval update interval
+ * @param listenToCloneModifications enable listening to clone modifications
+ */
+ public void setCertStatusUpdateInterval(IRepository requestRepo,
+ int interval,
+ boolean listenToCloneModifications);
+
+ /**
+ * Updates certificate status now. This is a blocking method.
+ *
+ * @exception EBaseException failed to update
+ */
+ public void updateCertStatus() throws EBaseException;
+
+ /**
+ * Modifies certificate record.
+ *
+ * @param serialNo serial number of record
+ * @param mods modifications
+ * @exception EBaseException failed to modify
+ */
+ public void modifyCertificateRecord(BigInteger serialNo,
+ ModificationSet mods) throws EBaseException;
+
+ /**
+ * Checks if the certificate exists in this repository.
+ *
+ * @param serialNo serial number of certificate
+ * @return true if it exists
+ * @exception EBaseException failed to check
+ */
+ public boolean containsCertificate(BigInteger serialNo)
+ throws EBaseException;
+
+ /**
+ * Deletes certificate from this repository.
+ *
+ * @param serialNo serial number of certificate
+ * @exception EBaseException failed to delete
+ */
+ public void deleteCertificateRecord(BigInteger serialNo)
+ throws EBaseException;
+
+ /**
+ * Marks certificate as revoked.
+ *
+ * @param id serial number
+ * @param info revocation information
+ * @exception EBaseException failed to mark
+ */
+ public void markAsRevoked(BigInteger id, IRevocationInfo info)
+ throws EBaseException;
+
+ /**
+ * Updates certificate status.
+ *
+ * @param id serial number
+ * @param status certificate status
+ * @exception EBaseException failed to update status
+ */
+ public void updateStatus(BigInteger id, String status)
+ throws EBaseException;
+
+ /**
+ * Marks certificate as renewable.
+ *
+ * @param record certificate record to modify
+ * @exception EBaseException failed to update
+ */
+ public void markCertificateAsRenewable(ICertRecord record)
+ throws EBaseException;
+
+ /**
+ * Marks certificate as not renewable.
+ *
+ * @param record certificate record to modify
+ * @exception EBaseException failed to update
+ */
+ public void markCertificateAsNotRenewable(ICertRecord record)
+ throws EBaseException;
+
+ /**
+ * Marks certificate as renewed.
+ *
+ * @param serialNo certificate record to modify
+ * @exception EBaseException failed to update
+ */
+ public void markCertificateAsRenewed(String serialNo)
+ throws EBaseException;
+
+ /**
+ * Marks certificate as renewed and notified.
+ *
+ * @param serialNo certificate record to modify
+ * @exception EBaseException failed to update
+ */
+ public void markCertificateAsRenewalNotified(String serialNo)
+ throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ * Here is a list of filter
+ * attribute can be used:
+ * <pre>
+ * certRecordId
+ * certMetaInfo
+ * certStatus
+ * certCreateTime
+ * certModifyTime
+ * x509Cert.notBefore
+ * x509Cert.notAfter
+ * x509Cert.subject
+ * </pre>
+ * The filter should follow RFC1558 LDAP filter syntax.
+ * For example,
+ * <pre>
+ * (&(certRecordId=5)(x509Cert.notBefore=934398398))
+ * </pre>
+ *
+ * @param filter search filter
+ * @param maxSize max size to return
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration searchCertificates(String filter, int maxSize)
+ throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ *
+ * @param filter search filter
+ * @param maxSize max size to return
+ * @param timeLimit timeout value
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration searchCertificates(String filter, int maxSize,
+ int timeLimit) throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ *
+ * @param filter search filter
+ * @param attrs selected attribute
+ * @param pageSize page size
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ *
+ * @param filter search filter
+ * @param attrs selected attribute
+ * @param sortKey key to use for sorting the returned elements
+ * @param pageSize page size
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ *
+ * @param filter search filter
+ * @param attrs selected attribute
+ * @param jumpTo jump to index
+ * @param sortKey key to use for sorting the returned elements
+ * @param pageSize page size
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException;
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, boolean hardJumpTo, String sortKey, int pageSize)
+ throws EBaseException;
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ *
+ * @param filter search filter
+ * @param attrs selected attribute
+ * @param jumpTo jump to index
+ * @param sortKey key to use for sorting the returned elements
+ * @param pageSize page size
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public ICertRecordList findCertRecordsInListRawJumpto(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException;
+
+ public static final int ALL_CERTS = 0;
+ public static final int ALL_VALID_CERTS = 1;
+ public static final int ALL_UNREVOKED_CERTS = 2;
+
+ /**
+ * Gets all valid and unexpired certificates pertaining
+ * to a subject DN.
+ *
+ * @param subjectDN The distinguished name of the subject.
+ * @param validityType The type of certificatese to retrieve.
+ * @return An array of certificates.
+ * @throws EBaseException on error.
+ */
+ public X509CertImpl[] getX509Certificates(String subjectDN,
+ int validityType) throws EBaseException;
+
+ /**
+ * Retrieves all the revoked certificates that have not expired.
+ *
+ * @param asOfDate as of date
+ * @return a list of revoked certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getRevokedCertificates(Date asOfDate)
+ throws EBaseException;
+
+ /**
+ * Retrieves all revoked certificates including ones that have expired
+ * or that are not yet valid.
+ *
+ * @return a list of revoked certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration getAllRevokedCertificates()
+ throws EBaseException;
+
+ /**
+ * Retrieves all revoked but not expired certificates.
+ *
+ * @return a list of revoked certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration getAllRevokedNonExpiredCertificates()
+ throws EBaseException;
+
+ /**
+ * Finds all certificates given a filter.
+ *
+ * @param filter search filter
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration findCertificates(String filter)
+ throws EBaseException;
+
+ /**
+ * Finds all certificate records given a filter.
+ *
+ * @param filter search filter
+ * @return a list of certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration findCertRecords(String filter)
+ throws EBaseException;
+
+ /**
+ * Gets Revoked certs orderes by noAfter date, jumps to records
+ * where notAfter date is greater than current.
+ *
+ * @param date reference date
+ * @param pageSize page size
+ * @return a list of certificate records
+ * @exception EBaseException failed to retrieve
+ */
+ public ICertRecordList getRevokedCertsByNotAfterDate(Date date,
+ int pageSize) throws EBaseException;
+
+ /**
+ * Gets Invalid certs orderes by noAfter date, jumps to records
+ * where notAfter date is greater than current.
+ *
+ * @param date reference date
+ * @param pageSize page size
+ * @return a list of certificate records
+ * @exception EBaseException failed to retrieve
+ */
+ public ICertRecordList getInvalidCertsByNotBeforeDate(Date date,
+ int pageSize) throws EBaseException;
+
+ /**
+ * Gets valid certs orderes by noAfter date, jumps to records
+ * where notAfter date is greater than current.
+ *
+ * @param date reference date
+ * @param pageSize page size
+ * @return a list of certificate records
+ * @exception EBaseException failed to retrieve
+ */
+ public ICertRecordList getValidCertsByNotAfterDate(Date date,
+ int pageSize) throws EBaseException;
+
+ /**
+ * Creates certificate record.
+ *
+ * @param id serial number
+ * @param cert certificate
+ * @param meta meta information
+ * @return certificate record
+ */
+ public ICertRecord createCertRecord(BigInteger id,
+ Certificate cert, MetaInfo meta);
+
+ /**
+ * Finds certificate records.
+ *
+ * @param filter search filter
+ * @return a list of certificate records
+ * @exception EBaseException failed to retrieve cert records
+ */
+ public Enumeration findCertRecs(String filter)
+ throws EBaseException;
+
+ /**
+ * Retrieves renewable certificates.
+ *
+ * @param renewalTime renewal time
+ * @return certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Hashtable getRenewableCertificates(String renewalTime)
+ throws EBaseException;
+
+ /**
+ * Unmark a revoked certificates.
+ *
+ * @param id serial number
+ * @param info revocation information
+ * @param revokedOn revocation date
+ * @param revokedBy userid
+ * @exception EBaseException failed to unmark
+ */
+ public void unmarkRevoked(BigInteger id, IRevocationInfo info,
+ Date revokedOn, String revokedBy)
+ throws EBaseException;
+
+ /**
+ * Retrieves valid and not published certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getValidNotPublishedCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves expired and published certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getExpiredPublishedCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves revoked and published certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getRevokedPublishedCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves valid certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getValidCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves expired certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getExpiredCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves revoked certificates.
+ *
+ * @param from starting serial number
+ * @param to ending serial number
+ * @return a list of certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Enumeration getRevokedCertificates(String from, String to)
+ throws EBaseException;
+
+ /**
+ * Retrieves modified certificate records.
+ *
+ * @param entry LDAPEntry with modified data
+ */
+ public void getModifications(LDAPEntry entry);
+
+ /**
+ * Removes certificate records with this repository.
+ *
+ * @param beginS BigInteger with radix 16
+ * @param endS BigInteger with radix 16
+ */
+ public void removeCertRecords(BigInteger beginS, BigInteger endS) throws EBaseException;
+
+ public void shutdown();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java
new file mode 100644
index 000000000..15e396943
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java
@@ -0,0 +1,54 @@
+// --- 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.certsrv.dbs.certdb;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a certificate revocation info. This
+ * object is written as an attribute of certificate record
+ * which essentially signifies a revocation act.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRevocationInfo {
+
+ /**
+ * Retrieves revocation date.
+ *
+ * @return revocation date
+ */
+ public Date getRevocationDate();
+
+ /**
+ * Retrieves CRL entry extensions.
+ *
+ * @return CRL entry extensions
+ */
+ public CRLExtensions getCRLEntryExtensions();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java b/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java
new file mode 100644
index 000000000..f0d98fd59
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java
@@ -0,0 +1,165 @@
+// --- 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.certsrv.dbs.crldb;
+
+
+import java.util.*;
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * An interface that defines abilities of
+ * a CRL issuing point record.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICRLIssuingPointRecord extends IDBObj {
+
+ public static final String ATTR_ID = "id";
+ public static final String ATTR_CRL_NUMBER = "crlNumber";
+ public static final String ATTR_DELTA_NUMBER = "deltaNumber";
+ public static final String ATTR_CRL_SIZE = "crlSize";
+ public static final String ATTR_DELTA_SIZE = "deltaSize";
+ public static final String ATTR_THIS_UPDATE = "thisUpdate";
+ public static final String ATTR_NEXT_UPDATE = "nextUpdate";
+ public static final String ATTR_FIRST_UNSAVED = "firstUnsaved";
+ public static final String ATTR_CRL = "certificaterevocationlist";
+ public static final String ATTR_CRL_CACHE = "crlCache";
+ public static final String ATTR_CA_CERT = "cACertificate";
+ public static final String ATTR_REVOKED_CERTS = "revokedCerts";
+ public static final String ATTR_UNREVOKED_CERTS = "unrevokedCerts";
+ public static final String ATTR_EXPIRED_CERTS = "expiredCerts";
+ public static final String ATTR_DELTA_CRL = "deltaRevocationList";
+
+ public static final String CLEAN_CACHE = "-1";
+ public static final String NEW_CACHE = "-2";
+
+ /**
+ * Retrieve unique CRL identifier.
+ *
+ * @return unique CRL identifier
+ */
+ public String getId();
+
+ /**
+ * Retrieves current CRL number out of CRL issuing point record.
+ *
+ * @return current CRL number
+ */
+ public BigInteger getCRLNumber();
+
+ /**
+ * Retrieves CRL size measured by the number of entries.
+ *
+ * @return CRL size
+ */
+ public Long getCRLSize();
+
+ /**
+ * Retrieves this update time.
+ *
+ * @return time of this update
+ */
+ public Date getThisUpdate();
+
+ /**
+ * Retrieves next update time.
+ *
+ * @return time of next update
+ */
+ public Date getNextUpdate();
+
+ /**
+ * Retrieves current delta CRL number out of CRL issuing point record.
+ *
+ * @return current delta CRL number
+ */
+ public BigInteger getDeltaCRLNumber();
+
+ /**
+ * Retrieves delta CRL size measured by the number of entries.
+ *
+ * @return delta CRL size
+ */
+ public Long getDeltaCRLSize();
+
+ /**
+ * Retrieve Retrieve reference to the first unsaved data.
+ *
+ * @return reference to the first unsaved data
+ */
+ public String getFirstUnsaved();
+
+ /**
+ * Retrieves encoded CRL.
+ *
+ * @return encoded CRL
+ */
+ public byte[] getCRL();
+
+ /**
+ * Retrieves encoded delta CRL.
+ *
+ * @return encoded delta CRL
+ */
+ public byte[] getDeltaCRL();
+
+ /**
+ * Retrieves encoded CA certificate.
+ *
+ * @return encoded CA certificate
+ */
+ public byte[] getCACert();
+
+ /**
+ * Retrieves cache information about CRL.
+ *
+ * @return list of recently revoked certificates
+ */
+ public Hashtable getCRLCacheNoClone();
+ public Hashtable getCRLCache();
+
+ /**
+ * Retrieves cache information about revoked certificates.
+ *
+ * @return list of recently revoked certificates
+ */
+ public Hashtable getRevokedCerts();
+
+ /**
+ * Retrieves cache information about certificates released from hold.
+ *
+ * @return list of certificates recently released from hold
+ */
+ public Hashtable getUnrevokedCerts();
+
+ /**
+ * Retrieves cache information about expired certificates.
+ *
+ * @return list of recently expired certificates
+ */
+ public Hashtable getExpiredCerts();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java
new file mode 100644
index 000000000..ffac9b37b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java
@@ -0,0 +1,183 @@
+// --- 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.certsrv.dbs.crldb;
+
+
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * An interface represents a CMS CRL repository. It stores
+ * all the CRL issuing points.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICRLRepository {
+
+ /**
+ * Adds CRL issuing point record.
+ *
+ * @param rec issuing point record
+ * @exception EBaseException failed to add new issuing point record
+ */
+ public void addCRLIssuingPointRecord(ICRLIssuingPointRecord rec)
+ throws EBaseException;
+
+ /**
+ * Retrieves all the issuing points' names.
+ *
+ * @return A list of issuing points' names.
+ * @exception EBaseException failed to retrieve all the issuing points' names.
+ */
+ public Vector getIssuingPointsNames() throws EBaseException;
+
+ /**
+ * Reads issuing point record.
+ *
+ * @return issuing point record
+ * @exception EBaseException failed to read issuing point record
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPointRecord(String id)
+ throws EBaseException;
+
+ /**
+ * Deletes issuing point record.
+ *
+ * @param id issuing point record id
+ * @exception EBaseException failed to delete issuing point record
+ */
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException;
+
+ /**
+ * Modifies issuing point record.
+ *
+ * @param id issuing point record id
+ * @param mods set of modifications
+ * @exception EBaseException failed to modify issuing point record
+ */
+ public void modifyCRLIssuingPointRecord(String id, ModificationSet mods)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record.
+ *
+ * @param id issuing point record id
+ * @param newCRL encoded binary CRL
+ * @param thisUpdate time of this update
+ * @param nextUpdate time of next update
+ * @param crlNumber CRL number
+ * @param crlSize CRL size
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record.
+ *
+ * @param id issuing point record id
+ * @param newCRL encoded binary CRL
+ * @param thisUpdate time of this update
+ * @param nextUpdate time of next update
+ * @param crlNumber CRL number
+ * @param crlSize CRL size
+ * @param revokedCerts list of revoked certificates
+ * @param unrevokedCerts list of released from hold certificates
+ * @param expiredCerts list of expired certificates
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize,
+ Hashtable revokedCerts, Hashtable unrevokedCerts, Hashtable expiredCerts)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record.
+ *
+ * @param id issuing point record id
+ * @param revokedCerts list of revoked certificates
+ * @param unrevokedCerts list of released from hold certificates
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateRevokedCerts(String id, Hashtable revokedCerts, Hashtable unrevokedCerts)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record.
+ *
+ * @param id issuing point record id
+ * @param expiredCerts list of expired certificates
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateExpiredCerts(String id, Hashtable expiredCerts)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record.
+ *
+ * @param id issuing point record id
+ * @param crlSize CRL size
+ * @param revokedCerts list of revoked certificates
+ * @param unrevokedCerts list of released from hold certificates
+ * @param expiredCerts list of expired certificates
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateCRLCache(String id, Long crlSize,
+ Hashtable revokedCerts,
+ Hashtable unrevokedCerts,
+ Hashtable expiredCerts)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record with delta-CRL.
+ *
+ * @param id issuing point record id
+ * @param deltaCRLNumber delta CRL number
+ * @param deltaCRLSize delta CRL size
+ * @param nextUpdate time of next update
+ * @param deltaCRL delta CRL in binary form
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateDeltaCRL(String id, BigInteger deltaCRLNumber,
+ Long deltaCRLSize, Date nextUpdate,
+ byte[] deltaCRL)
+ throws EBaseException;
+
+ /**
+ * Updates CRL issuing point record with reference to the first
+ * unsaved data.
+ *
+ * @param id issuing point record id
+ * @param firstUnsaved reference to the first unsaved data
+ * @exception EBaseException failed to update issuing point record
+ */
+ public void updateFirstUnsaved(String id, String firstUnsaved)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java
new file mode 100644
index 000000000..f795ff9a6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java
@@ -0,0 +1,125 @@
+// --- 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.certsrv.dbs.keydb;
+
+
+import java.util.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface contains constants for key record.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IKeyRecord {
+ public static final String ATTR_ID = "keySerialNumber";
+ public static final String ATTR_STATE = "keyState";
+ public static final String ATTR_ALGORITHM = "algorithm";
+ public static final String ATTR_KEY_SIZE = "keySize";
+ public static final String ATTR_OWNER_NAME = "keyOwnerName";
+ public static final String ATTR_PRIVATE_KEY_DATA = "privateKey";
+ public static final String ATTR_PUBLIC_KEY_DATA = "publicKey";
+ public static final String ATTR_DATE_OF_RECOVERY = "dateOfRecovery";
+ public static final String ATTR_CREATE_TIME = "keyCreateTime";
+ public static final String ATTR_MODIFY_TIME = "keyModifyTime";
+ public static final String ATTR_META_INFO = "keyMetaInfo";
+ public static final String ATTR_ARCHIVED_BY = "keyArchivedBy";
+
+ // key state
+ public static final String STATUS_ANY = "ANY";
+ public static final String STATUS_VALID = "VALID";
+ public static final String STATUS_INVALID = "INVALID";
+
+ /**
+ * Retrieves the state of the key.
+ *
+ * @return key state
+ * @exception EBaseException failed to retrieve state of the key
+ */
+ public KeyState getState() throws EBaseException;
+
+ /**
+ * Retrieves key identifier.
+ *
+ * @return key id
+ * @exception EBaseException failed to retrieve key id
+ */
+ public BigInteger getSerialNumber() throws EBaseException;
+
+ /**
+ * Retrieves key owner name.
+ *
+ * @return key owner name
+ * @exception EBaseException failed to retrieve key owner name
+ */
+ public String getOwnerName() throws EBaseException;
+
+ /**
+ * Retrieves key algorithm.
+ *
+ * @return key algorithm
+ */
+ public String getAlgorithm();
+
+ /**
+ * Retrieves key length.
+ *
+ * @return key length
+ * @exception EBaseException failed to retrieve key length
+ */
+ public Integer getKeySize() throws EBaseException;
+
+ /**
+ * Retrieves archiver identifier.
+ *
+ * @return archiver uid
+ */
+ public String getArchivedBy();
+
+ /**
+ * Retrieves creation time.
+ *
+ * @return creation time
+ */
+ public Date getCreateTime();
+
+ /**
+ * Retrieves last modification time.
+ *
+ * @return modification time
+ */
+ public Date getModifyTime();
+
+ /**
+ * Retrieves dates of recovery.
+ *
+ * @return recovery history
+ * @exception EBaseException failed to retrieve recovery history
+ */
+ public Date[] getDateOfRevocation() throws EBaseException;
+
+ /**
+ * Retrieves public key data.
+ *
+ * @return public key data
+ * @exception EBaseException failed to retrieve public key data
+ */
+ public byte[] getPublicKeyData() throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java
new file mode 100644
index 000000000..aced5cc1f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java
@@ -0,0 +1,54 @@
+// --- 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.certsrv.dbs.keydb;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * A class represents a list of key records.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IKeyRecordList {
+
+ /**
+ * Retrieves the size of key list.
+ *
+ * @return size of key list
+ */
+ public int getSize();
+
+ /**
+ * Retrieves key records.
+ *
+ * @param startidx start index
+ * @param endidx end index
+ * @return key records
+ * @exception EBaseException failed to retrieve key records
+ */
+ public Enumeration getKeyRecords(int startidx, int endidx)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java
new file mode 100644
index 000000000..324a7df17
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java
@@ -0,0 +1,177 @@
+// --- 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.certsrv.dbs.keydb;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * An interface represents a Key repository. This is the
+ * container of archived keys.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IKeyRepository extends IRepository {
+
+ /**
+ * Archives a key to the repository.
+ * <P>
+ *
+ * @param record key record
+ * @exception EBaseException failed to archive key
+ */
+ public void addKeyRecord(IKeyRecord record) throws EBaseException;
+
+ /**
+ * Reads an archived key by serial number.
+ * <P>
+ *
+ * @param serialNo serial number
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(BigInteger serialNo)
+ throws EBaseException;
+
+ /**
+ * Reads an archived key by b64 encoded cert.
+ * <P>
+ *
+ * @param cert b64 encoded cert
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(String cert)
+ throws EBaseException;
+
+ /**
+ * Reads an archived key by owner name.
+ * <P>
+ *
+ * @param ownerName owner name
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(X500Name ownerName)
+ throws EBaseException;
+
+ /**
+ * Reads archived key using public key.
+ *
+ * @param publicKey public key that is corresponding
+ * to the private key
+ * @return key record
+ * @exception EBaseException failed to read key
+ */
+ public IKeyRecord readKeyRecord(PublicKey publicKey)
+ throws EBaseException;
+
+ /**
+ * Searches for private keys.
+ *
+ * @param filter LDAP filter for the search
+ * @param maxSize maximium number of entries to be returned
+ * @return a list of private key records
+ * @exception EBaseException failed to search keys
+ */
+ public Enumeration searchKeys(String filter, int maxSize)
+ throws EBaseException;
+
+ /**
+ * Searches for private keys.
+ *
+ * @param filter LDAP filter for the search
+ * @param maxSize maximium number of entries to be returned
+ * @param timeLimt timeout value
+ * @return a list of private key records
+ * @exception EBaseException failed to search keys
+ */
+ public Enumeration searchKeys(String filter, int maxSize, int timeLimt)
+ throws EBaseException;
+
+ /**
+ * Deletes a key record.
+ *
+ * @param serialno key identifier
+ * @exception EBaseException failed to delete key record
+ */
+ public void deleteKeyRecord(BigInteger serialno)
+ throws EBaseException;
+
+ /**
+ * Modifies key record in this repository.
+ *
+ * @param serialNo key identifier
+ * @param mods modification of key records
+ * @exception EBaseException failed to modify key record
+ */
+ public void modifyKeyRecord(BigInteger serialNo,
+ ModificationSet mods) throws EBaseException;
+
+ /**
+ * Searchs for a list of key records.
+ * Here is a list of supported filter attributes:
+ * <pre>
+ * keySerialNumber
+ * keyState
+ * algorithm
+ * keySize
+ * keyOwnerName
+ * privateKey
+ * publicKey
+ * dateOfRecovery
+ * keyCreateTime
+ * keyModifyTime
+ * keyMetaInfo
+ * </pre>
+ *
+ * @param filter search filter
+ * @param attrs list of attributes to be returned
+ * @param pageSize virtual list page size
+ * @return list of key records
+ * @exception EBaseException failed to search key records
+ */
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException;
+
+ /**
+ * Searchs for a list of key records.
+ *
+ * @param filter search filter
+ * @param attrs list of attributes to be returned
+ * @param sortKey name of attribute that the list should be sorted by
+ * @param pageSize virtual list page size
+ * @return list of key records
+ * @exception EBaseException failed to search key records
+ */
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java
new file mode 100644
index 000000000..a6b7fa031
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java
@@ -0,0 +1,102 @@
+// --- 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.certsrv.dbs.keydb;
+
+
+import java.util.*;
+import java.io.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents key state. This object is to
+ * encapsulate the life cycle of a key.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public final class KeyState implements Serializable {
+
+ private int mStateCode;
+
+ /**
+ * Constructs a key state.
+ */
+ private KeyState(int code) {
+ mStateCode = code;
+ }
+
+ /**
+ * Request state.
+ */
+ public final static KeyState ANY = new KeyState(-1);
+ public final static KeyState VALID = new KeyState(0);
+ public final static KeyState INVALID = new KeyState(1);
+
+ /**
+ * Checks if the given object equals to this object.
+ *
+ * @param other object to be compared
+ * @return true if both objects are the same
+ */
+ public boolean equals(Object other) {
+ if (this == other)
+ return true;
+ else if (other instanceof KeyState)
+ return ((KeyState) other).mStateCode == mStateCode;
+ else
+ return false;
+ }
+
+ /**
+ * Returns the hash code.
+ *
+ * @return hash code
+ */
+ public int hashCode() {
+ return mStateCode;
+ }
+
+ /**
+ * Return the string-representation of this object.
+ *
+ * @return string value
+ */
+ public String toString() {
+ if (mStateCode == -1) return "ANY";
+ if (mStateCode == 0) return "VALID";
+ if (mStateCode == 1) return "INVAILD";
+ return "[UNDEFINED]";
+
+ }
+
+ /**
+ * Converts a string into a key state object.
+ *
+ * @param state state in string-representation
+ * @return key state object
+ */
+ public static KeyState toKeyState(String state) {
+ if (state.equalsIgnoreCase("ANY")) return ANY;
+ if (state.equalsIgnoreCase("VALID")) return VALID;
+ if (state.equalsIgnoreCase("INVALID")) return INVALID;
+ return null;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java
new file mode 100644
index 000000000..e92d13a16
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.dbs.replicadb;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * An interface represents a ReplicaID Repository.
+ * It provides unique managed replica IDs.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IReplicaIDRepository extends IRepository {
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
new file mode 100644
index 000000000..7ee01b3f1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
@@ -0,0 +1,92 @@
+// --- 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.certsrv.dbs.repository;
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+/**
+ * An interface represents a generic repository. It maintains unique
+ * serial number within repository.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRepository {
+
+ /**
+ * Retrieves the next serial number, and also increase the
+ * serial number by one.
+ *
+ * @return serial number
+ * @exception EBaseException failed to retrieve next serial number
+ */
+ public BigInteger getNextSerialNumber() throws EBaseException;
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException;
+
+ /**
+ * Retrieves the next serial number without increasing the serial number.
+ *
+ * @return serial number
+ * @exception EBaseException failed to retrieve next serial number
+ */
+ public BigInteger getTheSerialNumber() throws EBaseException;
+
+ /**
+ * Set the maximum serial number.
+ *
+ * @param serial maximum number
+ * @exception EBaseException failed to set maximum serial number
+ */
+ public void setMaxSerial (String serial) throws EBaseException;
+
+ /**
+ * Set the maximum serial number in next range.
+ *
+ * @param serial maximum number
+ * @exception EBaseException failed to set maximum serial number in next range
+ */
+ public void setNextMaxSerial(String serial) throws EBaseException;
+
+ /**
+ * Checks to see if a new range is needed, or if we have reached the end of the
+ * current range, or if a range conflict has occurred.
+ *
+ * @exception EBaseException failed to check next range for conflicts
+ */
+ public void checkRanges() throws EBaseException;
+
+ /**
+ * Sets whether serial number management is enabled for certs
+ * and requests.
+ *
+ * @param value true/false
+ * @exception EBaseException failed to set
+ */
+ public void setEnableSerialMgmt(boolean value) throws EBaseException;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java
new file mode 100644
index 000000000..5e6db669f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java
@@ -0,0 +1,49 @@
+// --- 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.certsrv.dbs.repository;
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+
+/**
+ * An interface represents a generic repository record.
+ * It maintains unique serial number within repository.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRepositoryRecord extends IDBObj {
+
+ public final static String ATTR_SERIALNO = "serialNo";
+ public final static String ATTR_PUB_STATUS = "publishingStatus";
+
+ /**
+ * Retrieves serial number.
+ *
+ * @return serial number
+ */
+ public BigInteger getSerialNumber();
+
+ public String getPublishingStatus();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java b/pki/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java
new file mode 100644
index 000000000..5764f4005
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java
@@ -0,0 +1,89 @@
+// --- 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.certsrv.evaluators;
+
+
+import java.util.*;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * A class represents an evaluator. An evaluator is used to
+ * evaluate an expression. For example, one can write an evaluator to
+ * evaluate if a user belongs to a certain group. An evaluator is
+ * generally used for access control expression evaluation, however, it
+ * can be used for other evaluation-related operations.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAccessEvaluator {
+
+ /**
+ * Initialize the evaluator
+ */
+ public void init();
+
+ /**
+ * Gets the type of the evaluator. Type is defined by each
+ * evaluator plugin. Each evaluator plugin should have a unique type.
+ * @return type of the evaluator
+ */
+ public String getType();
+
+ /**
+ * Gets the description of the evaluator
+ * @return a text description for this evaluator
+ */
+ public String getDescription();
+
+ /**
+ * Evaluates if the given value satisfies the access
+ * control in current context.
+ * @param type Type of the evaluator, eg, user, group etc
+ * @param op Operator of the evaluator, eg, =, !=
+ * @param value Part of the expression that can be used to
+ * evaluate, e.g, value can be the name of the group if the
+ * purpose of the evaluator is to evaluate if the user is a member
+ * of the group.
+ * @return true if the evaluation expression is matched; false otherwise.
+ */
+ public boolean evaluate(String type, String op, String value);
+
+ /**
+ * Evaluates if the given value satisfies the access
+ * control in authToken obtained from Authentication.
+ * @param authToken Authentication token
+ * @param type Type of the evaluator, eg, user, group etc
+ * @param op Operator of the evaluator, eg, =, !=
+ * @param value Part of the expression that can be used to
+ * evaluate, e.g, value can be the name of the group if the
+ * purpose of the evaluator is to evaluate if the user is a member
+ * of the group.
+ * @return true if the evaluation expression is matched; false otherwise.
+ */
+ public boolean evaluate(IAuthToken authToken, String type, String op, String value);
+
+ /**
+ * Get the supported operators for this evaluator
+ * @return Supported operators in string array
+ */
+ public String[] getSupportedOperators();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java b/pki/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java
new file mode 100644
index 000000000..297b44262
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java
@@ -0,0 +1,57 @@
+// --- 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.certsrv.extensions;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This represents the extensions exception.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EExtensionsException extends EBaseException {
+
+ /**
+ * Resource class name.
+ */
+ private static final String EXTENSIONS_RESOURCES =
+ ExtensionsResources.class.getName();
+
+ public EExtensionsException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ public EExtensionsException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ public EExtensionsException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ public EExtensionsException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ protected String getBundleName() {
+ return EXTENSIONS_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java b/pki/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java
new file mode 100644
index 000000000..b50638ddc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.extensions;
+
+
+import java.util.*;
+
+
+/**
+ * This represents the resources for extensions.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtensionsResources extends ListResourceBundle {
+
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java b/pki/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java
new file mode 100644
index 000000000..55f348b11
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java
@@ -0,0 +1,77 @@
+// --- 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.certsrv.extensions;
+
+
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+
+import netscape.security.x509.Extension;
+import netscape.security.util.ObjectIdentifier;
+
+
+/**
+ * CMS extension interface, for creating extensions from http input and
+ * displaying extensions to html forms.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICMSExtension {
+ public static String EXT_IS_CRITICAL = "isCritical";
+
+ public static String EXT_PREFIX = "ext_";
+
+ /**
+ * initialize from configuration file
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Get name of this extension.
+ * @return the name of this CMS extension, for
+ */
+ public String getName();
+
+ /**
+ * Get object identifier associated with this extension.
+ */
+ public ObjectIdentifier getOID();
+
+ /**
+ * Get an instance of the extension given http input.
+ * @return an instance of the extension.
+ */
+ public Extension getExtension(IArgBlock argblock)
+ throws EBaseException;
+
+ /**
+ * Get Javascript name value pairs to put into the request processing
+ * template.
+ * @return name value pairs
+ */
+ public IArgBlock getFormParams(Extension extension)
+ throws EBaseException;
+
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/EJobsException.java b/pki/base/common/src/com/netscape/certsrv/jobs/EJobsException.java
new file mode 100644
index 000000000..37528c603
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/EJobsException.java
@@ -0,0 +1,77 @@
+// --- 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.certsrv.jobs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a jobs exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EJobsException extends EBaseException {
+
+ /**
+ * Identity resource class name.
+ */
+ private static final String JOBS_RESOURCES = JobsResources.class.getName();
+
+ /**
+ * Constructs a Job Scheduler exception
+ * <P>
+ */
+ public EJobsException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public EJobsException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public EJobsException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public EJobsException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Retrieves bundle name.
+ */
+ protected String getBundleName() {
+ return JOBS_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/IJob.java b/pki/base/common/src/com/netscape/certsrv/jobs/IJob.java
new file mode 100644
index 000000000..410629982
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/IJob.java
@@ -0,0 +1,87 @@
+// --- 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.certsrv.jobs;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface to be implemented from for a job to be scheduled by
+ * the Jobs Scheduler.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IJob {
+
+ /**
+ * Initialize from the configuration file.
+ * @param id String name of this instance
+ * @param implName string name of this implementation
+ * @param config configuration store for this instance
+ * @exception EBaseException any initilization failure
+ */
+ public void init(ISubsystem owner, String id, String implName,
+ IConfigStore config) throws EBaseException;
+
+ /**
+ * tells if the job is enabled
+ * @return a boolean value indicating whether the job is enabled
+ * or not
+ */
+ public boolean isEnabled();
+
+ /**
+ * set instance id.
+ * @param id String id of the instance
+ */
+ public void setId(String id);
+
+ /**
+ * get instance id.
+ * @return a String identifier
+ */
+ public String getId();
+
+ /**
+ * get cron string associated with this job
+ * @return a JobCron object that represents the schedule of this job
+ */
+ public IJobCron getJobCron();
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams();
+
+ /**
+ * gets the plugin name of this job.
+ * @return a String that is the name of this implementation
+ */
+ public String getImplName();
+
+ /**
+ * Gets the configuration substore used by this job
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/IJobCron.java b/pki/base/common/src/com/netscape/certsrv/jobs/IJobCron.java
new file mode 100644
index 000000000..9e6d2b4de
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/IJobCron.java
@@ -0,0 +1,55 @@
+// --- 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.certsrv.jobs;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * class representing one Job cron information
+ * <p>here, an "item" refers to one of the 5 fields in a cron string;
+ * "element" refers to any comma-deliminated element in an
+ * "item"...which includes both numbers and '-' separated ranges.
+ * A cron string in the configuration takes the following format:
+ * <i>minute (0-59),
+ * hour (0-23),
+ * day of the month (1-31),
+ * month of the year (1-12),
+ * day of the week (0-6 with 0=Sunday)</i>
+ * <p>
+ * e.g. jobsScheduler.job.rnJob1.cron=30 11,23 * * 1-5
+ * In this example, the job "rnJob1" will be executed from Monday
+ * through Friday, at 11:30am and 11:30pm.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IJobCron {
+ /**
+ * constant that represents the configuration parameter
+ * "cron" for the job that this JobCron is associated with. The
+ * value of which should conform to the cron format specified above.
+ */
+ public static final String PROP_CRON = "cron";
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java b/pki/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java
new file mode 100644
index 000000000..d30ccbf35
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java
@@ -0,0 +1,160 @@
+// --- 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.certsrv.jobs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface that represents the job scheduler component. A JobScheduler
+ * is a daemon thread that handles scheduled jobs like cron would
+ * do with different jobs. This daemon wakes up at a pre-configured
+ * interval to see
+ * if there is any job to be done, if so, a thread is created to execute
+ * the job(s).
+ * <p>
+ * The interval <b>jobsScheduler.interval</b> in the configuration is
+ * specified as number of minutes. If not set, the default is 1 minute.
+ * Note that the cron specification for each job CAN NOT be finer than
+ * the granularity of the Scheduler daemon interval. For example, if
+ * the daemon interval is set to 5 minute, a job cron for every minute
+ * at 7am on each Tuesday (e.g. * 7 * * 2) will result in the
+ * execution of the job thread only once every 5 minutes during that
+ * hour. <b>The inteval value is recommended at 1 minute, setting it
+ * otherwise has the potential of forever missing the beat</b>. Use
+ * with caution.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IJobsScheduler extends ISubsystem {
+ /**
+ * The ID of this component
+ */
+ public final static String ID = "jobsScheduler";
+
+ /**
+ * constant that represents the configuration parameter
+ * "enabled" for this component in CMS.cfg. The value of which
+ * tells CMS whether the JobsScheduler is enabled or not
+ */
+ public static final String PROP_ENABLED = "enabled";
+
+ /**
+ * constant that represents the configuration parameter
+ * "interval" for this component in CMS.cfg. The value of which
+ * tells CMS the interval that the JobsScheduler thread should
+ * wake up and look for jobs to execute
+ */
+ public static final String PROP_INTERVAL = "interval";
+
+ /**
+ * constant that represents the configuration parameter
+ * "class" for this component in CMS.cfg. The values of which are
+ * the actual implementation classes
+ */
+ public static final String PROP_CLASS = "class";
+
+ /**
+ * constant that represents the configuration parameter
+ * "job" for this component in CMS.cfg. The values of which gives
+ * configuration information specific to one single job instance.
+ * There may be multiple jobs served by the jobsScheduler
+ */
+ public static final String PROP_JOB = "job";
+
+ /**
+ * constant that represents the configuration parameter
+ * "impl" for this component in CMS.cfg. The values of which are
+ * actual plugin implementation(s)
+ */
+ public static final String PROP_IMPL = "impl";
+
+ /**
+ * constant that represents the configuration parameter
+ * "pluginName" for this component in CMS.cfg. The value of which
+ * gives the pluginName for the job it associates with
+ */
+ public static final String PROP_PLUGIN = "pluginName";
+
+ /**
+ * Retrieves all the job implementations.
+ * @return a Hashtable of available job plugin implementations
+ */
+ public Hashtable getPlugins();
+
+ /**
+ * Retrieves all the job instances.
+ * @return a Hashtable of job instances
+ */
+ public Hashtable getInstances();
+
+ /**
+ * Retrieves the configuration parameters of the given
+ * implementation. It is used to return to the Console for
+ * configuration
+ * @param implName the pulubin implementation name
+ * @return a String array of required configuration parameters of
+ * the given implementation.
+ * @exception EJobsException when job plugin implementation can
+ * not be found, instantiation is impossible, permission problem
+ * with the class.
+ */
+ public String[] getConfigParams(String implName)
+ throws EJobsException;
+
+ /**
+ * Writes a message to the system log.
+ * @param level an integer representing the log message level.
+ * Depending on the configuration set by the administrator, this
+ * value is a determining factor for whether this message will be
+ * actually logged or not. The lower the level, the higher the
+ * priority, and the higher chance it will be logged.
+ * @param msg the message to be written. Ideally should call
+ * CMS.getLogMessage() to get the localizable message
+ * from the log properties file.
+ */
+ public void log(int level, String msg);
+
+ /**
+ * Sets daemon's wakeup interval.
+ * @param minutes time in minutes that is to be the frequency of
+ * JobsScheduler wakeup call.
+ */
+ public void setInterval(int minutes);
+
+ /**
+ * Starts up the JobsScheduler daemon. Usually called from the
+ * initialization method when it's successfully initialized.
+ */
+ public void startDaemon();
+
+ /**
+ * Creates a job cron. Each job is associated with a "cron" which
+ * specifies the rule of frequency that this job should be
+ * executed (e.g. every Sunday at midnight). This method is
+ * called by each job at initialization time.
+ * @param cs the string that represents the cron. See IJobCron
+ * for detail of the format.
+ * @return IJobCron an IJobCron
+ * @exception EBaseException when the cron string, cs, can not be
+ * parsed correctly
+ */
+ public IJobCron createJobCron(String cs) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java b/pki/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java
new file mode 100644
index 000000000..d610ee909
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java
@@ -0,0 +1,75 @@
+// --- 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.certsrv.jobs;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * This class represents a job plugin registered with the
+ * JobScheduler. A Job plugin can be instantiated into a Job instance
+ * and scheduled by the JobScheduler to run at a scheduled interval
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class JobPlugin {
+ /**
+ * The plugin name of this job
+ */
+ protected String mId = null;
+ /**
+ * The Java class name of this job plugin.
+ * e.g. com.netscape.cms.RenewalNotificationJob
+ */
+ protected String mClassPath = null;
+
+ /*
+ * Seems to be unused, should be removed
+ */
+ // protected Class mClass = null;
+
+ /**
+ * Constructor for a Job plugin.
+ * @param id job plugin name
+ * @param classPath the Java class name of this job plugin
+ */
+ public JobPlugin(String id, String classPath) {
+ mId = id;
+ mClassPath = classPath;
+ }
+
+ /**
+ * get the job plugin name
+ * @return the name of this job plugin
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * get the Java class name
+ * @return the Java class name of this plugin
+ */
+ public String getClassPath() {
+ return mClassPath;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/jobs/JobsResources.java b/pki/base/common/src/com/netscape/certsrv/jobs/JobsResources.java
new file mode 100644
index 000000000..00c057902
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/jobs/JobsResources.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.jobs;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the
+ * Jobs package
+ *
+ * @version $Revision$, $Date$
+ */
+public class JobsResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/EKRAException.java b/pki/base/common/src/com/netscape/certsrv/kra/EKRAException.java
new file mode 100644
index 000000000..7992d5fb0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/EKRAException.java
@@ -0,0 +1,88 @@
+// --- 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.certsrv.kra;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a KRA exception. This is the base
+ * exception for all the KRA specific exceptions. It is
+ * associated with <CODE>KRAResources</CODE>.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EKRAException extends EBaseException {
+
+ /**
+ * KRA resource class name.
+ * <P>
+ */
+ private static final String KRA_RESOURCES = KRAResources.class.getName();
+
+ /**
+ * Constructs a KRA exception.
+ * <P>
+ * @param msgFormat constant from KRAResources.
+ */
+ public EKRAException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a KRA exception.
+ * <P>
+ * @param msgFormat constant from KRAResources.
+ * @param param additional parameters to the message.
+ */
+ public EKRAException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a KRA exception.
+ * <P>
+ * @param msgFormat constant from KRAResources.
+ * @param e embedded exception.
+ */
+ public EKRAException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a KRA exception.
+ * <P>
+ * @param msgFormat constant from KRAResources.
+ * @param params additional parameters to the message.
+ */
+ public EKRAException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Returns the bundle file name.
+ * <P>
+ * @return name of bundle class associated with this exception.
+ */
+ protected String getBundleName() {
+ return KRA_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IJoinShares.java b/pki/base/common/src/com/netscape/certsrv/kra/IJoinShares.java
new file mode 100644
index 000000000..e130b95c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/IJoinShares.java
@@ -0,0 +1,33 @@
+// --- 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.certsrv.kra;
+
+/**
+ * Use Java's reflection API to leverage CMS's
+ * old Share and JoinShares implementations.
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public interface IJoinShares {
+
+ public void initialize(int threshold) throws Exception;
+ public void addShare(int shareNum, byte[] share);
+ public int getShareCount();
+ public byte[] recoverSecret();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java b/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
new file mode 100644
index 000000000..b2d02f2a3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
@@ -0,0 +1,319 @@
+// --- 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.certsrv.kra;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.math.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.security.*;
+import org.mozilla.jss.crypto.*;
+
+
+/**
+ * An interface represents key recovery authority. The
+ * key recovery authority is responsibile for archiving
+ * and recovering user encryption private keys.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IKeyRecoveryAuthority extends ISubsystem {
+
+ public static final String ID = "kra";
+
+ public final static String PROP_NAME = "name";
+ public final static String PROP_HTTP = "http";
+ public final static String PROP_POLICY = "policy";
+ public final static String PROP_DBS = "dbs";
+ public final static String PROP_TOKEN = "token";
+ public final static String PROP_SHARE = "share";
+ public final static String PROP_PROTECTOR = "protector";
+ public final static String PROP_LOGGING = "logging";
+ public final static String PROP_QUEUE_REQUESTS = "queueRequests";
+ public final static String PROP_STORAGE_KEY = "storageUnit";
+ public final static String PROP_TRANSPORT_KEY = "transportUnit";
+ public static final String PROP_NEW_NICKNAME = "newNickname";
+ public static final String PROP_KEYDB_INC = "keydbInc";
+
+ public final static String PROP_NOTIFY_SUBSTORE = "notification";
+ public final static String PROP_REQ_IN_Q_SUBSTORE = "requestInQ";
+
+ /**
+ * Returns the name of this subsystem.
+ * <P>
+ *
+ * @return KRA name
+ */
+ public X500Name getX500Name();
+
+ /**
+ * Retrieves KRA request repository.
+ * <P>
+ *
+ * @return request repository
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Retrieves the key repository. The key repository
+ * stores archived keys.
+ * <P>
+ */
+ public IKeyRepository getKeyRepository();
+
+ /**
+ * Retrieves the Replica ID repository.
+ *
+ * @return KRA's Replica ID repository
+ */
+ public IReplicaIDRepository getReplicaRepository();
+
+ /**
+ * Enables the auto recovery state. Once KRA is in the auto
+ * recovery state, no recovery agents need to be present for
+ * providing credentials. This feature is for enabling
+ * user-based recovery operation.
+ * <p>
+ *
+ * @param cs list of agent credentials
+ * @param on true if auto recovery state is on
+ * @return current auto recovery state
+ */
+ public boolean setAutoRecoveryState(Credential cs[], boolean on);
+
+ /**
+ * Returns the current auto recovery state.
+ *
+ * @return true if auto recvoery state is on
+ */
+ public boolean getAutoRecoveryState();
+
+ /**
+ * Adds credentials to the given authorizated recovery operation.
+ * In distributed recovery mode, recovery agent login to the
+ * agent interface and submit its credential for a particular
+ * recovery operation.
+ *
+ * @param id authorization identifier
+ * @param creds list of credentials
+ */
+ public void addAutoRecovery(String id, Credential creds[]);
+
+ /**
+ * Removes a particular auto recovery operation.
+ *
+ * @param id authorization identifier
+ */
+ public void removeAutoRecovery(String id);
+
+ /**
+ * Returns the number of required agents. In M-out-of-N
+ * recovery schema, only M agents are required even there
+ * are N agents. This method returns M.
+ *
+ * @return number of required agents
+ */
+ public int getNoOfRequiredAgents() throws EBaseException;
+
+ /**
+ * Sets the number of required recovery agents
+ *
+ * @param number number of agents
+ */
+ public void setNoOfRequiredAgents(int number) throws EBaseException;
+
+ /**
+ * Returns the current recovery identifier.
+ *
+ * @return recovery identifier
+ */
+ public String getRecoveryID();
+
+ /**
+ * Returns a list of recovery identifiers.
+ *
+ * @return list of auto recovery identifiers
+ */
+ public Enumeration getAutoRecoveryIDs();
+
+ /**
+ * Returns the storage key unit that manages the
+ * stoarge key.
+ *
+ * @return storage key unit
+ */
+ public IStorageKeyUnit getStorageKeyUnit();
+
+ /**
+ * Returns the transport key unit that manages the
+ * transport key.
+ *
+ * @return transport key unit
+ */
+ public ITransportKeyUnit getTransportKeyUnit();
+
+ /**
+ * Returns the token that generates user key pairs for supporting server-side keygen
+ *
+ * @return keygen token
+ */
+ public CryptoToken getKeygenToken();
+
+ /**
+ * Adds entropy to the token used for supporting server-side keygen
+ * Parameters are set in the config file
+ * @param logflag create log messages at info level to report entropy shortage
+ */
+ public void addEntropy(boolean logflag);
+
+
+ /**
+ * Returns the request listener that listens on
+ * the request completion event.
+ *
+ * @return request listener
+ */
+ public IRequestListener getRequestInQListener();
+
+ /**
+ * Returns policy processor of the key recovery
+ * authority.
+ *
+ * @return policy processor
+ */
+ public IPolicyProcessor getPolicyProcessor();
+
+ /**
+ * Returns the nickname of the transport certificate.
+ *
+ * @return transport certificate nickname.
+ */
+ public String getNickname();
+
+ /**
+ * Sets the nickname of the transport certificate.
+ *
+ * @param str nickname
+ */
+ public void setNickname(String str);
+
+ /**
+ * Returns the new nickname of the transport certifiate.
+ *
+ * @return new nickname
+ */
+ public String getNewNickName() throws EBaseException;
+
+ /**
+ * Sets the new nickname of the transport certifiate.
+ *
+ * @param name new nickname
+ */
+ public void setNewNickName(String name);
+
+ /**
+ * Logs event into key recovery authority logging.
+ *
+ * @param level log level
+ * @param msg log message
+ */
+ public void log(int level, String msg);
+
+ /**
+ * Creates a request object to store attributes that
+ * will not be serialized. Currently, request queue
+ * framework will try to serialize all the attribute into
+ * persistent storage. Things like passwords are not
+ * desirable to be stored.
+ *
+ * @param id request id
+ * @return volatile requests
+ */
+ public Hashtable createVolatileRequest(RequestId id);
+
+ /**
+ * Retrieves the request object.
+ *
+ * @param id request id
+ * @return volatile requests
+ */
+ public Hashtable getVolatileRequest(RequestId id);
+
+ /**
+ * Destroys the request object.
+ *
+ * @param id request id
+ */
+ public void destroyVolatileRequest(RequestId id);
+
+ public Vector getAppAgents(
+ String recoveryID) throws EBaseException;
+
+ /**
+ * Creates error for a specific recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @param error error
+ * @exception EBaseException failed to create error
+ */
+ public void createError(String recoveryID, String error)
+ throws EBaseException;
+
+ /**
+ * Retrieves error by recovery identifier.
+ *
+ * @param recoveryID recovery id
+ * @return error message
+ */
+ public String getError(String recoveryID)
+ throws EBaseException;
+
+ /**
+ * Retrieves PKCS12 package by recovery identifier.
+ *
+ * @param recoveryID recovery id
+ * @return pkcs12 package in bytes
+ */
+ public byte[] getPk12(String recoveryID)
+ throws EBaseException;
+
+ /**
+ * Creates PKCS12 package in memory.
+ *
+ * @param recoveryID recovery id
+ * @param pk12 package in bytes
+ */
+ public void createPk12(String recoveryID, byte[] pk12)
+ throws EBaseException;
+
+ /**
+ * Retrieves the transport certificate.
+ */
+ public org.mozilla.jss.crypto.X509Certificate getTransportCert();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IKeyService.java b/pki/base/common/src/com/netscape/certsrv/kra/IKeyService.java
new file mode 100644
index 000000000..5fe5a4025
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/IKeyService.java
@@ -0,0 +1,177 @@
+// --- 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.certsrv.kra;
+
+
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.security.cert.X509Certificate;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import netscape.security.x509.X509CertImpl;
+
+
+/**
+ * An interface representing a recovery service.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IKeyService {
+
+ /**
+ * Retrieves number of agent required to perform
+ * key recovery operation.
+ *
+ * @return number of required recovery agents
+ * @exception EBaseException failed to retrieve value
+ */
+ public int getNoOfRequiredAgents() throws EBaseException;
+
+ /**
+ * is async recovery request status APPROVED -
+ * i.e. all required # of recovery agents approved
+ * @param reqID request id
+ * @return true if # of recovery required agents approved; false otherwise
+ */
+ public boolean isApprovedAsyncKeyRecovery(String reqID)
+ throws EBaseException;
+
+ /**
+ * get async recovery request initiating agent
+ * @param reqID request id
+ * @return agentUID
+ */
+ public String getInitAgentAsyncKeyRecovery(String reqID)
+ throws EBaseException;
+
+ /**
+ * Initiate asynchronous key recovery
+ * @param kid key identifier
+ * @param cert certificate embedded in PKCS12
+ * @return requestId
+ * @exception EBaseException failed to initiate async recovery
+ */
+ public String initAsyncKeyRecovery(BigInteger kid, X509CertImpl cert, String agent)
+ throws EBaseException;
+
+ /**
+ * add approving agent in asynchronous key recovery
+ * @param reqID request id
+ * @param agentID agent id
+ * @exception EBaseException failed to initiate async recovery
+ */
+ public void addAgentAsyncKeyRecovery(String reqID, String agentID)
+ throws EBaseException;
+
+ /**
+ * Performs administrator-initiated key recovery.
+ *
+ * @param kid key identifier
+ * @param creds list of credentials (id and password)
+ * @param pwd password to protect PKCS12
+ * @param cert certificate embedded in PKCS12
+ * @param delivery delivery mechanism
+ * @return pkcs12
+ * @exception EBaseException failed to perform recovery
+ */
+ public byte[] doKeyRecovery(BigInteger kid,
+ Credential creds[], String pwd, X509CertImpl cert,
+ String delivery, String nickname, String agent) throws EBaseException;
+
+ /**
+ * Async Recovers key for administrators. This method is
+ * invoked by the agent operation of the key recovery servlet.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST used whenever
+ * a user private key recovery request is made (this is when the DRM
+ * receives the request)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED used whenever
+ * a user private key recovery request is processed (this is when the DRM
+ * processes the request)
+ * </ul>
+ * @param reqID request id
+ * @param password password of the PKCS12 package
+ * subsystem
+ * @exception EBaseException failed to recover key
+ * @return a byte array containing the key
+ */
+ public byte[] doKeyRecovery(
+ String reqID,
+ String password)
+ throws EBaseException;
+
+ /**
+ * Retrieves recovery identifier.
+ *
+ * @return recovery id
+ */
+ public String getRecoveryID();
+
+ /**
+ * Creates recovery parameters for the given recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @return recovery parameters
+ * @exception EBaseException failed to create
+ */
+ public Hashtable createRecoveryParams(String recoveryID)
+ throws EBaseException;
+
+ /**
+ * Destroys recovery parameters for the given recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @exception EBaseException failed to destroy
+ */
+ public void destroyRecoveryParams(String recoveryID)
+ throws EBaseException;
+
+ /**
+ * Retrieves recovery parameters for the given recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @return recovery parameters
+ * @exception EBaseException failed to retrieve
+ */
+ public Hashtable getRecoveryParams(String recoveryID)
+ throws EBaseException;
+
+ /**
+ * Adds password in the distributed recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @param uid agent uid
+ * @param pwd agent password
+ * @exception EBaseException failed to add
+ */
+ public void addDistributedCredential(String recoveryID,
+ String uid, String pwd) throws EBaseException;
+
+ /**
+ * Retrieves credentials in the distributed recovery operation.
+ *
+ * @param recoveryID recovery id
+ * @return agent's credentials
+ * @exception EBaseException failed to retrieve
+ */
+ public Credential[] getDistributedCredentials(String recoveryID)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java b/pki/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java
new file mode 100644
index 000000000..571380eaf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java
@@ -0,0 +1,87 @@
+// --- 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.certsrv.kra;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents a proof of archival.
+ * <P>
+ * Here is the ASN1 definition of a proof of escrow:
+ * <PRE>
+ * ProofOfArchival ::= SIGNED {
+ * SEQUENCE {
+ * version [0] Version DEFAULT v1,
+ * serialNumber INTEGER,
+ * subjectName Name,
+ * issuerName Name,
+ * dateOfArchival Time,
+ * extensions [1] Extensions OPTIONAL
+ * }
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProofOfArchival {
+
+ /**
+ * Retrieves version of this proof.
+ *
+ * @return version
+ */
+ public BigInteger getVersion();
+
+ /**
+ * Retrieves the serial number.
+ *
+ * @return serial number
+ */
+ public BigInteger getSerialNumber();
+
+ /**
+ * Retrieves the subject name.
+ *
+ * @return subject name
+ */
+ public String getSubjectName();
+
+ /**
+ * Retrieves the issuer name.
+ *
+ * @return issuer name
+ */
+ public String getIssuerName();
+
+ /**
+ * Returns the beginning of the escrowed perioid.
+ *
+ * @return date of archival
+ */
+ public Date getDateOfArchival();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IShare.java b/pki/base/common/src/com/netscape/certsrv/kra/IShare.java
new file mode 100644
index 000000000..c4d58f0a0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/IShare.java
@@ -0,0 +1,32 @@
+// --- 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.certsrv.kra;
+
+/**
+ * Use Java's reflection API to leverage CMS's
+ * old Share and JoinShares implementations.
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public interface IShare {
+
+ public void initialize(byte[] secret, int threshold) throws Exception;
+ public byte[] createShare(int sharenumber);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/KRAResources.java b/pki/base/common/src/com/netscape/certsrv/kra/KRAResources.java
new file mode 100644
index 000000000..74f66992b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/KRAResources.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.kra;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for KRA subsystem.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class KRAResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ static final Object[][] contents = {
+ };
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java b/pki/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java
new file mode 100644
index 000000000..5fe06f921
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java
@@ -0,0 +1,440 @@
+// --- 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.certsrv.kra;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+//import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a proof of escrow. It indicates a key
+ * pairs have been escrowed by appropriate authority. The
+ * structure of this object is very similar (if not exact) to
+ * X.509 certificate. A proof of escrow is signed by an escrow
+ * authority. It is possible to have a CMS policy to reject
+ * the certificate issuance request if proof of escrow is not
+ * presented.
+ * <P>
+ * Here is the ASN1 definition of a proof of escrow:
+ * <PRE>
+ * ProofOfEscrow ::= SIGNED {
+ * SEQUENCE {
+ * version [0] Version DEFAULT v1,
+ * serialNumber INTEGER,
+ * subjectName Name,
+ * issuerName Name,
+ * dateOfArchival Time,
+ * extensions [1] Extensions OPTIONAL
+ * }
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ProofOfArchival implements IDBObj, IProofOfArchival, Serializable {
+
+ /**
+ * Constants
+ */
+ public static final BigInteger DEFAULT_VERSION = new BigInteger("1");
+
+ public static final String ATTR_VERSION = "pofVersion";
+ public static final String ATTR_SERIALNO = "pofSerialNo";
+ public static final String ATTR_SUBJECT = "pofSubject";
+ public static final String ATTR_ISSUER = "pofIssuer";
+ public static final String ATTR_DATE_OF_ARCHIVAL = "pofDateOfArchival";
+
+ protected BigInteger mSerialNo = null;
+ protected BigInteger mVersion = null;
+ protected String mSubject = null;
+ protected String mIssuer = null;
+ protected Date mDateOfArchival = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_VERSION);
+ mNames.addElement(ATTR_SERIALNO);
+ mNames.addElement(ATTR_SUBJECT);
+ mNames.addElement(ATTR_ISSUER);
+ mNames.addElement(ATTR_DATE_OF_ARCHIVAL);
+ }
+
+ /**
+ * Constructs a proof of escrow.
+ * <P>
+ * @param serialNo serial number of proof
+ * @param subject subject name
+ * @param issuer issuer name
+ * @param dateOfArchival date of archival
+ */
+ public ProofOfArchival(BigInteger serialNo, String subject,
+ String issuer, Date dateOfArchival) {
+ mVersion = DEFAULT_VERSION;
+ mSerialNo = serialNo;
+ mSubject = subject;
+ mIssuer = issuer;
+ mDateOfArchival = dateOfArchival;
+ }
+
+ /**
+ * Constructs proof of escrow from input stream.
+ * <P>
+ * @param in encoding source
+ * @exception EBaseException failed to decode
+ */
+ public ProofOfArchival(InputStream in) throws EBaseException {
+ decode(in);
+ }
+
+ /**
+ * Sets an attribute value.
+ * <P>
+ * @param name attribute name
+ * @param obj attribute value
+ * @exception EBaseException failed to set attribute
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equals(ATTR_VERSION)) {
+ mVersion = (BigInteger) obj;
+ } else if (name.equals(ATTR_SERIALNO)) {
+ mSerialNo = (BigInteger) obj;
+ } else if (name.equals(ATTR_SUBJECT)) {
+ mSubject = (String) obj;
+ } else if (name.equals(ATTR_ISSUER)) {
+ mIssuer = (String) obj;
+ } else if (name.equals(ATTR_DATE_OF_ARCHIVAL)) {
+ mDateOfArchival = (Date) obj;
+ } else {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves the value of an named attribute.
+ * <P>
+ * @param name attribute name
+ * @return attribute value
+ * @exception EBaseException failed to get attribute
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equals(ATTR_VERSION)) {
+ return mVersion;
+ } else if (name.equals(ATTR_SERIALNO)) {
+ return mSerialNo;
+ } else if (name.equals(ATTR_SUBJECT)) {
+ return mSubject;
+ } else if (name.equals(ATTR_ISSUER)) {
+ return mIssuer;
+ } else if (name.equals(ATTR_DATE_OF_ARCHIVAL)) {
+ return mDateOfArchival;
+ } else {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes an attribute.
+ * <P>
+ * @param name attribute name
+ * @exception EBaseException failed to get attribute
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ /**
+ * Retrieves a list of possible attribute names.
+ * <P>
+ *
+ * @return a list of names
+ */
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serializable attribute names.
+ *
+ * @return a list of serializable attribute names
+ */
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves version of this proof.
+ * <P>
+ * @return version
+ */
+ public BigInteger getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Retrieves the serial number.
+ * <P>
+ * @return serial number
+ */
+ public BigInteger getSerialNumber() {
+ return mSerialNo;
+ }
+
+ /**
+ * Retrieves the subject name.
+ * <P>
+ * @return subject name
+ */
+ public String getSubjectName() {
+ return mSubject;
+ }
+
+ /**
+ * Retrieves the issuer name.
+ * <P>
+ * @return issuer name
+ */
+ public String getIssuerName() {
+ return mIssuer;
+ }
+
+ /**
+ * Returns the beginning of the escrowed perioid.
+ * <P>
+ * @return date of archival
+ */
+ public Date getDateOfArchival() {
+ return mDateOfArchival;
+ }
+
+ /**
+ * Encodes this proof of escrow into the given
+ * output stream.
+ * <P>
+ */
+ public void encode(DerOutputStream out) throws EBaseException {
+ try {
+ DerOutputStream seq = new DerOutputStream();
+
+ // version (OPTIONAL)
+ if (!mVersion.equals(DEFAULT_VERSION)) {
+ DerOutputStream version = new DerOutputStream();
+
+ version.putInteger(new BigInt(mVersion));
+ seq.write(DerValue.createTag(
+ DerValue.TAG_CONTEXT, true, (byte) 0),
+ version);
+ }
+
+ // serial number
+ DerOutputStream serialno = new DerOutputStream();
+
+ seq.putInteger(new BigInt(mSerialNo));
+
+ // subject name
+ DerOutputStream subject = new DerOutputStream();
+
+ (new X500Name(mSubject)).encode(seq);
+
+ // issuer name
+ DerOutputStream issuer = new DerOutputStream();
+
+ (new X500Name(mIssuer)).encode(seq);
+
+ // issue date
+ seq.putUTCTime(mDateOfArchival);
+ out.write(DerValue.tag_Sequence, seq);
+
+ } catch (IOException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED", e.toString()));
+ }
+ }
+
+ /**
+ * Encodes and signs this proof of escrow.
+ * <P>
+ */
+ public void encodeAndSign(PrivateKey key, String algorithm,
+ String provider, DerOutputStream out)
+ throws EBaseException {
+
+ try {
+ Signature sigEngine = null;
+
+ if (provider == null) {
+ sigEngine = Signature.getInstance(algorithm);
+ } else {
+ sigEngine = Signature.getInstance(algorithm,
+ provider);
+ }
+
+ sigEngine.initSign(key);
+ DerOutputStream tmp = new DerOutputStream();
+
+ encode(tmp);
+
+ AlgorithmId sigAlgId = AlgorithmId.get(
+ sigEngine.getAlgorithm());
+
+ sigAlgId.encode(tmp);
+ byte dataToSign[] = tmp.toByteArray();
+
+ sigEngine.update(dataToSign, 0, dataToSign.length);
+ byte signature[] = sigEngine.sign();
+
+ tmp.putBitString(signature);
+ out.write(DerValue.tag_Sequence, tmp);
+ return;
+ } catch (NoSuchAlgorithmException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString()));
+ } catch (NoSuchProviderException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString()));
+ } catch (SignatureException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString()));
+ } catch (IOException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString()));
+ }
+ }
+
+ /**
+ * Decodes the input stream.
+ * <P>
+ */
+ public void decode(InputStream in) throws EBaseException {
+ try {
+ // POA is a SIGNED ASN.1 macro, a three element sequence:
+ // - Data to be signed (ToBeSigned) -- the "raw" data
+ // - Signature algorithm (SigAlgId)
+ // - The Signature bits
+
+ DerValue val = new DerValue(in);
+
+ DerValue seq[] = new DerValue[3];
+
+ seq[0] = val.data.getDerValue();
+ if (seq[0].tag == DerValue.tag_Sequence) {
+ // with signature
+ seq[1] = val.data.getDerValue();
+ seq[2] = val.data.getDerValue();
+ if (seq[1].data.available() != 0) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED_1",
+ "no algorithm found"));
+ }
+
+ if (seq[2].data.available() != 0) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED_1",
+ "no signature found"));
+ }
+
+ AlgorithmId algid = AlgorithmId.parse(seq[1]);
+ byte signature[] = seq[2].getBitString();
+
+ decodePOA(val, null);
+ } else {
+ // without signature
+ decodePOA(val, seq[0]);
+ }
+ } catch (IOException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED_1", e.toString()));
+ }
+ }
+
+ /**
+ * Decodes proof of escrow.
+ * <P>
+ */
+ private void decodePOA(DerValue val, DerValue preprocessed)
+ throws EBaseException {
+ try {
+ DerValue tmp = null;
+
+ if (preprocessed == null) {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED_1",
+ "not start with sequence"));
+ }
+ tmp = val.data.getDerValue();
+ } else {
+ tmp = preprocessed;
+ }
+
+ // version
+ if (tmp.isContextSpecific((byte) 0)) {
+ if (tmp.isConstructed() && tmp.isContextSpecific()) {
+ DerValue version = tmp.data.getDerValue();
+ BigInt ver = version.getInteger();
+
+ mVersion = ver.toBigInteger();
+ tmp = val.data.getDerValue();
+ }
+ } else {
+ mVersion = DEFAULT_VERSION;
+ }
+
+ // serial number
+ DerValue serialno = tmp;
+
+ mSerialNo = serialno.getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = val.data.getDerValue();
+
+ // mSubject = new X500Name(subject); // doesnt work
+ mSubject = new String(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = val.data.getDerValue();
+
+ mIssuer = new String(issuer.toByteArray());
+
+ // date of archival
+ mDateOfArchival = val.data.getUTCTime();
+ } catch (IOException e) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_DECODE_FAILED_1", e.toString()));
+ }
+ }
+
+ /**
+ * Retrieves the string reprensetation of this
+ * proof of archival.
+ */
+ public String toString() {
+ return "Version: " + mVersion.toString() + "\n" +
+ "SerialNo: " + mSerialNo.toString() + "\n" +
+ "Subject: " + mSubject + "\n" +
+ "Issuer: " + mIssuer + "\n" +
+ "DateOfArchival: " + mDateOfArchival.toString();
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ELdapException.java b/pki/base/common/src/com/netscape/certsrv/ldap/ELdapException.java
new file mode 100644
index 000000000..3f829aa31
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ELdapException.java
@@ -0,0 +1,86 @@
+// --- 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.certsrv.ldap;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class that represents a Ldap exception. Various
+ * errors can occur when interacting with a Ldap directory server.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELdapException extends EBaseException {
+
+ /**
+ * Ldap resource class name.
+ */
+ private static final String LDAP_RESOURCES = LdapResources.class.getName();
+
+ /**
+ * Constructs a Ldap exception.
+ * @param msgFormat Resource Key, if key not present, serves as the message.
+ * <P>
+ */
+ public ELdapException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a Ldap exception.
+ * @param msgFormat Resource Key, if key not present, serves as the message.
+ * Include a message string parameter for variable content.
+ * @param param Message string parameter.
+ * <P>
+ */
+ public ELdapException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a Ldap exception.
+ * @param msgFormat Resource Key, if key not present, serves as the message.
+ * @param e Common exception.
+ * <P>
+ */
+ public ELdapException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a Ldap exception.
+ * @param msgFormat Resource Key, if key not present, serves as the message.
+ * @param params Array of Message string parameters.
+ * <P>
+ */
+ public ELdapException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Gets the resource bundle name
+ * @return Name of the Ldap Exception resource bundle name.
+ * <p>
+ */
+ protected String getBundleName() {
+ return LDAP_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java b/pki/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java
new file mode 100644
index 000000000..b6b04a760
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java
@@ -0,0 +1,35 @@
+// --- 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.certsrv.ldap;
+
+
+/**
+ * This represents exception which indicates Ldap server is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELdapServerDownException extends ELdapException {
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ * @param errorString Detailed error message.
+ */
+ public ELdapServerDownException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java
new file mode 100644
index 000000000..13cadf2ab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java
@@ -0,0 +1,103 @@
+// --- 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.certsrv.ldap;
+
+
+import java.util.Hashtable;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Class for obtaining ldap authentication info from the configuration store.
+ * Two types of authentication is basic and SSL client authentication.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILdapAuthInfo {
+ static public final String PROP_LDAPAUTHTYPE = "authtype";
+ static public final String PROP_CLIENTCERTNICKNAME = "clientCertNickname";
+ static public final String PROP_BINDDN = "bindDN";
+ static public final String PROP_BINDPW = "bindPassword";
+ static public final String PROP_BINDPW_PROMPT = "bindPWPrompt";
+ static public final String PROP_BINDDN_DEFAULT = "cn=Directory Manager";
+
+ static public final String LDAP_BASICAUTH_STR = "BasicAuth";
+ static public final String LDAP_SSLCLIENTAUTH_STR = "SslClientAuth";
+
+ static public final int LDAP_AUTHTYPE_NONE = 0; // illegal
+ static public final int LDAP_AUTHTYPE_BASICAUTH = 1;
+ static public final int LDAP_AUTHTYPE_SSLCLIENTAUTH = 2;
+
+ /**
+ * Initialize this class from the config store.
+ * @param config The config store from which to initialize.
+ * @exception EBaseException Due to failure of the initialization process.
+ *
+ */
+ public void init(IConfigStore config) throws EBaseException;
+
+ /**
+ * Initialize this class from the config store.
+ * Based on host, port, and secure boolean info.
+ * which allows an actual attempt on the server to verify credentials.
+ * @param config The config store from which to initialize.
+ * @exception EBaseException Due to failure of the initialization process.
+ *
+ */
+ public void init(IConfigStore config, String host, int port, boolean secure)
+ throws EBaseException;
+
+ /**
+ * Reset the connection to the host
+ */
+ public void reset();
+
+ /**
+ * Get authentication type.
+ * @return one of: <br>
+ * LdapAuthInfo.LDAP_AUTHTYPE_BASICAUTH or
+ * LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH
+ */
+ public int getAuthType();
+
+ /**
+ * Get params for authentication.
+ * @return array of parameters for this authentication as an array of Strings.
+ */
+ public String[] getParms();
+
+ /**
+ * Add password to private password data structure.
+ * @param prompt Password prompt.
+ * @param pw Password itself.
+ */
+ public void addPassword(String prompt, String pw);
+
+ /**
+ * Remove password from private password data structure.
+ * @param prompt Identify password to remove with prompt.
+ */
+ public void removePassword(String prompt);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java
new file mode 100644
index 000000000..71b810709
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.ldap;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Maintains a pool of connections to the LDAP server.
+ * CMS requests are processed on a multi threaded basis.
+ * A pool of connections then must be be maintained so this
+ * access to the Ldap server can be easily managed. The min and
+ * max size of this connection pool should be configurable. Once
+ * the maximum limit of connections is exceeded, the factory
+ * should provide proper synchronization to resolve contention issues.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILdapBoundConnFactory extends ILdapConnFactory {
+
+ public static final String PROP_MINCONNS = "minConns";
+ public static final String PROP_MAXCONNS = "maxConns";
+ public static final String PROP_LDAPCONNINFO = "ldapconn";
+ public static final String PROP_LDAPAUTHINFO = "ldapauth";
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java
new file mode 100644
index 000000000..8ac2cd505
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java
@@ -0,0 +1,90 @@
+// --- 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.certsrv.ldap;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Maintains a pool of connections to the LDAP server.
+ * Multiple threads use this interface to utilize and release
+ * the Ldap connection resources.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILdapConnFactory {
+
+ /**
+ * Initialize the poll from the config store.
+ * @param config The configuration substore.
+ * @exception EBaseException On configuration error.
+ * @exception ELdapException On all other errors.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException, ELdapException;
+
+ /**
+ *
+ * Used for disconnecting all connections.
+ * Used just before a subsystem
+ * shutdown or process exit.
+ * @exception EldapException on Ldap failure when closing connections.
+ */
+ public void reset()
+ throws ELdapException;
+
+ /**
+ * Returns the number of free connections available from this pool.
+ * @return Integer number of free connections.
+ */
+
+ public int freeConn();
+
+ /**
+ * Returns the number of total connections available from this pool.
+ * Includes sum of free and in use connections.
+ * @return Integer number of total connections.
+ */
+ public int totalConn();
+
+ /**
+ * Returns the maximum number of connections available from this pool.
+ * @return Integer maximum number of connections.
+ */
+ public int maxConn();
+
+ /**
+ * Request access to a Ldap connection from the pool.
+ * @exception ELdapException if any error occurs, such as a
+ * @return Ldap connection object.
+ * connection is not available
+ */
+ public LDAPConnection getConn()
+ throws ELdapException;
+
+ /**
+ * Return connection to the factory. mandatory after a getConn().
+ * @param conn Ldap connection object to be returned to the free list of the pool.
+ * @exception ELdapException On any failure to return the connection.
+ */
+ public void returnConn(LDAPConnection conn)
+ throws ELdapException;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java
new file mode 100644
index 000000000..f56bf4d3e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java
@@ -0,0 +1,84 @@
+// --- 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.certsrv.ldap;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Class for reading ldap connection information from the config store.
+ * Ldap connection info: host name, port number,whether of not it is a secure connection.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILdapConnInfo {
+ public static final String PROP_HOST = "host";
+ public static final String PROP_PORT = "port";
+ public static final String PROP_SECURE = "secureConn";
+ public static final String PROP_PROTOCOL = "version";
+ public static final String PROP_FOLLOW_REFERRALS = "followReferrals";
+ public static final String PROP_HOST_DEFAULT = "localhost";
+ public static final String PROP_PORT_DEFAULT = "389";
+
+ public static final int LDAP_VERSION_2 = 2;
+ public static final int LDAP_VERSION_3 = 3;
+
+ /**
+ * Initializes an instance from a config store.
+ * @param config Configuration store.
+ * @exception ELdapException Ldap related error found.
+ * @exception EBaseException Other errors and errors with params included in the config store.
+ */
+ public void init(IConfigStore config) throws EBaseException, ELdapException;
+
+ /**
+ * Return the name of the Host.
+ *
+ */
+
+
+ public String getHost();
+
+ /**
+ * Return the port number of the host.
+ *
+ */
+ public int getPort();
+
+ /**
+ * Return the Ldap version number of the Ldap server.
+ */
+
+ public int getVersion();
+
+ /**
+ * Return whether or not the connection is secure.
+ */
+ public boolean getSecure();
+
+ /**
+ * Return whether or not the server is to follow referrals
+ * to other servers when servicing a query.
+ */
+ public boolean getFollowReferrals();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java
new file mode 100644
index 000000000..3cf762663
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java
@@ -0,0 +1,60 @@
+// --- 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.certsrv.ldap;
+
+
+import com.netscape.certsrv.base.*;
+import java.security.cert.*;
+
+
+/**
+ * Class on behalf of the Publishing system that controls an instance of an ILdapConnFactory.
+ * Allows a factory to be intialized and grants access
+ * to the factory to other interested parties.
+ *
+ * @version $Revision$, $Date$
+ */
+
+public interface ILdapConnModule {
+
+ /**
+ * Initialize ldap publishing module with config store.
+ * @param owner Entity that is interested in this instance of Publishing.
+ * @param config Config store containing the info needed to set up Publishing.
+ * @exception ELdapException Due to Ldap error.
+ * @exception EBaseException Due to config value errors and all other errors.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException, ELdapException;
+
+ /**
+ * Returns the internal ldap connection factory.
+ * This can be useful to get a ldap connection to the
+ * ldap publishing directory without having to get it again from the
+ * config file. Note that this means sharing a ldap connection pool
+ * with the ldap publishing module so be sure to return connections to pool.
+ * Use ILdapConnFactory.getConn() to get a Ldap connection to the ldap
+ * publishing directory.
+ * Use ILdapConnFactory.returnConn() to return the connection.
+ *
+ * @return Instance of ILdapConnFactory.
+ */
+
+ public ILdapConnFactory getLdapConnFactory();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ldap/LdapResources.java b/pki/base/common/src/com/netscape/certsrv/ldap/LdapResources.java
new file mode 100644
index 000000000..79a8aecb4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ldap/LdapResources.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.ldap;
+
+
+import java.util.*;
+
+
+/**
+ * A resource bundle for ldap subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/listeners/EListenersException.java b/pki/base/common/src/com/netscape/certsrv/listeners/EListenersException.java
new file mode 100644
index 000000000..40dad6eb9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/listeners/EListenersException.java
@@ -0,0 +1,84 @@
+// --- 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.certsrv.listeners;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a listener exception.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class EListenersException extends EBaseException {
+
+ /**
+ * CA resource class name.
+ */
+ private static final String LISTENERS_RESOURCES = ListenersResources.class.getName();
+
+ /**
+ * Constructs a listeners exception.
+ * <P>
+ * @param msgFormat The error message resource key.
+ */
+ public EListenersException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a listeners exception.
+ * <P>
+ * @param msgFormat exception details in message string format.
+ * @param param message string parameter.
+ */
+ public EListenersException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a Listeners exception.
+ * <P>
+ * @param msgFormat The resource key.
+ * @param e The parameter as an exception.
+ */
+ public EListenersException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a Listeners exception.
+ * <P>
+ * @param msgFormat The resource key.
+ * @param params Array of params.
+ */
+ public EListenersException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+ /**
+ * get the listener resource class name.
+ * <P>
+ * @return the class name of the resource.
+ */
+ protected String getBundleName() {
+ return LISTENERS_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java b/pki/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java
new file mode 100644
index 000000000..83f6bd68d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java
@@ -0,0 +1,77 @@
+// --- 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.certsrv.listeners;
+
+
+import com.netscape.certsrv.base.*;
+
+/**
+ * This interface represents a plug-in listener. Implement this class to
+ * add the listener to an ARequestNotifier of a subsystem.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public interface IRequestListenerPlugin {
+
+ /**
+ * get the registered class name set in the init() method.
+ * <P>
+ * @return the Name.
+ */
+ public String getName();
+
+ /**
+ * get the plugin implementaion name set in the init() method.
+ * <P>
+ * @return the plugin implementation name.
+ */
+ public String getImplName();
+
+ /**
+ * the subsystem call this method to initialize the plug-in.
+ * <P>
+ * @param name the registered class name of the plug-in.
+ * @param implName the implemetnation name of the plug-in.
+ * @param config the configuration store where the.
+ * properties of the plug-in are stored.
+ * @exception EBaseException throws base exception in the certificate server.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException;
+ /**
+ * shutdown the plugin.
+ */
+ public void shutdown();
+ /**
+ * get the configuration parameters of the plug-in.
+ * <P>
+ * @return the configuration parameters.
+ * @exception EBaseException throws base exception in the certificate server.
+ */
+ public String[] getConfigParams()
+ throws EBaseException;
+ /**
+ * get the configuration store of the plugin where the
+ * configuration parameters of the plug-in are stored.
+ * <P>
+ * @return the configuration store.
+ */
+
+ public IConfigStore getConfigStore();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java b/pki/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java
new file mode 100644
index 000000000..7fae366d8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.listeners;
+
+
+import java.util.*;
+
+/**
+ * A class represents a resource bundle for the
+ * listeners package.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ListenersResources extends ListResourceBundle {
+
+ /**
+ * get the content of the resource.
+ * <P>
+ * @return the content of this resource is a value pairs array of keys and values.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+ static final Object[][] contents = {
+ };
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/pki/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
new file mode 100644
index 000000000..8fa1249f6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -0,0 +1,331 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * The log event object that carries message detail of a log event
+ * that goes into the Transaction log. Note that the name of this
+ * class "AuditEvent" is legacy and has nothing to do with the signed
+ * audit log events, whcih are represented by SignedAuditEvent.
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see com.netscape.certsrv.logging.LogResources
+ */
+public class AuditEvent implements IBundleLogEvent {
+
+ protected Object mParams[] = null;
+
+ private String mEventType = null;
+ private String mMessage = null;
+ private int mLevel = -1;
+ private int mNTEventType = -1;
+ private int mSource = -1;
+ private boolean mMultiline = false;
+ private long mTimeStamp = System.currentTimeMillis();
+
+ /**
+ * The bundle name for this event.
+ */
+ private String mBundleName = LogResources.class.getName();
+ private static final String INVALID_LOG_LEVEL="log level: {0} is invalid, should be 0-6";
+
+ /**
+ * Constructs a message event
+ * <P>
+ *
+ * @param msgFormat the message string
+ */
+ public AuditEvent(String msgFormat) {
+ mMessage = msgFormat;
+ mParams = null;
+ }
+
+ /**
+ * Constructs a message with a parameter. For example,
+ * <PRE>
+ * new AuditEvent("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat details in message string format
+ * @param param message string parameter
+ */
+ public AuditEvent(String msgFormat, String param) {
+ this(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a message from an exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * logHandler.log(new AuditEvent("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param exception system exception
+ */
+ public AuditEvent(String msgFormat, Exception exception) {
+ this(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = exception;
+ }
+
+ /**
+ * Constructs a message from a base exception. This will use the msgFormat
+ * from the exception itself.
+ * <PRE>
+ * try {
+ * ...
+ * } catch (Exception e) {
+ * logHandler.log(new AuditEvent(e));
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param e CMS exception
+ */
+ public AuditEvent(Exception e) {
+ this(e.getMessage());
+ if (e instanceof EBaseException) {
+ mParams = ((EBaseException) e).getParameters();
+ } else {
+ mParams = new Exception[1];
+ mParams[0] = e;
+ }
+ }
+
+ /**
+ * Constructs a message event with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat message string format
+ * @param params list of message format parameters
+ */
+ public AuditEvent(String msgFormat, Object params[]) {
+ this(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns the current message format string.
+ * <P>
+ *
+ * @return details message
+ */
+ public String getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Returns a list of parameters.
+ * <P>
+ *
+ * @return list of message format parameters
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized message string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return details message
+ */
+ public String toContent() {
+ return toContent(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale locale
+ * @return details message
+ */
+ public String toContent(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ getMessage(),
+ getParameters());
+ }
+
+ /**
+ * Gets the resource bundle name for this class instance. This should
+ * be overridden by subclasses who have their own resource bundles.
+ * @param bundle String that represents the resource bundle name to be set
+ */
+ public void setBundleName(String bundle) {
+ mBundleName = bundle;
+ }
+
+ /**
+ * Retrieves bundle name.
+ * @return a String that represents the resource bundle name
+ */
+ protected String getBundleName() {
+ return mBundleName;
+ }
+
+ /**
+ * Retrieves log source.
+ * @return an integer that indicates the component source
+ * where this message event was triggered
+ */
+ public int getSource() {
+ return mSource;
+ }
+
+ /**
+ * Sets log source.
+ * @param source an integer that represents the component source
+ * where this message event was triggered
+ */
+ public void setSource(int source) {
+ mSource = source;
+ }
+
+
+ /**
+ * Retrieves log level.
+ * The log level of an event represents its relative importance
+ * or severity within CMS.
+ * @return Integer log level value.
+ */
+ public int getLevel() {
+ return mLevel;
+ }
+
+ /**
+ * Retrieves NT specific log event type.
+ * @return Integer NTEventType value.
+ */
+ public int getNTEventType() {
+ return mNTEventType;
+ }
+
+ /**
+ * Sets log level, NT log event type.
+ * For certain log levels the NT log event type gets
+ * set as well.
+ * @param level Integer log level value.
+ */
+ public void setLevel(int level) {
+ mLevel = level;
+ switch (level) {
+ case ILogger.LL_DEBUG:
+ case ILogger.LL_INFO:
+ mNTEventType = ILogger.NT_INFO;
+ break;
+
+ case ILogger.LL_WARN:
+ mNTEventType = ILogger.NT_WARN;
+ break;
+
+ case ILogger.LL_FAILURE:
+ case ILogger.LL_MISCONF:
+ case ILogger.LL_CATASTRPHE:
+ case ILogger.LL_SECURITY:
+ mNTEventType = ILogger.NT_ERROR;
+ break;
+
+ default:
+ ConsoleError.send(new SystemEvent(INVALID_LOG_LEVEL,
+ Integer.toString(level)));
+ break;
+ }
+ }
+
+ /**
+ * Retrieves log multiline attribute.
+ * @return Boolean whether or not this event is multiline.
+ * A multiline message simply consists of more than one line.
+ */
+ public boolean getMultiline() {
+ return mMultiline;
+ }
+
+ /**
+ * Sets log multiline attribute. A multiline message consists of
+ * more than one line.
+ * @param multiline Boolean multiline value.
+ */
+ public void setMultiline(boolean multiline) {
+ mMultiline = multiline;
+ }
+
+ /**
+ * Retrieves event time stamp.
+ * @return Long integer of the time the event was created.
+ */
+ public long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+
+ /**
+ * Retrieves log event type. Each type of event
+ * has an associated String type value.
+ * @return String containing the type of event.
+ */
+ public String getEventType() {
+ return mEventType;
+ }
+
+
+ /**
+ * Sets log event type. Each type of event
+ * has an associated String type value.
+ * @param eventType String containing the type of event.
+ */
+ public void setEventType(String eventType) {
+ mEventType = eventType;
+ }
+
+ /**
+ * Return string representation of log message.
+ * @return String containing log message.
+ */
+ public String toString() {
+ if (getBundleName() == null) {
+ MessageFormat detailMessage = new MessageFormat(mMessage);
+
+ return detailMessage.format(mParams);
+ //return getMessage();
+ } else
+ return toContent();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/AuditFormat.java b/pki/base/common/src/com/netscape/certsrv/logging/AuditFormat.java
new file mode 100644
index 000000000..8d870ad90
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/AuditFormat.java
@@ -0,0 +1,112 @@
+// --- 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.certsrv.logging;
+
+
+/**
+ * Define audit log message format. Note that the name of this
+ * class "AuditFormat" is legacy and has nothing to do with the signed
+ * audit log events format
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuditFormat {
+
+ /**
+ * default log level for writing audit log
+ */
+ public static final int LEVEL = ILogger.LL_INFO;
+
+ /**
+ * initiative: the event is from EE
+ */
+ public static final String FROMUSER = "fromUser";
+
+ /**
+ * initiative: the event is from agent
+ */
+ public static final String FROMAGENT = "fromAgent";
+
+ /**
+ * initiative: the event is from router
+ */
+ public static final String FROMROUTER = "fromRouter";
+
+ /**
+ * initiative: the event is from remote authority
+ */
+ public static final String FROMRA = "fromRemoteAuthority";
+
+ /**
+ * authentication module: no Authentication manager
+ */
+ public static final String NOAUTH = "noAuthManager";
+
+ // for ProcessCertReq.java ,kra
+ /**
+ 0: request type
+ 1: request ID
+ 2: initiative
+ 3: auth module
+ 4: status
+ 5: cert dn
+ 6: other info. eg cert serial number, violation policies
+ */
+ public static final String FORMAT =
+ "{0} reqID {1} {2} authenticated by {3} is {4} DN requested: {5} {6}";
+ public static final String NODNFORMAT =
+ "{0} reqID {1} {2} authenticated by {3} is {4}";
+
+ public static final String ENROLLMENTFORMAT =
+ "Enrollment request reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} {5}";
+ public static final String RENEWALFORMAT =
+ "Renewal request reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} old serial number: 0x{5} {6}";
+ public static final String REVOCATIONFORMAT =
+ "Revocation request reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} serial number: 0x{5} revocation reason: {6} {7}";
+
+ // 1: fromAgent AgentID: xxx authenticated by xxx
+ public static final String DOREVOKEFORMAT =
+ "Revocation request reqID {0} {1} is {2}. DN requested: {3} serial number: 0x{4} revocation reason: {5}";
+ // 1: fromAgent AgentID: xxx authenticated by xxx
+ public static final String DOUNREVOKEFORMAT =
+ "Unrevocation request reqID {0} {1} is {2}. DN requested: {3} serial number: 0x{4}";
+
+ // 0:initiative
+ public static final String CRLUPDATEFORMAT =
+ "CRLUpdate request {0} authenticated by {1} is {2}. Id: {3}\ncrl Number: {4} last update time: {5} next update time: {6} number of entries in the CRL: {7}";
+
+ // audit user/group
+ public static final String ADDUSERFORMAT =
+ "Admin UID: {0} added User UID: {1}";
+ public static final String REMOVEUSERFORMAT =
+ "Admin UID: {0} removed User UID: {1} ";
+ public static final String MODIFYUSERFORMAT =
+ "Admin UID: {0} modified User UID: {1}";
+ public static final String ADDUSERCERTFORMAT =
+ "Admin UID: {0} added cert for User UID: {1}. cert DN: {2} serial number: 0x{3}";
+ public static final String REMOVEUSERCERTFORMAT =
+ "Admin UID: {0} removed cert of User UID: {1}. cert DN: {2} serial number: 0x{3}";
+ public static final String ADDUSERGROUPFORMAT =
+ "Admin UID: {0} added User UID: {1} to group: {2}";
+ public static final String REMOVEUSERGROUPFORMAT =
+ "Admin UID: {0} removed User UID: {1} from group: {2}";
+
+ // LDAP publishing
+ public static final String LDAP_PUBLISHED_FORMAT =
+ "{0} successfully published serial number: 0x{1} with DN: {2}";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ConsoleError.java b/pki/base/common/src/com/netscape/certsrv/logging/ConsoleError.java
new file mode 100644
index 000000000..750e35807
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ConsoleError.java
@@ -0,0 +1,42 @@
+// --- 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.certsrv.logging;
+
+
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A static class to log error messages to the Console
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConsoleError {
+ private static final ConsoleLog console = new ConsoleLog();
+
+ /**
+ * Send the given event to the Console.
+ *
+ * @param ev log event to be sent to the console
+ */
+ public static void send(ILogEvent ev) {
+ console.log(ev);
+ console.flush();
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java b/pki/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java
new file mode 100644
index 000000000..c45b5d129
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java
@@ -0,0 +1,121 @@
+// --- 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.certsrv.logging;
+
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A log event listener which sends all log events to the system console/tty
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConsoleLog implements ILogEventListener {
+
+ /**
+ * Log the given event. Usually called from a log manager.
+ *
+ * @param ev log event
+ */
+ public void log(ILogEvent ev) {
+ System.err.println(Thread.currentThread().getName() + ": " + ev);
+ }
+
+ /**
+ * Flush the system output stream.
+ *
+ */
+ public void flush() {
+ System.err.flush();
+ }
+
+ /**
+ * All operations need to be cleaned up for shutdown are done here
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * get the configuration store that is associated with this
+ * log listener
+ * @return the configuration store that is associated with this
+ * log listener
+ */
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Retrieve last "maxLine" number of system log with log lever >"level"
+ * and from source "source". If the parameter is omitted. All entries
+ * are sent back.
+ * @param req a Hashtable containing the required information such as
+ * log entry, log level, log source, and log name
+ * @return the content of the log that match the criteria in req
+ * @exception servletException
+ * @exception IOException
+ * @exception EBaseException
+ */
+ public synchronized NameValuePairs retrieveLogContent(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ /**
+ * Retrieve log file list.
+ * <br> unimplemented
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "ConsoleLog";
+ }
+
+ public String getDescription() {
+ return "ConsoleLog";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ELogException.java b/pki/base/common/src/com/netscape/certsrv/logging/ELogException.java
new file mode 100644
index 000000000..d15033657
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ELogException.java
@@ -0,0 +1,148 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+
+/**
+ * This class implements a Log exception. LogExceptions
+ * should be caught by LogSubsystem managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ */
+public class ELogException extends EBaseException {
+
+ /**
+ * Resource bundle class name.
+ */
+ private static final String LOG_RESOURCES = LogResources.class.getName();
+
+ /**
+ * Constructs a log exception.
+ * <P>
+ *
+ * @param msgFormat Exception details.
+ */
+ public ELogException(String msgFormat) {
+ super(msgFormat);
+ mParams = null;
+ }
+
+ /**
+ * Constructs a log exception with a parameter. For example,
+ * <PRE>
+ * new ELogException("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Exception details in message string format.
+ * @param param Message string parameter.
+ */
+ public ELogException(String msgFormat, String param) {
+ super(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a log exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * throw new ELogException("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Exception details in message string format.
+ * @param param System exception.
+ */
+ public ELogException(String msgFormat, Exception param) {
+ super(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a log exception with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat Exception details in message string format.
+ * @param params List of message format parameters.
+ */
+ public ELogException(String msgFormat, Object params[]) {
+ super(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns a list of parameters.
+ * <P>
+ *
+ * @return list of message format parameters.
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized exception string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale Locale.
+ * @return Details message.
+ */
+ public String toString(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ super.getMessage(), mParams);
+ }
+
+ /**
+ * Retrieves resource bundle name.
+ * Subclasses should override this as necessary
+ * @return String containing name of resource bundle.
+ */
+
+ protected String getBundleName() {
+ return LOG_RESOURCES;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java b/pki/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java
new file mode 100644
index 000000000..49d55f360
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java
@@ -0,0 +1,35 @@
+// --- 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.certsrv.logging;
+
+
+/**
+ * Exception for log not found.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELogNotFound extends ELogException {
+
+ /**
+ * Constructs a exception for a missing required log.
+ * @param errorString Detailed error message.
+ */
+ public ELogNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java
new file mode 100644
index 000000000..1775c8644
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.logging;
+
+
+/**
+ * Exception for log plugin not found.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELogPluginNotFound extends ELogException {
+
+ /**
+ * Constructs a exception for a missing log plugin.
+ * @param errorString Detailed error message.
+ */
+ public ELogPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java b/pki/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java
new file mode 100644
index 000000000..fc9540e55
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.Serializable;
+import java.util.Locale;
+
+
+/**
+ * An interface which all loggable events must implement.
+ * See ILogEvent class.
+ * This class maintains a resource bundle name for given
+ * event type.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IBundleLogEvent extends ILogEvent {
+
+ /**
+ * Sets the name of the resource bundle to be associated
+ * with this event type.
+ * @param bundle name of resource bundle.
+ */
+ public void setBundleName(String bundle);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogEvent.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogEvent.java
new file mode 100644
index 000000000..d0caca71d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogEvent.java
@@ -0,0 +1,106 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.Serializable;
+import java.util.Locale;
+
+
+/**
+ * An interface which all loggable events must implement. CMS comes
+ * with a limited set of ILogEvent types to implement: audit, system, and
+ * signed audit. This is the base class of all the subsequent implemented types.
+ * A log event represents a certain kind of log message designed for a specific purpose.
+ * For instance, an audit type event represents messages having to do with auditable CMS
+ * actions. The resulting message will ultimately appear into a specific log file.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogEvent extends Serializable {
+
+ /**
+ * Retrieves event time stamp.
+ * @return Long integer of the time the event was created.
+ */
+ public long getTimeStamp();
+
+ /**
+ * Retrieves log source.
+ * This is an id of the subsystem responsible
+ * for creating the log event.
+ * @return Integer source id.
+ */
+ public int getSource();
+
+
+ /**
+ * Retrieves log level.
+ * The log level of an event represents its relative importance
+ * or severity within CMS.
+ * @return Integer log level value.
+ */
+ public int getLevel();
+
+ /**
+ * Retrieves NT specific log event type.
+ * @return Integer NTEventType value.
+ */
+ public int getNTEventType();
+
+ /**
+ * Retrieves multiline attribute.
+ * Does this message consiste of more than one line.
+ * @return Boolean of multiline status.
+ */
+ public boolean getMultiline();
+
+
+ /**
+ * Retrieves log event type. Each type of event
+ * has an associated String type value.
+ * @return String containing the type of event.
+ */
+ public String getEventType();
+
+ /**
+ * Sets log event type. Each type of event
+ * has an associated String type value.
+ * @param eventType String containing the type of event.
+ */
+ public void setEventType(String eventType);
+
+
+ /**
+ * Returns localized message string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String toContent();
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale locale
+ * @return Details message.
+ */
+ public String toContent(Locale locale);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java
new file mode 100644
index 000000000..b0fd0ce18
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java
@@ -0,0 +1,55 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * An interface represents a log event factory. This
+ * factory will be responsible for creating and returning ILogEvent objects
+ * on demand.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogEventFactory {
+
+ /**
+ * Creates an event of a particular event type/class.
+ *
+ * @param evtClass The event type.
+ * @param prop The resource bundle.
+ * @param source The subsystem ID who creates the log event.
+ * @param level The severity of the log event.
+ * @param multiline The log message has more than one line or not.
+ * @param msg The detail message of the log.
+ * @param params The parameters in the detail log message.
+ * @return The created ILogEvent object.
+ */
+ public ILogEvent create(int evtClass, Properties prop, int source,
+ int level, boolean multiline, String msg, Object params[]);
+
+ /**
+ * Releases previously created event.
+ *
+ * @param event The log event.
+ */
+ public void release(ILogEvent event);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java
new file mode 100644
index 000000000..e970d4182
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java
@@ -0,0 +1,125 @@
+// --- 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.certsrv.logging;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * An interface reprensents a log event listener.
+ * A ILogEventListener is registered to a specific
+ * ILogQueue to be notified of created ILogEvents.
+ * the log queue will notify all its registered listeners
+ * of the logged event. The listener will then proceed to
+ * process the event accordingly which will result in a log
+ * message existing in some file.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogEventListener extends EventListener {
+
+ /**
+ * The event notification method: Logs event.
+ *
+ * @param event The log event to be processed.
+ */
+ public void log(ILogEvent event) throws ELogException;
+
+ /**
+ * Flushes the log buffers (if any). Will result in the messages
+ * being actually written to their destination.
+ */
+ public void flush();
+
+ /**
+ * Closes the log file and destroys any associated threads.
+ */
+ public void shutdown();
+
+ /**
+ * Get the configuration store for the log event listener.
+ * @return The configuration store of this log event listener.
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Initialize this log listener
+ * @param owner The subsystem.
+ * @param config Configuration store for this log listener.
+ * @exception Any initialization error.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Startup the instance.
+ */
+ public void startup()
+ throws EBaseException;
+
+ /**
+ * Retrieve last "maxLine" number of system logs with log level >"level"
+ * and from source "source". If the parameter is omitted. All entries
+ * are sent back.
+ * @param req a Hashtable containing the required information such as
+ * log entry, log level, log source, and log name.
+ * @return NameValue pair list of log messages.
+ * @exception ServletException For Servelet errros.
+ * @exception IOException For input/output problems.
+ * @exception EBaseException For other problems.
+ */
+ public NameValuePairs retrieveLogContent(Hashtable req) throws ServletException,
+ IOException, EBaseException;
+
+ /**
+ * Retrieve list of log files.
+ *
+ */
+ public NameValuePairs retrieveLogList(Hashtable req) throws ServletException,
+ IOException, EBaseException;
+
+ /**
+ * Returns implementation name.
+ * @return String name of event listener implementation.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the description of this log event listener.
+ * @return String with listener description.
+ */
+ public String getDescription();
+
+ /**
+ * Return list of default config parameters for this log event listener.
+ * @return Vector of default parameters.
+ */
+ public Vector getDefaultParams();
+
+ /**
+ * Return list of instance config parameters for this log event listener.
+ * @return Vector of instance parameters.
+ */
+ public Vector getInstanceParams();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogQueue.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogQueue.java
new file mode 100644
index 000000000..65d4136c7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogQueue.java
@@ -0,0 +1,74 @@
+// --- 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.certsrv.logging;
+
+
+import java.util.*;
+
+
+/**
+ * An interface represents a log queue. A log queue
+ * is a queue of pending log events to be dispatched
+ * to a set of registered ILogEventListeners.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogQueue {
+
+ /**
+ * Dispatch the log event to all registered log event listeners.
+ *
+ * @param evt the log event
+ */
+ public void log(ILogEvent evt);
+
+ /**
+ * Flushes log queue, flushes all registered listeners.
+ * Messages should be written to their destination.
+ */
+ public void flush();
+
+ /**
+ * Registers an event listener.
+ *
+ * @param listener The log event listener to be registered
+ * to this queue.
+ */
+ public void addLogEventListener(ILogEventListener listener);
+
+ /**
+ * Removes an event listener.
+ *
+ * @param listener The log event listener to be removed from this queue.
+ */
+ public void removeLogEventListener(ILogEventListener listener);
+
+ /**
+ * Initializes the log queue.
+ * <P>
+ *
+ */
+ public void init();
+
+ /**
+ * Stops this log queue:shuts down all registered log event listeners.
+ * <P>
+ */
+ public void shutdown();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java
new file mode 100644
index 000000000..82bde43f4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java
@@ -0,0 +1,105 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.MessageFormat;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * An interface that represents a logging component. The logging
+ * component is a framework that handles different types of log types,
+ * each represented by an ILogEventListener, and each implements a log
+ * plugin. CMS comes
+ * with three standard log types: "signedAudit", "system", and
+ * "transaction". Each log plugin can be instantiated into log
+ * instances. Each log instance can be individually configured and is
+ * associated with its own configuration entries in the configuration file.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogSubsystem extends ISubsystem {
+
+ /**
+ * The ID of this component
+ */
+ public static final String ID = "log";
+
+ /**
+ * Retrieve plugin name (implementation name) of the log event
+ * listener. If no plug name found, an empty string is returned
+ * @param log the log event listener
+ * @return the log event listener's plugin name
+ */
+ public String getLogPluginName(ILogEventListener log);
+
+ /**
+ * Retrieve the log event listener by instance name
+ * @param insName the log instance name in String
+ * @return the log instance in ILogEventListener
+ */
+ public ILogEventListener getLogInstance(String insName);
+
+ /**
+ * get the list of log plugins that are available
+ * @return log plugins in a Hashtable. Each entry in the
+ * Hashtable contains the name/value pair of pluginName/LogPlugin
+ * @see LogPlugin
+ */
+ public Hashtable getLogPlugins();
+
+ /**
+ * get the list of log instances that are available
+ * @return log instances in a Hashtable. Each entry in the
+ * Hashtable contains the name/value pair of instName/ILogEventListener
+ * @see LogPlugin
+ */
+ public Hashtable getLogInsts();
+
+ /**
+ * Get the default configuration parameter names associated with a
+ * plugin. It is used by
+ * administration servlet to handle log configuration when a new
+ * log instance is added.
+ * @param implName The implementation name for which the
+ * configuration parameters are to be configured
+ * @return a Vector of default configuration paramter names
+ * associated with this log plugin
+ * @exception ELogException when instantiation of the plugin
+ * implementation fails.
+ */
+ public Vector getLogDefaultParams(String implName) throws
+ ELogException;
+
+ /**
+ * Get the default configuration parameter names associated with a
+ * log instance. It is used by administration servlet to handle
+ * log instance configuration.
+ * @param insName The instance name for which the configuration
+ * parameters are to be configured
+ * @return a Vector of default configuration paramter names
+ * associated with this log instance.
+ */
+ public Vector getLogInstanceParams(String insName)
+ throws ELogException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/ILogger.java b/pki/base/common/src/com/netscape/certsrv/logging/ILogger.java
new file mode 100644
index 000000000..b4a7070a7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/ILogger.java
@@ -0,0 +1,496 @@
+// --- 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.certsrv.logging;
+
+
+import java.util.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * An interface represents a logger for certificate server. This object is used to
+ * issue log messages for the various types of logging event types. A log message results
+ * in a ILogEvent being created. This event is then placed on a ILogQueue to be ultimately
+ * written to the destination log file. This object also maintains a collection of ILogFactory objects
+ * which are used to create the supported types of ILogEvents. CMS comes out of the box with three event
+ * types: "signedAudit", "system", and "audit".
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILogger {
+
+ //List of defined log classes.
+ /**
+ * log class: audit event.
+ */
+ public static final int EV_AUDIT = 0;
+ public static final String PROP_AUDIT = "transaction";
+
+ /**
+ * log class: system event.
+ * System event with log level >= LL_FAILURE will also be logged in error log
+ */
+ public static final int EV_SYSTEM = 1;
+ public static final String PROP_SYSTEM = "system";
+
+ /**
+ * log class: SignedAudit event.
+ */
+ public static final int EV_SIGNED_AUDIT = 2;
+ public static final String PROP_SIGNED_AUDIT = "signedAudit";
+
+ //List of defined log sources.
+
+ /**
+ * log source: used by servlet to retrieve all logs
+ */
+ public static final int S_ALL = 0; //used by servlet only
+
+ /**
+ * log source: identify the log entry is from KRA
+ */
+ public static final int S_KRA = 1;
+
+ /**
+ * log source: identify the log entry is from RA
+ */
+ public static final int S_RA = 2;
+
+ /**
+ * log source: identify the log entry is from CA
+ */
+ public static final int S_CA = 3;
+
+ /**
+ * log source: identify the log entry is from http subsystem
+ */
+ public static final int S_HTTP = 4;
+
+ /**
+ * log source: identify the log entry is from database subsystem
+ */
+ public static final int S_DB = 5;
+
+ /**
+ * log source: identify the log entry is from authentication subsystem
+ */
+ public static final int S_AUTHENTICATION = 6;
+
+ /**
+ * log source: identify the log entry is from admin subsystem
+ */
+ public static final int S_ADMIN = 7;
+
+ /**
+ * log source: identify the log entry is from ldap subsystem
+ */
+ public static final int S_LDAP = 8;
+
+ /**
+ * log source: identify the log entry is from request queue subsystem
+ */
+ public static final int S_REQQUEUE = 9;
+
+ /**
+ * log source: identify the log entry is from acl subsystem
+ */
+ public static final int S_ACLS = 10;
+
+ /**
+ * log source: identify the log entry is from usergrp subsystem
+ */
+ public static final int S_USRGRP = 11;
+ public static final int S_OCSP = 12;
+
+ /**
+ * log source: identify the log entry is from authorization subsystem
+ */
+ public static final int S_AUTHORIZATION = 13;
+
+ /**
+ * log source: identify the log entry is from signed audit
+ */
+ public static final int S_SIGNED_AUDIT = 14;
+
+ /**
+ * log source: identify the log entry is from CrossCertPair subsystem
+ */
+ public static final int S_XCERT = 15;
+
+ /**
+ * log source: identify the log entry is from CrossCertPair subsystem
+ */
+
+ public static final int S_TKS = 16;
+
+ /**
+ * log source: identify the log entry is from other subsystem
+ * eg. policy, security, connector,registration
+ */
+ public static final int S_OTHER = 20;
+
+
+ // List of defined log levels.
+ /**
+ * log level: used by servlet to retrieve all level logs
+ */
+ public static final int LL_ALL = -1; //used by servlet only
+ public static final String LL_ALL_STRING = "All"; //used by servlet only
+
+ /**
+ * log level: indicate this log entry is debug info
+ */
+
+ /**
+ * Debug level is depreciated since CMS6.1. Please use
+ * CMS.debug() to output messages to debugging file.
+ */
+ public static final int LL_DEBUG = 0; // depreciated
+ public static final String LL_DEBUG_STRING = "Debug";
+
+ /**
+ * log level: indicate this log entry is for info note
+ */
+ public static final int LL_INFO = 1;
+ public static final String LL_INFO_STRING = "Information";
+
+ /**
+ * log level: indicate this log entry is warning info
+ */
+ public static final int LL_WARN = 2;
+ public static final String LL_WARN_STRING = "Warning";
+
+ /**
+ * log level: indicate this log entry is fail/error info
+ */
+ public static final int LL_FAILURE = 3;
+ public static final String LL_FAILURE_STRING = "Failure";
+
+ /**
+ * log level: indicate this log entry is about misconfiguration
+ */
+ public static final int LL_MISCONF = 4;
+ public static final String LL_MISCONF_STRING = "Misconfiguration";
+
+ /**
+ * log level: indicate this log entry is catastrphe info
+ */
+ public static final int LL_CATASTRPHE = 5;
+ public static final String LL_CATASTRPHE_STRING = "Catastrophe";
+
+ /**
+ * log level: indicate this log entry is security info
+ */
+ public static final int LL_SECURITY = 6;
+ public static final String LL_SECURITY_STRING = "Security";
+
+ /**
+ * "SubjectID" for system-initiated events logged
+ * in signed audit log messages
+ */
+ public static final String SYSTEM_UID = "$System$";
+
+ /**
+ * A constant string value used to denote a single "unknown" identity
+ * in signed audit log messages
+ */
+ public static final String UNIDENTIFIED = "$Unidentified$";
+
+ /**
+ * A constant string value used to denote a single "non-role" identity
+ * in signed audit log messages
+ */
+ public static final String NONROLEUSER = "$NonRoleUser$";
+
+ /**
+ * "Outcome" for events logged in signed audit log messages
+ */
+ public static final String SUCCESS = "Success";
+ public static final String FAILURE = "Failure";
+
+ /**
+ * A constant string value used to denote a "non-applicable"
+ * data value in signed audit log messages
+ */
+ public final static String SIGNED_AUDIT_NON_APPLICABLE = "N/A";
+
+ /**
+ * A constant string value used to denote an "empty", or "null",
+ * data value in signed audit log messages
+ */
+ public final static String SIGNED_AUDIT_EMPTY_VALUE = "<null>";
+
+ /**
+ * Constant string values associated with the type of certificate
+ * processing stored in the "InfoName" field in certain signed
+ * audit log messages
+ */
+ public final static String SIGNED_AUDIT_ACCEPTANCE = "certificate";
+ public final static String SIGNED_AUDIT_CANCELLATION = "cancelReason";
+ public final static String SIGNED_AUDIT_REJECTION = "rejectReason";
+
+ // List of all NT event type
+ /**
+ * NT event type: correspond to log level LL_DEBUG or LL_INFO
+ */
+ public static final int NT_INFO = 4;
+
+ /**
+ * NT event type: correspond to log level LL_WARNING
+ */
+ public static final int NT_WARN = 2;
+
+ /**
+ * NT event type: correspont to log level LL_FAILURE and above
+ */
+ public static final int NT_ERROR = 1;
+
+ // List of defined log multiline attribute.
+ /**
+ * indicate the log message has more than one line
+ */
+ public static final boolean L_MULTILINE = true;
+
+ /**
+ * indicate the log message has one line
+ */
+ public static final boolean L_SINGLELINE = false;
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param msg The detail message to be logged.
+ */
+ public void log(int evtClass, int source, String msg);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param msg The detail message to be logged.
+ */
+ public void log(int evtClass, Properties props, int source, String msg);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ */
+ public void log(int evtClass, int source, int level, String msg);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameter in the detail message.
+ */
+ public void log(int evtClass, int source, int level, String msg, Object param);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param params The parameters in the detail message.
+ */
+ public void log(int evtClass, int source, int level, String msg, Object params[]);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameters in the detail message.
+ */
+ public void log(int evtClass, Properties props, int source, String msg, Object param);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameter in the detail message.
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg,
+ Object param);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param prop The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param params The parameters in the detail message.
+ */
+ public void log(int evtClass, Properties prop, int source, int level, String msg,
+ Object params[]);
+
+ //multiline log
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param msg The detail message to be logged.
+ * @param multiline true If the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, int source, String msg, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param msg The detail message to be logged.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, Properties props, int source, String msg, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, int source, int level, String msg, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameter in the detail message.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, int source, int level, String msg, Object param, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source TTTTsource of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameter in the detail message.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, Properties props, int source, String msg, Object param, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param param The parameter in the detail message.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg,
+ Object param, boolean multiline);
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param prop The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param params The parameters in the detail message.
+ * @param multiline True if the message has more than one line, otherwise false.
+ */
+ public void log(int evtClass, Properties prop, int source, int level, String msg,
+ Object params[], boolean multiline);
+
+ /*
+ * Generates an ILogEvent
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM or EV_SIGNED_AUDIT.
+ * @param props The resource bundle used for the detailed message.
+ * @param source The source of the log event.
+ * @param level The level of the log event.
+ * @param msg The detail message to be logged.
+ * @param params The parameters in the detail message.
+ * @param multiline True if the message has more than one line, otherwise false.
+ * @return ILogEvent, a log event.
+ */
+ public ILogEvent create(int evtClass, Properties prop, int source, int level,
+ String msg, Object params[], boolean multiline);
+
+ /**
+ * Register a log event factory. Which will create the desired ILogEvents.
+ */
+ public void register(int evtClass, ILogEventFactory f);
+
+ /**
+ * Retrieves the associated log queue. The log queue is where issued log events
+ * are collected for later processing.
+ */
+ public ILogQueue getLogQueue();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/LogPlugin.java b/pki/base/common/src/com/netscape/certsrv/logging/LogPlugin.java
new file mode 100644
index 000000000..30ee30836
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/LogPlugin.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.logging;
+
+
+import java.util.*;
+import java.lang.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * This class represents a registered logger plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class LogPlugin extends Plugin {
+ public LogPlugin (String id, String path) {
+ super(id, path);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/LogResources.java b/pki/base/common/src/com/netscape/certsrv/logging/LogResources.java
new file mode 100644
index 000000000..942b570db
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/LogResources.java
@@ -0,0 +1,59 @@
+// --- 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.certsrv.logging;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This is the fallback resource bundle for all log events.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class LogResources extends ListResourceBundle {
+ public static final String BASE_RESOURCES = BaseResources.class.getName();
+
+ /**
+ * Contructs a log resource bundle and sets it's parent to the base
+ * resource bundle.
+ *
+ * @see com.netscape.certsrv.base.BaseResources
+ */
+ public LogResources() {
+ super();
+ setParent(ResourceBundle.getBundle(BASE_RESOURCES));
+ }
+
+ /**
+ * Returns the content of this resource.
+ * @return Array of objects making up the contents of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /*
+ * Contents.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java b/pki/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java
new file mode 100644
index 000000000..ea97fe3d6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java
@@ -0,0 +1,334 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * The log event object that carries message detail of a log event
+ * that goes into the Signed Audit Event log. This log has the
+ * property of being digitally signed for security considerations.
+ *
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see com.netscape.certsrv.logging.LogResources
+ */
+public class SignedAuditEvent implements IBundleLogEvent {
+
+ protected Object mParams[] = null;
+
+ private String mEventType = null;
+ private String mMessage = null;
+ private int mLevel = -1;
+ private int mNTEventType = -1;
+ private int mSource = -1;
+ private boolean mMultiline = false;
+ private long mTimeStamp = System.currentTimeMillis();
+
+ private static final String INVALID_LOG_LEVEL="log level: {0} is invalid, should be 0-6";
+
+ /**
+ * The bundle name for this event.
+ * ....not anymore...keep for now and clean up later
+ */
+ private String mBundleName = LogResources.class.getName();
+
+ /**
+ * Constructs a SignedAuditEvent message event.
+ * <P>
+ *
+ * @param msgFormat The message string.
+ */
+ public SignedAuditEvent(String msgFormat) {
+ mMessage = msgFormat;
+ mParams = null;
+ }
+
+ /**
+ * Constructs a message with a parameter. For example,
+ * <PRE>
+ * new SignedAuditEvent("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Details in message string format.
+ * @param param Message string parameter.
+ */
+ public SignedAuditEvent(String msgFormat, String param) {
+ this(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a message from an exception. It can be used to carry
+ * a signed audit exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * logHandler.log(new SignedAuditEvent("Encountered Signed Audit Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Exception details in message string format.
+ * @param exception System exception.
+ */
+ public SignedAuditEvent(String msgFormat, Exception exception) {
+ this(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = exception;
+ }
+
+ /**
+ * Constructs a message from a base exception. This will use the msgFormat
+ * from the exception itself.
+ * <PRE>
+ * try {
+ * ...
+ * } catch (Exception e) {
+ * logHandler.log(new SignedAuditEvent(e));
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param e CMS exception.
+ */
+ public SignedAuditEvent(Exception e) {
+ this(e.getMessage());
+ if (e instanceof EBaseException) {
+ mParams = ((EBaseException) e).getParameters();
+ } else {
+ mParams = new Exception[1];
+ mParams[0] = e;
+ }
+ }
+
+ /**
+ * Constructs a message event with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat Message string format.
+ * @param params List of message format parameters.
+ */
+ public SignedAuditEvent(String msgFormat, Object params[]) {
+ this(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns the current message format string.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Returns a list of parameters. These parameters can be
+ * used to assist in formatting the message.
+ * <P>
+ *
+ * @return List of message format parameters.
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized message string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String toContent() {
+ return toContent(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale Locale.
+ * @return Details message.
+ */
+ public String toContent(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ getMessage(),
+ getParameters());
+ }
+
+ /**
+ * Sets the resource bundle name for this class instance. This should
+ * be overridden by subclasses who have their own resource bundles.
+ * @param bundle String with name of resource bundle.
+ */
+ public void setBundleName(String bundle) {
+ mBundleName = bundle;
+ }
+
+ /**
+ * Retrieves bundle name.
+ * @return String with name of resource bundle.
+ */
+ protected String getBundleName() {
+ return mBundleName;
+ }
+
+ /**
+ * Retrieves log source.
+ * This is an id of the subsystem responsible
+ * for creating the log event.
+ * @return Integer source id.
+ */
+ public int getSource() {
+ return mSource;
+ }
+
+ /**
+ * Sets log source.
+ * @param source Integer id of log source.
+ */
+ public void setSource(int source) {
+ mSource = source;
+ }
+
+ /**
+ * Retrieves log level.
+ * The log level of an event represents its relative importance
+ * or severity within CMS.
+ * @return Integer log level value.
+ */
+ public int getLevel() {
+ return mLevel;
+ }
+
+
+ /**
+ * Retrieves NT specific log event type.
+ * @return Integer NTEventType value.
+ */
+ public int getNTEventType() {
+ return mNTEventType;
+ }
+
+ /**
+ * Sets log level, NT log event type.
+ * For certain log levels the NT log event type gets
+ * set as well.
+ * @param level Integer log level value.
+ */
+ public void setLevel(int level) {
+ mLevel = level;
+ switch (level) {
+ case ILogger.LL_DEBUG:
+ case ILogger.LL_INFO:
+ mNTEventType = ILogger.NT_INFO;
+ break;
+
+ case ILogger.LL_WARN:
+ mNTEventType = ILogger.NT_WARN;
+ break;
+
+ case ILogger.LL_FAILURE:
+ case ILogger.LL_MISCONF:
+ case ILogger.LL_CATASTRPHE:
+ case ILogger.LL_SECURITY:
+ mNTEventType = ILogger.NT_ERROR;
+ break;
+
+ default:
+ ConsoleError.send(new SignedAuditEvent(INVALID_LOG_LEVEL,
+ Integer.toString(level)));
+ break;
+ }
+ }
+
+ /**
+ * Retrieves log multiline attribute.
+ * @return Boolean whether or not this event is multiline.
+ * A multiline message simply consists of more than one line.
+ */
+ public boolean getMultiline() {
+ return mMultiline;
+ }
+
+ /**
+ * Sets log multiline attribute. A multiline message consists of
+ * more than one line.
+ * @param multiline Boolean multiline value.
+ */
+ public void setMultiline(boolean multiline) {
+ mMultiline = multiline;
+ }
+
+
+ /**
+ * Retrieves event time stamp.
+ * @return Long integer of the time the event was created.
+ */
+ public long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+
+ /**
+ * Retrieves log event type. Each type of event
+ * has an associated String type value.
+ * @return String containing the type of event.
+ */
+ public String getEventType() {
+ return mEventType;
+ }
+
+
+ /**
+ * Sets log event type. Each type of event
+ * has an associated String type value.
+ * @param eventType String containing the type of event.
+ */
+ public void setEventType(String eventType) {
+ mEventType = eventType;
+ }
+
+ /**
+ * Return string representation of log message.
+ * @return String containing log message.
+ */
+ public String toString() {
+ if (getBundleName() == null) {
+ MessageFormat detailMessage = new MessageFormat(mMessage);
+
+ return detailMessage.format(mParams);
+ } else
+ return toContent();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/logging/SystemEvent.java b/pki/base/common/src/com/netscape/certsrv/logging/SystemEvent.java
new file mode 100644
index 000000000..648d3b18c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/logging/SystemEvent.java
@@ -0,0 +1,330 @@
+// --- 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.certsrv.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * The log event object that carries a log message.
+ * This class represents System events which are CMS events
+ * which need to be logged to a log file.
+ *
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see com.netscape.certsrv.logging.LogResources
+ */
+public class SystemEvent implements IBundleLogEvent {
+
+ protected Object mParams[] = null;
+
+ private String mEventType = null;
+ private String mMessage = null;
+ private int mLevel = -1;
+ private int mNTEventType = -1;
+ private int mSource = -1;
+ private boolean mMultiline = false;
+ private long mTimeStamp = System.currentTimeMillis();
+
+ /**
+ * The bundle name for this event.
+ */
+ private String mBundleName = LogResources.class.getName();
+
+ private static final String INVALID_LOG_LEVEL="log level: {0} is invalid, should be 0-6";
+
+ /**
+ * Constructs a SystemEvent message event.
+ * <P>
+ *
+ * @param msgFormat The message string.
+ */
+ public SystemEvent(String msgFormat) {
+ mMessage = msgFormat;
+ mParams = null;
+ }
+
+ /**
+ * Constructs a SystemEvent message with a parameter. For example,
+ * <PRE>
+ * new SystemEvent("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Details in message string format.
+ * @param param Message string parameter.
+ */
+ public SystemEvent(String msgFormat, String param) {
+ this(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a SystemEvent message from an exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * logHandler.log(new SystemEvent("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat Exception details in message string format.
+ * @param exception System exception.
+ */
+ public SystemEvent(String msgFormat, Exception exception) {
+ this(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = exception;
+ }
+
+ /**
+ * Constructs a SystemEvent message from a base exception. This will use the msgFormat
+ * from the exception itself.
+ * <PRE>
+ * try {
+ * ...
+ * } catch (Exception e) {
+ * logHandler.log(new SystemEvent(e));
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param e CMS exception.
+ */
+ public SystemEvent(Exception e) {
+ this(e.getMessage());
+ if (e instanceof EBaseException) {
+ mParams = ((EBaseException) e).getParameters();
+ } else {
+ mParams = new Exception[1];
+ mParams[0] = e;
+ }
+ }
+
+ /**
+ * Constructs a SystemEvent message event with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat Message string format.
+ * @param params List of message format parameters.
+ */
+ public SystemEvent(String msgFormat, Object params[]) {
+ this(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns the current message format string.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Returns a list of parameters. These parameters can be
+ * used to assist in formatting the message.
+ * <P>
+ *
+ * @return List of message format parameters.
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized message string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return Details message.
+ */
+ public String toContent() {
+ return toContent(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale Locale.
+ * @return Details message.
+ */
+ public String toContent(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ getMessage(),
+ getParameters());
+ }
+
+ /**
+ * Sets the resource bundle name for this class instance. This should
+ * be overridden by subclasses who have their own resource bundles.
+ * @param bundle String with the name of resource bundle.
+ */
+ public void setBundleName(String bundle) {
+ mBundleName = bundle;
+ }
+
+ /**
+ * Retrieves bundle name.
+ * @return String with name of resource bundle.
+ */
+ protected String getBundleName() {
+ return mBundleName;
+ }
+
+ /**
+ * Retrieves log source.
+ * This is an id of the subsystem responsible
+ * for creating the log event.
+ * @return Integer source id.
+ */
+ public int getSource() {
+ return mSource;
+ }
+
+ /**
+ * Sets log source.
+ * Sets the id of the subsystem issuing the event.
+ * @param source Integer source id.
+ */
+ public void setSource(int source) {
+ mSource = source;
+ }
+
+ /**
+ * Retrieves log level.
+ * The log level of an event represents its relative importance
+ * or severity within CMS.
+ * @return Integer log level value.
+ */
+ public int getLevel() {
+ return mLevel;
+ }
+
+ /**
+ * Retrieves NT specific log event type.
+ * @return Integer NTEventType value.
+ */
+ public int getNTEventType() {
+ return mNTEventType;
+ }
+
+ /**
+ * Sets log level, NT log event type.
+ * For certain log levels the NT log event type gets
+ * set as well.
+ * @param level Integer log level value.
+ */
+ public void setLevel(int level) {
+ mLevel = level;
+ switch (level) {
+ case ILogger.LL_DEBUG:
+ case ILogger.LL_INFO:
+ mNTEventType = ILogger.NT_INFO;
+ break;
+
+ case ILogger.LL_WARN:
+ mNTEventType = ILogger.NT_WARN;
+ break;
+
+ case ILogger.LL_FAILURE:
+ case ILogger.LL_MISCONF:
+ case ILogger.LL_CATASTRPHE:
+ case ILogger.LL_SECURITY:
+ mNTEventType = ILogger.NT_ERROR;
+ break;
+
+ default:
+ ConsoleError.send(new SystemEvent(INVALID_LOG_LEVEL,
+ Integer.toString(level)));
+ break;
+ }
+ }
+
+ /**
+ * Retrieves log multiline attribute.
+ * @return Boolean whether or not this event is multiline.
+ * A multiline message simply consists of more than one line.
+ */
+ public boolean getMultiline() {
+ return mMultiline;
+ }
+
+ /**
+ * Sets log multiline attribute. A multiline message consists of
+ * more than one line.
+ * @param multiline Boolean multiline value.
+ */
+ public void setMultiline(boolean multiline) {
+ mMultiline = multiline;
+ }
+
+ /**
+ * Retrieves event time stamp.
+ * @return Long integer of the time the event was created.
+ */
+ public long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+ /**
+ * Retrieves log event type. Each type of event
+ * has an associated String type value.
+ * @return String containing the type of event.
+ */
+ public String getEventType() {
+ return mEventType;
+ }
+
+
+ /**
+ * Sets log event type. Each type of event
+ * has an associated String type value.
+ * @param eventType String containing the type of event.
+ */
+ public void setEventType(String eventType) {
+ mEventType = eventType;
+ }
+
+ /**
+ * Return string representation of log message.
+ * @return String containing log message.
+ */
+ public String toString() {
+ if (getBundleName() == null) {
+ MessageFormat detailMessage = new MessageFormat(mMessage);
+
+ return detailMessage.format(mParams);
+ } else
+ return toContent();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/ENotificationException.java b/pki/base/common/src/com/netscape/certsrv/notification/ENotificationException.java
new file mode 100644
index 000000000..a5347ff43
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/ENotificationException.java
@@ -0,0 +1,77 @@
+// --- 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.certsrv.notification;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a notification exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ENotificationException extends EBaseException {
+
+ /**
+ * Identity resource class name.
+ */
+ private static final String NOTIFICATION_RESOURCES = NotificationResources.class.getName();
+
+ /**
+ * Constructs a notification exception
+ * <P>
+ */
+ public ENotificationException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public ENotificationException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public ENotificationException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * <P>
+ */
+ public ENotificationException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Retrieves bundle name.
+ */
+ protected String getBundleName() {
+ return NOTIFICATION_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java b/pki/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java
new file mode 100644
index 000000000..234c7a46d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java
@@ -0,0 +1,84 @@
+// --- 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.certsrv.notification;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.notification.*;
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * formulates the final email. Escape character '\' is understood.
+ * '$' is used preceeding a token name. A token name should not be a
+ * substring of any other token name
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEmailFormProcessor {
+
+ // list of token names
+ public final static String TOKEN_ID = "InstanceID";
+ public final static String TOKEN_SERIAL_NUM = "SerialNumber";
+ public final static String TOKEN_HEX_SERIAL_NUM = "HexSerialNumber";
+ public final static String TOKEN_REQUEST_ID = "RequestId";
+ public final static String TOKEN_HTTP_HOST = "HttpHost";
+ public final static String TOKEN_HTTP_PORT = "HttpPort";
+ public final static String TOKEN_ISSUER_DN = "IssuerDN";
+ public final static String TOKEN_SUBJECT_DN = "SubjectDN";
+ public final static String TOKEN_REQUESTOR_EMAIL = "RequestorEmail";
+ public final static String TOKEN_CERT_TYPE = "CertType";
+ public final static String TOKEN_REQUEST_TYPE = "RequestType";
+ public final static String TOKEN_STATUS = "Status";
+ public final static String TOKEN_NOT_AFTER = "NotAfter";
+ public final static String TOKEN_NOT_BEFORE = "NotBefore";
+ public final static String TOKEN_SENDER_EMAIL = "SenderEmail";
+ public final static String TOKEN_RECIPIENT_EMAIL = "RecipientEmail";
+ public final static String TOKEN_SUMMARY_ITEM_LIST = "SummaryItemList";
+ public final static String TOKEN_SUMMARY_TOTAL_NUM = "SummaryTotalNum";
+ public final static String TOKEN_SUMMARY_SUCCESS_NUM = "SummaryTotalSuccess";
+ public final static String TOKEN_SUMMARY_FAILURE_NUM = "SummaryTotalFailure";
+ public final static String TOKEN_EXECUTION_TIME = "ExecutionTime";
+
+ public final static String TOKEN_REVOCATION_DATE = "RevocationDate";
+
+ /*
+ * takes the form template, parse and replace all $tokens with the
+ * right values. It handles escape character '\'
+ * @param form The locale specific form template,
+ * @param tok2vals a hashtable containing one to one mapping
+ * from $tokens used by the admins in the form template to the real
+ * values corresponding to the $tokens
+ * @return mail content
+ */
+ public String getEmailContent(String form,
+ Hashtable tok2vals);
+
+ /**
+ * takes a vector of strings and concatenate them
+ */
+ public String formContent(Vector vec);
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java b/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java
new file mode 100644
index 000000000..6b654da40
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.notification;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An email resolver that first checks the request email, if none,
+ * then follows by checking the subjectDN of the certificate
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEmailResolver {
+
+ /**
+ * returns an email address by using the resolver keys. The
+ * return value can possibly be null
+ * @param keys list of keys used for resolving the email address
+ */
+ public String getEmail(IEmailResolverKeys keys)
+ throws EBaseException, ENotificationException;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java b/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java
new file mode 100644
index 000000000..2382412c4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.notification;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+
+/**
+ * An interface represents email resolver (ordered) keys for resolving
+ * emails
+ * e.g. request/cert, cert/request, request, request/cert/subjectalternatename etc.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEmailResolverKeys extends IAttrSet {
+
+ public static final String KEY_REQUEST = "request";
+ public static final String KEY_CERT = "cert";
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java b/pki/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java
new file mode 100644
index 000000000..74c97402b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java
@@ -0,0 +1,57 @@
+// --- 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.certsrv.notification;
+
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.notification.*;
+
+
+/**
+ * Files to be processed and returned to the requested parties. It
+ * is a template with $tokens to be used by the form/template processor.
+ *
+ * @version $Revision$, $Date$
+ */
+
+public interface IEmailTemplate {
+
+ public boolean init();
+
+ /**
+ * @return Template Name in string form
+ */
+ public String getTemplateName();
+
+ /**
+ * @return true if template is an html file, false otherwise
+ */
+ public boolean isHTML();
+
+ /**
+ * @return Content of the template
+ */
+ public String toString();
+
+ public int length();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/IMailNotification.java b/pki/base/common/src/com/netscape/certsrv/notification/IMailNotification.java
new file mode 100644
index 000000000..4301f5327
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/IMailNotification.java
@@ -0,0 +1,85 @@
+// --- 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.certsrv.notification;
+
+
+import java.util.*;
+import java.io.*;
+import java.lang.String;
+import netscape.net.smtp.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.notification.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This class handles mail notification via SMTP.
+ * This class uses <b>smtp.host</b> in the configuration for smtp
+ * host. The port default (25) is used. If no smtp specified, local
+ * host is used
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IMailNotification {
+
+ /**
+ * send one message to one or more addressees
+ */
+ public void sendNotification() throws IOException, ENotificationException;
+
+ /**
+ * sets the "From" field
+ * @param from email address of the sender
+ */
+ public void setFrom(String from);
+
+ /**
+ * sets the "Subject" field
+ * @param subject subject of the email
+ */
+ public void setSubject(String subject);
+
+ /**
+ * sets the "Content-Type" field
+ * @param contentType content type of the email
+ */
+ public void setContentType(String contentType);
+
+ /**
+ * sets the content of the email
+ * @param content the message content
+ */
+ public void setContent(String content);
+
+ /**
+ * sets the recipients' email addresses
+ * @param addresses a list of email addresses of the recipients
+ */
+ public void setTo(Vector addresses);
+
+ /**
+ * sets the recipient's email address
+ * @param to address of the recipient email address
+ */
+ public void setTo(String to);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/notification/NotificationResources.java b/pki/base/common/src/com/netscape/certsrv/notification/NotificationResources.java
new file mode 100644
index 000000000..e9cdbdfa1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/notification/NotificationResources.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.notification;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the
+ * Mail Notification package
+ *
+ * @version $Revision$, $Date$
+ */
+public class NotificationResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java b/pki/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java
new file mode 100644
index 000000000..a9c24fdc1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java
@@ -0,0 +1,181 @@
+// --- 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.certsrv.ocsp;
+
+
+import java.util.*;
+import java.math.*;
+import java.security.cert.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.cmsutil.ocsp.*;
+
+
+/**
+ * This class defines an Online Certificate Status Protocol (OCSP) store which
+ * has been extended to provide information from the internal database.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDefStore extends IOCSPStore
+{
+ /**
+ * This method retrieves the number of CRL updates since startup.
+ * <P>
+ *
+ * @return count the number of OCSP default stores
+ */
+ public int getStateCount();
+
+ /**
+ * This method retrieves the number of OCSP requests since startup.
+ * <P>
+ *
+ * @param id a string associated with an OCSP request
+ * @return count the number of this type of OCSP requests
+ */
+ public long getReqCount(String id);
+
+ /**
+ * This method creates a an OCSP default store repository record.
+ * <P>
+ *
+ * @return IRepositoryRecord an instance of the repository record object
+ */
+ public IRepositoryRecord createRepositoryRecord();
+
+ /**
+ * This method adds a request to the default OCSP store repository.
+ * <P>
+ *
+ * @param name a string representing the name of this request
+ * @param thisUpdate the current request
+ * @param rec an instance of the repository record object
+ * @exception EBaseException occurs when there is an error attempting to
+ * add this request to the repository
+ */
+ public void addRepository(String name, String thisUpdate,
+ IRepositoryRecord rec)
+ throws EBaseException;
+
+ /**
+ * This method specifies whether or not to wait for the Certificate
+ * Revocation List (CRL) to be updated.
+ * <P>
+ *
+ * @return boolean true or false
+ */
+ public boolean waitOnCRLUpdate();
+
+ /**
+ * This method updates the specified CRL.
+ * <P>
+ *
+ * @param crl the CRL to be updated
+ * @exception EBaseException occurs when the CRL cannot be updated
+ */
+ public void updateCRL(X509CRL crl) throws EBaseException;
+
+ /**
+ * This method attempts to read the CRL issuing point.
+ * <P>
+ *
+ * @param name the name of the CRL to be read
+ * @return ICRLIssuingPointRecord the CRL issuing point
+ * @exception EBaseException occurs when the specified CRL cannot be located
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPoint(String name)
+ throws EBaseException;
+
+ /**
+ * This method searches all CRL issuing points.
+ * <P>
+ *
+ * @param maxSize specifies the largest number of hits from the search
+ * @return Enumeration a list of the CRL issuing points
+ * @exception EBaseException occurs when no CRL issuing point exists
+ */
+ public Enumeration searchAllCRLIssuingPointRecord(
+ int maxSize)
+ throws EBaseException;
+
+ /**
+ * This method searches all CRL issuing points constrained by the specified
+ * filtering mechanism.
+ * <P>
+ *
+ * @param filter a string which constrains the search
+ * @param maxSize specifies the largest number of hits from the search
+ * @return Enumeration a list of the CRL issuing points
+ * @exception EBaseException occurs when no CRL issuing point exists
+ */
+ public Enumeration searchCRLIssuingPointRecord(String filter,
+ int maxSize)
+ throws EBaseException;
+
+ /**
+ * This method creates a CRL issuing point record.
+ * <P>
+ *
+ * @param name a string representation of this CRL issuing point record
+ * @param crlNumber the number of this CRL issuing point record
+ * @param crlSize the size of this CRL issuing point record
+ * @param thisUpdate the time for this CRL issuing point record
+ * @param nextUpdate the time for the next CRL issuing point record
+ * @return ICRLIssuingPointRecord this CRL issuing point record
+ */
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(
+ String name, BigInteger crlNumber,
+ Long crlSize, Date thisUpdate, Date nextUpdate);
+
+ /**
+ * This method adds a CRL issuing point
+ * <P>
+ *
+ * @param name a string representation of this CRL issuing point record
+ * @param rec this CRL issuing point record
+ * @exception EBaseException occurs when the specified CRL issuing point
+ * record cannot be added
+ */
+ public void addCRLIssuingPoint(String name, ICRLIssuingPointRecord rec)
+ throws EBaseException;
+
+ /**
+ * This method deletes a CRL issuing point record
+ * <P>
+ *
+ * @param id a string representation of this CRL issuing point record
+ * @exception EBaseException occurs when the specified CRL issuing point
+ * record cannot be deleted
+ */
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException;
+
+ /**
+ * This method checks to see if the OCSP response should return good
+ * when the certificate is not found.
+ * <P>
+ *
+ * @return boolean true or false
+ */
+ public boolean isNotFoundGood();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java
new file mode 100644
index 000000000..84b223a88
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java
@@ -0,0 +1,197 @@
+// --- 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.certsrv.ocsp;
+
+
+import java.util.*;
+import java.security.*;
+import java.util.Vector;
+import java.io.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import netscape.security.x509.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cmsutil.ocsp.*;
+
+
+/**
+ * This class represents the primary interface for the Online Certificate
+ * Status Protocol (OCSP) server.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IOCSPAuthority extends ISubsystem
+{
+ public static final String ID = "ocsp";
+
+ public final static OBJECT_IDENTIFIER OCSP_NONCE = new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.48.1.2");
+
+ public final static String PROP_DEF_STORE_ID = "storeId";
+ public final static String PROP_STORE = "store";
+ public final static String PROP_SIGNING_SUBSTORE = "signing";
+ public static final String PROP_NICKNAME = "certNickname";
+ public final static String PROP_NEW_NICKNAME = "newNickname";
+
+ /**
+ * This method retrieves the OCSP store given its name.
+ * <P>
+ *
+ * @param id the string representation of an OCSP store
+ * @return IOCSPStore an instance of an OCSP store object
+ */
+ public IOCSPStore getOCSPStore(String id);
+
+ /**
+ * This method retrieves the signing unit.
+ * <P>
+ *
+ * @return ISigningUnit an instance of a signing unit object
+ */
+ public ISigningUnit getSigningUnit();
+
+ /**
+ * This method retrieves the responder ID by its name.
+ * <P>
+ *
+ * @return ResponderID an instance of a responder ID
+ */
+ public ResponderID getResponderIDByName();
+
+ /**
+ * This method retrieves the responder ID by its hash.
+ * <P>
+ *
+ * @return ResponderID an instance of a responder ID
+ */
+ public ResponderID getResponderIDByHash();
+
+ /**
+ * This method retrieves the default OCSP store
+ * (i. e. - information from the internal database).
+ * <P>
+ *
+ * @return IDefStore an instance of the default OCSP store
+ */
+ public IDefStore getDefaultStore();
+
+ /**
+ * This method sets the supplied algorithm as the default signing algorithm.
+ * <P>
+ *
+ * @param algorithm a string representing the requested algorithm
+ * @exception EBaseException if the algorithm is unknown or disallowed
+ */
+ public void setDefaultAlgorithm(String algorithm)
+ throws EBaseException;
+
+ /**
+ * This method retrieves the default signing algorithm.
+ * <P>
+ *
+ * @return String the name of the default signing algorithm
+ */
+ public String getDefaultAlgorithm();
+
+ /**
+ * This method retrieves all potential OCSP signing algorithms.
+ * <P>
+ *
+ * @return String[] the names of all potential OCSP signing algorithms
+ */
+ public String[] getOCSPSigningAlgorithms();
+
+ /**
+ * This method logs the specified message at the specified level.
+ * <P>
+ *
+ * @param level the log level
+ * @param msg the log message
+ */
+ public void log(int level, String msg);
+
+ /**
+ * This method logs the specified message at the specified level given
+ * the specified event.
+ * <P>
+ *
+ * @param event the log event
+ * @param level the log message
+ * @param msg the log message
+ */
+ public void log(int event, int level, String msg);
+
+ /**
+ * This method retrieves the X500Name of an OCSP server instance.
+ * <P>
+ *
+ * @return X500Name an instance of the X500 name object
+ */
+ public X500Name getName();
+
+ /**
+ * This method retrieves an OCSP server instance digest name as a string.
+ * <P>
+ *
+ * @param alg the signing algorithm
+ * @return String the digest name of the related OCSP server
+ */
+ public String getDigestName(AlgorithmIdentifier alg);
+
+ /**
+ * This method signs the basic OCSP response data provided as a parameter.
+ * <P>
+ *
+ * @param rd response data
+ * @return BasicOCSPResponse signed response data
+ * @exception EBaseException error associated with an inability to sign
+ * the specified response data
+ */
+ public BasicOCSPResponse sign(ResponseData rd)
+ throws EBaseException;
+
+ /**
+ * This method compares two byte arrays to see if they are equivalent.
+ * <P>
+ *
+ * @param bytes the first byte array
+ * @param ints the second byte array
+ * @return boolean true or false
+ */
+ public boolean arraysEqual(byte[] bytes, byte[] ints);
+
+ public void incTotalTime(long inc);
+ public void incSignTime(long inc);
+ public void incLookupTime(long inc);
+ public void incNumOCSPRequest(long inc);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java
new file mode 100644
index 000000000..9bd9ba027
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java
@@ -0,0 +1,100 @@
+// --- 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.certsrv.ocsp;
+
+
+import java.util.*;
+import java.security.*;
+import java.util.Vector;
+import java.io.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import netscape.security.x509.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cmsutil.ocsp.*;
+
+
+/**
+ * This class represents the servlet that serves the Online Certificate
+ * Status Protocol (OCSP) requests.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface IOCSPService
+{
+ /**
+ * This method validates the information associated with the specified
+ * OCSP request and returns an OCSP response.
+ * <P>
+ *
+ * @param r an OCSP request
+ * @return OCSPResponse the OCSP response associated with the specified
+ * OCSP request
+ * @exception EBaseException an error associated with the inability to
+ * process the supplied OCSP request
+ */
+ public OCSPResponse validate(OCSPRequest r)
+ throws EBaseException;
+
+ /**
+ * Returns the in-memory count of the processed OCSP requests.
+ *
+ * @return number of processed OCSP requests in memory
+ */
+ public long getNumOCSPRequest();
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the processed time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPRequestTotalTime();
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the signing time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalSignTime();
+
+ public long getOCSPTotalLookupTime();
+
+ /**
+ * Returns the total data signed
+ * for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalData();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java
new file mode 100644
index 000000000..8576864e8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java
@@ -0,0 +1,76 @@
+// --- 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.certsrv.ocsp;
+
+
+import java.util.*;
+import java.math.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.cmsutil.ocsp.*;
+
+
+/**
+ * This class represents the generic interface for an Online Certificate
+ * Status Protocol (OCSP) store. Users can plugin different OCSP stores
+ * by extending this class. For example, imagine that if a user wants to
+ * use the corporate LDAP server for revocation checking, then the user
+ * would merely create a new class that extends this class (e. g. -
+ * "public interface ICorporateLDAPStore extends IOCSPStore").
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IOCSPStore extends ISubsystem
+{
+ /**
+ * This method validates the information associated with the specified
+ * OCSP request and returns an OCSP response.
+ * <P>
+ *
+ * @param req an OCSP request
+ * @return OCSPResponse the OCSP response associated with the specified
+ * OCSP request
+ * @exception EBaseException an error associated with the inability to
+ * process the supplied OCSP request
+ */
+ public OCSPResponse validate(OCSPRequest req)
+ throws EBaseException;
+
+ /**
+ * This method retrieves the configuration parameters associated with this
+ * OCSP store.
+ * <P>
+ *
+ * @return NameValuePairs all configuration items
+ */
+ public NameValuePairs getConfigParameters();
+
+ /**
+ * This method stores the configuration parameters specified by the
+ * passed-in Name Value pairs object.
+ * <P>
+ *
+ * @param pairs a name-value pair object
+ * @exception EBaseException an illegal name-value pair
+ */
+ public void setConfigParameters(NameValuePairs pairs)
+ throws EBaseException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java b/pki/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java
new file mode 100644
index 000000000..5c814fd2e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java
@@ -0,0 +1,83 @@
+// --- 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.certsrv.password;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+/**
+ * A class represents a password checker exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EPasswordCheckException extends EBaseException {
+
+ /**
+ * Resource class name.
+ */
+ private static final String PASSWORD_CHECK_RESOURCES = PasswordResources.class.getName();
+
+ /**
+ * Constructs a password checker exception
+ * <P>
+ * @param msgFormat exception details
+ */
+ public EPasswordCheckException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a password checker exception.
+ * <P>
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EPasswordCheckException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a password checker exception.
+ * <P>
+ * @param msgFormat exception details in message string format
+ * @param exception system exception
+ */
+ public EPasswordCheckException(String msgFormat, Exception exception) {
+ super(msgFormat, exception);
+ }
+
+ /**
+ * Constructs a password checker exception.
+ * <P>
+ * @param msgFormat the message format.
+ * @param params list of message format parameters
+ */
+ public EPasswordCheckException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Retrieves bundle name.
+ * @return resource bundle name.
+ */
+ protected String getBundleName() {
+ return PASSWORD_CHECK_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java b/pki/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java
new file mode 100644
index 000000000..ddf4325c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.password;
+
+
+/**
+ * Configuration Wizard Password quality checker interface.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConfigPasswordCheck {
+
+ /**
+ * Check if the password meets the quality requirement
+ * @param pwd the given password
+ * @return true if the password meets the quality requirement; otherwise false
+ */
+ public boolean isGoodConfigPassword(String pwd);
+
+ /**
+ * Returns a reason if the password doesnt meet the quality requirement.
+ * @param pwd the given password
+ * @return a reason if the password quality requirement is not met.
+ */
+ public String getConfigReason(String pwd);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java b/pki/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java
new file mode 100644
index 000000000..bb84a72fa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.password;
+
+
+/**
+ * Password quality checker interface.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPasswordCheck {
+
+ /**
+ * Check if the password meets the quality requirement
+ * @param pwd the given password
+ * @return true if the password meets the quality requirement; otherwise false
+ */
+ public boolean isGoodPassword(String pwd);
+
+ /**
+ * Returns a reason if the password doesnt meet the quality requirement.
+ * @param pwd the given password
+ * @return a reason if the password quality requirement is not met.
+ */
+ public String getReason(String pwd);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java b/pki/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java
new file mode 100644
index 000000000..ef6c5af66
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java
@@ -0,0 +1,58 @@
+// --- 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.certsrv.pattern;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+/**
+ * This class represents a collection of attribute
+ * sets.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AttrSetCollection extends Hashtable {
+
+ /**
+ * Constructs a collection.
+ */
+ public AttrSetCollection() {
+ super();
+ }
+
+ /**
+ * Retrieves a attribute set from this collection.
+ *
+ * @param name name of the attribute set
+ * @return attribute set
+ */
+ public IAttrSet getAttrSet(String name) {
+ return (IAttrSet) get(name);
+ }
+
+ /**
+ * Sets attribute set in this collection.
+ *
+ * @param name set of the attribute set
+ * @param set attribute set
+ */
+ public void putAttrSet(String name, IAttrSet set) {
+ put(name, set);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/pattern/Pattern.java b/pki/base/common/src/com/netscape/certsrv/pattern/Pattern.java
new file mode 100644
index 000000000..fe6426306
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/pattern/Pattern.java
@@ -0,0 +1,164 @@
+// --- 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.certsrv.pattern;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This is a generic pattern subtitution engine. The
+ * pattern format should be:
+ * <p>
+ * $[attribute set key].[attribute name]$
+ * <p>
+ * For example,
+ * <p>
+ * $request.requestor_email$
+ * $ctx.user_id$
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class Pattern {
+
+ private String mS = null;
+
+ /**
+ * Constructs a pattern object with the given string.
+ *
+ * @param s string with pattern (i.e. $request.requestor_email$)
+ */
+ public Pattern(String s) {
+ mS = s;
+ }
+
+ /**
+ * Subtitutes this pattern with the given attribute set.
+ *
+ * @param key key name of the given attribute set
+ * @param attrSet attribute set
+ * @return substituted string
+ */
+ public String substitute(String key, IAttrSet attrSet) {
+ return substitute2(key, attrSet);
+ }
+
+ /**
+ * Subtitutes this pattern with the given attribute set.
+ *
+ * @param attrSetCollection attribute set collection
+ * @return substituted string
+ */
+ public String substitute(AttrSetCollection attrSetCollection) {
+ String temp = mS;
+ Enumeration keys = attrSetCollection.keys();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ Pattern p = new Pattern(temp);
+
+ temp = p.substitute(key,
+ attrSetCollection.getAttrSet(key));
+
+ }
+ return temp;
+ }
+
+ /**
+ * Subtitutes this pattern with the given attribute set.
+ *
+ * This is an extended version of the substitute() method.
+ * It takes a more flexible pattern format that could have
+ * non-token ($...$) format. e.g.
+ * $request.screenname$@redhat.com
+ * where "@redhat.com" is not in token pattern format, and will be
+ * literally put in place. e.g.
+ * TomRiddle@redhat.com
+ *
+ * @param key key name of the given attribute set
+ * @param attrSet attribute set
+ * @return substituted string
+ */
+ public String substitute2(String key, IAttrSet attrSet) {
+ StringBuffer sb = new StringBuffer();
+
+ int startPos = 0;
+ int lastPos;
+
+ do {
+ // from startPos to right before '$' or end of string
+ // need to be copied over
+
+ lastPos = mS.indexOf('$', startPos);
+
+ // if no '$', return the entire string
+ if (lastPos == -1 && startPos == 0)
+ return mS;
+
+ // no more '$' found, copy the rest of chars, done
+ if (lastPos == -1) {
+ sb.append(mS.substring(startPos)); //
+ return sb.toString(); //
+ // continue;
+ }
+
+ // found '$'
+ if (startPos < lastPos) {
+ sb.append(mS.substring(startPos, lastPos));
+ }
+
+ // look for the ending '$'
+ int endPos = mS.indexOf('$', lastPos + 1);
+ String token = mS.substring(lastPos + 1, endPos);
+ int dotPos = token.indexOf('.');
+
+ // it's assuming there's always a '.'
+ String attrKey = token.substring(0, dotPos);
+ String attrName = token.substring(dotPos + 1);
+
+ if (!key.equals(attrKey)) {
+ startPos = endPos + 1;
+ sb.append("$" + attrKey + "." + attrName + "$");
+ continue;
+ }
+
+ try {
+ Object o = attrSet.get(attrName);
+
+ if (!(o instanceof String)) {
+ startPos = endPos + 1;
+ // if no such attrName, copy the token pattern over
+ sb.append("$" + attrKey + "." + attrName + "$");
+ continue;
+ }
+ String val = (String) o;
+
+ sb.append(val);
+ } catch (EBaseException e) {
+ sb.append("$" + attrKey + "." + attrName + "$");
+ }
+ startPos = endPos + 1;
+ }
+ while (lastPos != -1);
+
+ return sb.toString();
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/EPolicyException.java b/pki/base/common/src/com/netscape/certsrv/policy/EPolicyException.java
new file mode 100644
index 000000000..a65e2e5ff
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/EPolicyException.java
@@ -0,0 +1,165 @@
+// --- 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.certsrv.policy;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.reflect.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This class represents Exceptions used by the policy package.
+ * The policies themselves do not raise exceptions but use them
+ * to format error messages.
+ *
+ * Adapted from EBasException
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ */
+public class EPolicyException extends EBaseException {
+
+ /**
+ * Resource class name.
+ */
+ private static final String POLICY_RESOURCES = PolicyResources.class.getName();
+
+ /**
+ * Constructs a base exception.
+ * <P>
+ *
+ * @param msgFormat exception details
+ */
+ public EPolicyException(String msgFormat) {
+ super(msgFormat);
+ mParams = null;
+ }
+
+ /**
+ * Constructs a base exception with a parameter. For example,
+ * <PRE>
+ * new EPolicyException("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ */
+ public EPolicyException(String msgFormat, String param) {
+ super(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a base exception with two String parameters. For example,
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param param1 message string parameter
+ * @param param2 message string parameter
+ */
+ public EPolicyException(String msgFormat, String param1, String param2) {
+ super(msgFormat);
+ mParams = new String[2];
+ mParams[0] = param1;
+ mParams[1] = param2;
+ }
+
+ /**
+ * Constructs a base exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * throw new EPolicyException("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param param system exception
+ */
+ public EPolicyException(String msgFormat, Exception param) {
+ super(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a base exception with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param params list of message format parameters
+ */
+ public EPolicyException(String msgFormat, Object params[]) {
+ super(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns a list of parameters.
+ * <P>
+ *
+ * @return list of message format parameters
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized exception string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return details message
+ */
+ public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale locale
+ * @return details message
+ */
+ public String toString(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ super.getMessage(), mParams);
+ }
+
+ protected String getBundleName() {
+ return POLICY_RESOURCES;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java b/pki/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java
new file mode 100644
index 000000000..bfd0e7c20
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for an enrollment policy rule. This provides general
+ * typing for rules so that a policy processor can group rules
+ * based on a particular type.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IEnrollmentPolicy extends IPolicyRule {
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IExpression.java b/pki/base/common/src/com/netscape/certsrv/policy/IExpression.java
new file mode 100644
index 000000000..e5deb476a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IExpression.java
@@ -0,0 +1,63 @@
+// --- 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.certsrv.policy;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * Interface for a policy expression.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IExpression {
+ public static final int OP_EQUAL = 1;
+ public static final int OP_NEQUAL = 2;
+ public static final int OP_GT = 3;
+ public static final int OP_LT = 4;
+ public static final int OP_GE = 5;
+ public static final int OP_LE = 6;
+ public static final String EQUAL_STR = "==";
+ public static final String NEQUAL_STR = "!=";
+ public static final String GT_STR = ">";
+ public static final String GE_STR = ">=";
+ public static final String LT_STR = "<";
+ public static final String LE_STR = "<=";
+
+ /**
+ * Evaluate the Expression.
+ *
+ * @param req The PKIRequest on which we are applying the condition.
+ * @return The return value.
+ */
+ boolean evaluate(IRequest req)
+ throws EPolicyException;
+
+ /**
+ * Convert to a string.
+ */
+ public String toString();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java
new file mode 100644
index 000000000..0dac71068
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java
@@ -0,0 +1,54 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IGeneralNameAsConstraintsConfig {
+
+ /**
+ * Retrieves instance parameters.
+ *
+ * @param params parameters
+ */
+ public void getInstanceParams(Vector params);
+
+ /**
+ * Retrieves the general name.
+ *
+ * @return general name
+ */
+ public GeneralName getGeneralName();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java
new file mode 100644
index 000000000..5b33fc888
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java
@@ -0,0 +1,67 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IGeneralNameConfig {
+
+ /**
+ * Forms a general name from string.
+ *
+ * @param value general name in string
+ * @return general name object
+ * @exception EBaseException failed to form general name
+ */
+ public GeneralName formGeneralName(String value)
+ throws EBaseException;
+
+ /**
+ * Forms general names from the given value.
+ *
+ * @param value general name in string
+ * @return a vector of general names
+ * @exception EBaseException failed to form general name
+ */
+ public Vector formGeneralNames(Object value)
+ throws EBaseException;
+
+ /**
+ * Retrieves the instance parameters.
+ *
+ * @param params parameters
+ */
+ public void getInstanceParams(Vector params);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java
new file mode 100644
index 000000000..c1526284a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java
@@ -0,0 +1,80 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IGeneralNameUtil {
+
+ public static final String PROP_NUM_GENERALNAMES = "numGeneralNames";
+ public static final String PROP_GENERALNAME = "generalName";
+ public static final String PROP_GENNAME_CHOICE = "generalNameChoice";
+ public static final String PROP_GENNAME_VALUE = "generalNameValue";
+ public static final String GENNAME_CHOICE_RFC822NAME = "rfc822Name";
+ public static final String GENNAME_CHOICE_DIRECTORYNAME = "directoryName";
+ public static final String GENNAME_CHOICE_DNSNAME = "dNSName";
+ public static final String GENNAME_CHOICE_X400ADDRESS = "x400Address";
+ public static final String GENNAME_CHOICE_EDIPARTYNAME = "ediPartyName";
+ public static final String GENNAME_CHOICE_URL = "URL";
+ public static final String GENNAME_CHOICE_IPADDRESS = "iPAddress";
+ public static final String GENNAME_CHOICE_REGISTEREDID = "OID";
+ public static final String GENNAME_CHOICE_OTHERNAME = "otherName";
+
+ /**
+ * Default number of general names.
+ */
+ public static final int DEF_NUM_GENERALNAMES = 8;
+
+ /**
+ * Default extended plugin info.
+ */
+ public static String
+ NUM_GENERALNAMES_INFO = "number;The total number of alternative names or identities permitted in the extension.";
+ public static String GENNAME_CHOICE_INFO =
+ "choice(" +
+ IGeneralNameUtil.GENNAME_CHOICE_RFC822NAME + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_DIRECTORYNAME + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_DNSNAME + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_EDIPARTYNAME + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_URL + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_IPADDRESS + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_REGISTEREDID + "," +
+ IGeneralNameUtil.GENNAME_CHOICE_OTHERNAME + ");" +
+ "GeneralName choice. See RFC 2459 appendix B2 on GeneralName.";
+ public static String GENNAME_VALUE_INFO =
+ "string;Value according to the GeneralName choice.";
+
+ public static String
+ PROP_NUM_GENERALNAMES_INFO = PROP_NUM_GENERALNAMES + ";" + NUM_GENERALNAMES_INFO;
+ public static String
+ PROP_GENNAME_CHOICE_INFO = PROP_GENNAME_CHOICE + ";" + GENNAME_CHOICE_INFO;
+ public static String
+ PROP_GENNAME_VALUE_INFO = PROP_GENNAME_VALUE + ";" + GENNAME_VALUE_INFO;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java
new file mode 100644
index 000000000..dbaa97394
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java
@@ -0,0 +1,54 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IGeneralNamesAsConstraintsConfig {
+
+ /**
+ * Retrieves a list of configured general names.
+ *
+ * @return a list of general names
+ */
+ public GeneralNames getGeneralNames();
+
+ /**
+ * Retrieves instance parameters.
+ *
+ * @param params instance parameters
+ */
+ public void getInstanceParams(Vector params);
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java
new file mode 100644
index 000000000..51584fb96
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IGeneralNamesConfig {
+
+ /**
+ * Retrieves a list of configured general names.
+ *
+ * @return general names
+ */
+ public GeneralNames getGeneralNames();
+
+ /**
+ * Retrieves the instance parameters.
+ *
+ * @param params instance parameters
+ */
+ public void getInstanceParams(Vector params);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java b/pki/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java
new file mode 100644
index 000000000..13ba5f616
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java
@@ -0,0 +1,34 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for a key recovery policy rule.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IKeyArchivalPolicy extends IPolicyRule {
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java b/pki/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java
new file mode 100644
index 000000000..1d173f28f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java
@@ -0,0 +1,34 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for a key recovery policy rule.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IKeyRecoveryPolicy extends IPolicyRule {
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java
new file mode 100644
index 000000000..7b5f44650
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for policy predicate parsers.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IPolicyPredicateParser {
+
+ /**
+ * Parse the predicate expression and return a vector of expressions.
+ *
+ * @param predicateExpression The predicate expression as read from the
+ * config file.
+ * @return expVector The vector of expressions.
+ */
+ IExpression parse(String predicateExpression)
+ throws EPolicyException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java
new file mode 100644
index 000000000..341c006f0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java
@@ -0,0 +1,195 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A generic interface for a policy processor. By making a processor
+ * extend the policy interface, we make even the processor a rule -
+ * which makes sense because a processor may be based on some rule
+ * such as evaluate all policies before returning the final result or
+ * return as soon as one of the policies return a failure and so on.
+ *
+ * By making both processor and policy rules implement a common
+ * interface, one can write rules that are processors as well.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IPolicyProcessor extends ISubsystem,
+ com.netscape.certsrv.request.IPolicy {
+
+ public final static String PROP_DEF_POLICIES = "systemPolicies";
+ public final static String PROP_UNDELETABLE_POLICIES = "undeletablePolicies";
+ public final static String PROP_ENABLE = "enable";
+ public final static String PROP_RULE = "rule";
+ public final static String PROP_CLASS = "class";
+ public final static String PROP_IMPL_NAME = "implName";
+ public final static String PROP_PREDICATE = "predicate";
+ public final static String PROP_IMPL = "impl";
+ public final static String PROP_ORDER = "order";
+
+ public ISubsystem getAuthority();
+
+ /**
+ * Returns the policy substore id.
+ *
+ * @return storeID The policy store id used by this processor.
+ */
+ String getPolicySubstoreId();
+
+ /**
+ * Returns information on Policy impls.
+ *
+ * @return An enumeration of strings describing the information
+ * about policy implementations. Currently only the
+ * the implementation id is expected.
+ */
+ Enumeration getPolicyImplsInfo();
+
+ /**
+ * Returns the rule implementations registered with this processor.
+ *
+ * @return An Enumeration of uninitialized IPolicyRule
+ * objects.
+ */
+ Enumeration getPolicyImpls();
+
+ /**
+ * Returns an implementation identified by a given id.
+ *
+ * @param id The implementation id.
+ * @return The uninitialized instance of the policy rule.
+ */
+ IPolicyRule getPolicyImpl(String id);
+
+ /**
+ * Returns configuration for an implmentation.
+ *
+ * @param id The implementation id.
+ * @return A vector of name/value pairs in the form of
+ * name=value.
+ */
+ Vector getPolicyImplConfig(String id);
+
+ /**
+ * Deletes a policy implementation identified by an impl id.
+ *
+ *
+ * @param id The impl id of the policy to be deleted.
+ * There shouldn't be any active instance for this
+ * implementation.
+ * @exception EBaseException is thrown if an error occurs in deletion.
+ */
+ void deletePolicyImpl(String id)
+ throws EBaseException;
+
+ /**
+ * Adds a policy implementation identified by an impl id.
+ *
+ * @param id The impl id of the policy to be added.
+ * The id should be unique.
+ * @param classPath The fully qualified path for the implementation.
+ * @exception EBaseException is thrown if an error occurs in addition.
+ */
+ void addPolicyImpl(String id, String classPath)
+ throws EBaseException;
+
+ /**
+ * Returns information on Policy instances.
+ *
+ * @return An Enumeration of Strings describing the information
+ * about policy rule instances.
+ */
+ Enumeration getPolicyInstancesInfo();
+
+ /**
+ * Returns policy instances registered with this processor.
+ *
+ * @return An Enumeration of policy instances.
+ */
+ Enumeration getPolicyInstances();
+
+ /**
+ * Returns instance configuration for a given instance id.
+ *
+ * @param id The rule id.
+ * @return A vector of name/value pairs in the form of
+ * name=value.
+ */
+ Vector getPolicyInstanceConfig(String id);
+
+ /**
+ * Returns instance configuration for a given instance id.
+ *
+ * @param id The rule id.
+ * @return the policy instance identified by the id.
+ */
+ IPolicyRule getPolicyInstance(String id);
+
+ /**
+ * Deletes a policy instance identified by an instance id.
+ *
+ * @param id The instance id of the policy to be deleted.
+ * @exception EBaseException is thrown if an error occurs in deletion.
+ */
+ void deletePolicyInstance(String id)
+ throws EBaseException;
+
+ /**
+ * Adds a policy instance
+ *
+ * @param id The impl id of the policy to be added.
+ * The id should be unique.
+ * @param ht a Hashtable of config params.
+ * @exception EBaseException is thrown if an error occurs in addition.
+ */
+ void addPolicyInstance(String id, Hashtable ht)
+ throws EBaseException;
+
+ /**
+ * Modifies a policy instance
+ *
+ * @param id The impl id of the policy to be modified.
+ * The policy instance with this id should be present.
+ * @param ht a Hashtable of config params.
+ * @exception EBaseException is thrown if an error occurs in addition.
+ */
+ void modifyPolicyInstance(String id, Hashtable ht)
+ throws EBaseException;
+
+ /**
+ * Modifies policy ordering.
+ *
+ * @param policyOrderStr The comma separated list of instance ids.
+ *
+ */
+ void changePolicyInstanceOrdering(String policyOrderStr)
+ throws EBaseException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java
new file mode 100644
index 000000000..d7eeb1cfb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java
@@ -0,0 +1,127 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * Interface for a policy rule.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IPolicyRule
+ extends com.netscape.certsrv.request.IPolicy {
+ public static final String PROP_ENABLE = "enable";
+ public static final String PROP_PREDICATE = "predicate";
+ public static final String PROP_IMPLNAME = "implName";
+
+ /**
+ * Initializes the policy rule.
+ * <P>
+ *
+ * @param config The config store reference
+ */
+ void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Gets the description for this policy rule.
+ * <P>
+ * @return The Description for this rule.
+ */
+ String getDescription();
+
+ /**
+ * Returns the name of the policy rule class.
+ * <P>
+ *
+ * @return The name of the policy class.
+ */
+ String getName();
+
+ /**
+ * Returns the name of the policy rule instance.
+ * <P>
+ *
+ * @return The name of the policy rule instance. If none
+ * is set the name of the implementation will be returned.
+ *
+ */
+ String getInstanceName();
+
+ /**
+ * Sets a predicate expression for rule matching.
+ * <P>
+ *
+ * @param exp The predicate expression for the rule.
+ */
+ void setPredicate(IExpression exp);
+
+ /**
+ * Returns the predicate expression for the rule.
+ * <P>
+ *
+ * @return The predicate expression for the rule.
+ */
+ IExpression getPredicate();
+
+ /**
+ * Applies the policy on the given Request. This may modify
+ * the request appropriately.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The PolicyResult object.
+ */
+ PolicyResult apply(IRequest req);
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs. Each name/value
+ * pair is constructed as a String in name=value format.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs. Each name/value
+ * pair is constructed as a String in name=value.
+ */
+ public Vector getDefaultParams();
+
+ public void setError(IRequest req, String format, Object[] params);
+
+ public void setInstanceName(String instanceName);
+
+ public void setPolicyException(IRequest req, EBaseException ex);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IPolicySet.java b/pki/base/common/src/com/netscape/certsrv/policy/IPolicySet.java
new file mode 100644
index 000000000..1132b9831
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IPolicySet.java
@@ -0,0 +1,106 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * Represents a set of policy rules. Policy rules are ordered from
+ * lowest priority to highest priority. The priority assignment for rules
+ * is not enforced by this interface. Various implementation may
+ * use different mechanisms such as a linear ordering of rules
+ * in a configuration file or explicit assignment of priority levels ..etc.
+ * The policy system initialization needs to deal with reading the rules, sorting
+ * them in increasing order of priority and presenting an ordered vector of rules
+ * via the IPolicySet interface.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IPolicySet {
+
+ /**
+ * Returns the name of the rule set.
+ * <P>
+ *
+ * @return The name of the rule set.
+ */
+ String getName();
+
+ /**
+ * Returns the no of rules in a set.
+ * <P>
+ * @return the no of rules.
+ */
+ int count();
+
+ /**
+ * Add a policy rule.
+ * <P>
+ *
+ * @param ruleName The name of the rule to be added.
+ * @param rule The rule to be added.
+ */
+ void addRule(String ruleName, IPolicyRule rule);
+
+ /**
+ * Removes a policy rule identified by the given name.
+ *
+ * @param ruleName The name of the rule to be removed.
+ */
+ void removeRule(String ruleName);
+
+ /**
+ * Returns the rule identified by a given name.
+ * <P>
+ *
+ * @param ruleName The name of the rule to be return.
+ * @return The rule identified by the given name or null if none exists.
+ */
+ IPolicyRule getRule(String ruleName);
+
+ /**
+ * Returns an enumeration of rules.
+ * <P>
+ *
+ * @return An enumeration of rules.
+ */
+ Enumeration getRules();
+
+ /**
+ * Apply policy rules on a request. This call may modify
+ * the request content.
+ *
+ * @param req The request to apply policies on.
+ *
+ * <P>
+ * @return The policy result.
+ */
+ PolicyResult apply(IRequest req);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java b/pki/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java
new file mode 100644
index 000000000..7bf2026e2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java
@@ -0,0 +1,34 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for a renewal policy rule.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IRenewalPolicy extends IPolicyRule {
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java b/pki/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java
new file mode 100644
index 000000000..e0ecfb16f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java
@@ -0,0 +1,34 @@
+// --- 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.certsrv.policy;
+
+
+/**
+ * Interface for a revocation policy rule.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface IRevocationPolicy extends IPolicyRule {
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java b/pki/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java
new file mode 100644
index 000000000..ca7b1f01e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public interface ISubjAltNameConfig extends IGeneralNameConfig {
+
+ /**
+ * Retrieves configuration prefix.
+ *
+ * @return prefix
+ */
+ public String getPfx();
+
+ /**
+ * Retrieves configuration attribute.
+ *
+ * @return attribute
+ */
+ public String getAttr();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/policy/PolicyResources.java b/pki/base/common/src/com/netscape/certsrv/policy/PolicyResources.java
new file mode 100644
index 000000000..f7c80f1f8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/policy/PolicyResources.java
@@ -0,0 +1,46 @@
+// --- 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.certsrv.policy;
+
+
+import java.util.*;
+
+
+/**
+ * Error messages for Policies.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class PolicyResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java b/pki/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java
new file mode 100644
index 000000000..8593da163
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java
@@ -0,0 +1,112 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+
+public class CertInfoProfile
+{
+ private Vector mDefaults = new Vector();
+ private String mName = null;
+ private String mID = null;
+ private String mDescription = null;
+ private String mProfileIDMapping = null;
+ private String mProfileSetIDMapping = null;
+
+ public CertInfoProfile(String cfg) throws Exception
+ {
+ IConfigStore config = CMS.createFileConfigStore(cfg);
+ mID = config.getString("id");
+ mName = config.getString("name");
+ mDescription = config.getString("description");
+ mProfileIDMapping = config.getString("profileIDMapping");
+ mProfileSetIDMapping = config.getString("profileSetIDMapping");
+ StringTokenizer st = new StringTokenizer(config.getString("list"), ",");
+ while (st.hasMoreTokens()) {
+ String id = (String)st.nextToken();
+ String c = config.getString(id + ".default.class");
+ try {
+ /* load defaults */
+ ICertInfoPolicyDefault def = (ICertInfoPolicyDefault)
+ Class.forName(c).newInstance();
+ init(config.getSubStore(id + ".default"), def);
+ mDefaults.addElement(def);
+ } catch (Exception e) {
+ CMS.debug("CertInfoProfile: " + e.toString());
+ }
+ }
+ }
+
+ private void init(IConfigStore config, ICertInfoPolicyDefault def)
+ throws Exception
+ {
+ try {
+ def.init(null, config);
+ } catch (Exception e) {
+ CMS.debug("CertInfoProfile.init: " + e.toString());
+ }
+ }
+
+ public String getID()
+ {
+ return mID;
+ }
+
+ public String getName()
+ {
+ return mName;
+ }
+
+ public String getDescription()
+ {
+ return mDescription;
+ }
+
+ public String getProfileIDMapping()
+ {
+ return mProfileIDMapping;
+ }
+
+ public String getProfileSetIDMapping()
+ {
+ return mProfileSetIDMapping;
+ }
+
+ public void populate(X509CertInfo info)
+ {
+ Enumeration e1 = mDefaults.elements();
+ while (e1.hasMoreElements()) {
+ ICertInfoPolicyDefault def =
+ (ICertInfoPolicyDefault)e1.nextElement();
+ try {
+ def.populate(null /* request */, info);
+ } catch (Exception e) {
+ CMS.debug(e);
+ CMS.debug("CertInfoProfile.populate: " + e.toString());
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/EDeferException.java b/pki/base/common/src/com/netscape/certsrv/profile/EDeferException.java
new file mode 100644
index 000000000..6c48fcb91
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/EDeferException.java
@@ -0,0 +1,47 @@
+// --- 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.certsrv.profile;
+
+import com.netscape.certsrv.base.*;
+
+/**
+ * This represents a profile specific exception. The
+ * framework raises this exception when a request is
+ * deferred.
+ * <p>
+ * A deferred request will not be processed
+ * immediately. Manual approval is required for
+ * processing the request again.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDeferException extends EProfileException {
+
+ /**
+ * Creates a defer exception.
+ *
+ * @param msg localized message that will be
+ * displayed to end user. This message
+ * should indicate the reason why a request
+ * is deferred.
+ */
+ public EDeferException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/EProfileException.java b/pki/base/common/src/com/netscape/certsrv/profile/EProfileException.java
new file mode 100644
index 000000000..197db3bcf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/EProfileException.java
@@ -0,0 +1,43 @@
+// --- 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.certsrv.profile;
+
+import com.netscape.certsrv.base.*;
+
+/**
+ * This represents a generic profile exception.
+ * <p>
+ * This is the base class for all profile-specific
+ * exception.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EProfileException extends EBaseException {
+
+ /**
+ * Creates a profile exception.
+ *
+ * @param msg additional message for the handler
+ * of the exception. The message may
+ * or may not be localized.
+ */
+ public EProfileException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/ERejectException.java b/pki/base/common/src/com/netscape/certsrv/profile/ERejectException.java
new file mode 100644
index 000000000..9a626ef22
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/ERejectException.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.profile;
+
+import com.netscape.certsrv.base.*;
+
+/**
+ * This represents a profile specific exception. This
+ * exception is raised when a request is rejected.
+ * <p>
+ * A rejected request cannot be reprocessed. Rejected
+ * request is considered as a request in its terminal
+ * state.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ERejectException extends EProfileException {
+
+ /**
+ * Creates a rejection exception.
+ *
+ * @param msg localized message that indicates
+ * the reason why a request is
+ * rejected.
+ */
+ public ERejectException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java b/pki/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java
new file mode 100644
index 000000000..c8af3275c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+
+import netscape.security.x509.*;
+
+public interface ICertInfoPolicyDefault extends IPolicyDefault {
+
+ /**
+ * Populates certificate info directly.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java b/pki/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
new file mode 100644
index 000000000..f56f47160
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.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.certsrv.profile;
+
+import com.netscape.certsrv.request.*;
+
+/**
+ * This interface represents an enrollment profile.
+ * <p>
+ * An enrollment profile contains a list of enrollment
+ * specific input plugins, default policies, constriant
+ * policies and output plugins.
+ * <p>
+ * This interface also defines a set of enrollment specific
+ * attribute names that can be used to retrieve values
+ * from an enrollment request.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEnrollProfile extends IProfile {
+
+ /**
+ * Name of request attribute that stores the User
+ * Supplied Certificate Request Type.
+ */
+ public static final String CTX_CERT_REQUEST_TYPE = "cert_request_type";
+
+ /**
+ * Name of request attribute that stores the User
+ * Supplied Certificate Request.
+ */
+ public static final String CTX_CERT_REQUEST = "cert_request";
+
+ /**
+ * Possible values for CTX_CERT_REQUEST_TYPE attribute.
+ */
+ public static final String REQ_TYPE_PKCS10 = "pkcs10";
+ public static final String REQ_TYPE_CRMF = "crmf";
+ public static final String REQ_TYPE_CMC = "cmc";
+ public static final String REQ_TYPE_KEYGEN = "keygen";
+
+ /**
+ * Name of request attribute that stores the End-User Locale.
+ * <p>
+ * The value is of type java.util.Locale.
+ */
+ public static final String REQUEST_LOCALE = "req_locale";
+
+ /**
+ * Name of request attribute that stores the sequence number. Consider
+ * a CRMF request that may contain multiple certificate request.
+ * The first sub certificate certificate request has a sequence
+ * number of 0, the next one has a sequence of 1, and so on.
+ * <p>
+ * The value is of type java.lang.Integer.
+ */
+ public static final String REQUEST_SEQ_NUM = "req_seq_num";
+
+ /**
+ * Name of the request attribute that stores the sequence number for a
+ * renewal request. Only one request at a time is permitted for a renewal.
+ * This value corresponds to the sequence number (and hence the appropriate
+ * certificate) of the original request
+ */
+ public static final String CTX_RENEWAL_SEQ_NUM = "renewal_seq_num";
+
+ /**
+ * Name of request attribute to indicate if this is a renewal
+ */
+ public static final String CTX_RENEWAL = "renewal";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * Key.
+ * <p>
+ * The value is of type netscape.security.x509.CertificateX509Key
+ */
+ public static final String REQUEST_KEY = "req_key";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * Subject Name.
+ * <p>
+ * The value is of type netscape.security.x509.CertificateSubjectName
+ */
+ public static final String REQUEST_SUBJECT_NAME = "req_subject_name";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * Validity.
+ * <p>
+ * The value is of type netscape.security.x509.CertificateValidity
+ */
+ public static final String REQUEST_VALIDITY = "req_validity";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * Signing Algorithm.
+ * <p>
+ * The value is of type netscape.security.x509.CertificateAlgorithmId
+ */
+ public static final String REQUEST_SIGNING_ALGORITHM = "req_signing_alg";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * Extensions.
+ * <p>
+ * The value is of type netscape.security.x509.CertificateExtensions
+ */
+ public static final String REQUEST_EXTENSIONS = "req_extensions";
+
+ /**
+ * Name of request attribute that stores the End-User Supplied
+ * PKI Archive Option extension. This extension is extracted
+ * from a CRMF request that has the user-provided private key.
+ * <p>
+ * The value is of type byte []
+ */
+ public static final String REQUEST_ARCHIVE_OPTIONS = "req_archive_options";
+
+ /**
+ * Name of request attribute that stores the certificate template
+ * that will be signed and then become a certificate.
+ * <p>
+ * The value is of type netscape.security.x509.X509CertInfo
+ */
+ public static final String REQUEST_CERTINFO = "req_x509info";
+
+ /**
+ * Name of request attribute that stores the issued certificate.
+ * <p>
+ * The value is of type netscape.security.x509.X509CertImpl
+ */
+ public static final String REQUEST_ISSUED_CERT = "req_issued_cert";
+
+ /**
+ * Set Default X509CertInfo in the request.
+ * @param request profile-based certificate request.
+ * @exception EProfileException failed to set the X509CertInfo.
+ */
+ public void setDefaultCertInfo(IRequest request) throws EProfileException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java b/pki/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java
new file mode 100644
index 000000000..cb368f9da
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java
@@ -0,0 +1,90 @@
+// --- 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.certsrv.profile;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+
+
+/**
+ * This represents a constraint policy. A constraint policy
+ * validates if the given request conforms to the set
+ * rules.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPolicyConstraint extends IConfigTemplate {
+
+ /**
+ * Initializes this constraint policy.
+ *
+ * @param profile owner of this policy
+ * @param config configuration store for this constraint
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Returns the corresponding configuration store
+ * of this constraint policy.
+ *
+ * @return config store of this constraint
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ *
+ * @param request request to be validated
+ * @exception ERejectException reject the given request
+ */
+ public void validate(IRequest request)
+ throws ERejectException;
+
+ /**
+ * Returns localized description of this constraint.
+ *
+ * @param locale locale of the end-user
+ * @return localized description of this constraint
+ */
+ public String getText(Locale locale);
+
+ /**
+ * Returns localized name of this constraint.
+ *
+ * @param locale locale of the end-user
+ * @return localized name of this constraint
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Checks if this constraint is applicable to the
+ * given default policy.
+ *
+ * @param def default policy to be checked
+ * @return true if this constraint can be applied to
+ * the given default policy
+ */
+ public boolean isApplicable(IPolicyDefault def);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java b/pki/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java
new file mode 100644
index 000000000..0aa8bb234
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java
@@ -0,0 +1,144 @@
+// --- 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.certsrv.profile;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * This represents a default policy that populates
+ * the request with additional values.
+ * <p>
+ *
+ * During request submission process, a default
+ * policy is invoked to populate the default values
+ * in the request. The default values will later
+ * on be used for execution. The default values
+ * are like the parameters for the request.
+ * <p>
+ *
+ * This policy is called in 2 places. For
+ * automated enrollment request, this policy
+ * is invoked to populate the HTTP parameters
+ * into the request. For request that cannot
+ * be executed immediately, this policy will be
+ * invoked again right after the agent's
+ * approval.
+ * <p>
+ *
+ * Each default policy may contain zero or more
+ * properties that describe the default value.
+ * For example, a X509 Key can be described by
+ * its key type, key length, and key data. The
+ * properties help to describe the default value
+ * into human readable values.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPolicyDefault extends IConfigTemplate {
+
+ /**
+ * Initializes this default policy.
+ *
+ * @param profile owner of this default policy
+ * @param config configuration store for this default
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Retrieves the configuration store of this default.
+ *
+ * @return configuration store of this default policy
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * @param request request to be populated
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale locale of the end user
+ * @return localized name of this default policy
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale locale of the end user
+ * @return localized description of this default policy
+ */
+ public String getText(Locale locale);
+
+ /**
+ * Retrieves a list of names of the property.
+ *
+ * @return a list of property names. The values are
+ * of type java.lang.String
+ */
+ public Enumeration getValueNames();
+
+ /**
+ * Retrieves the descriptor of the given property
+ * by name. The descriptor contains syntax
+ * information.
+ *
+ * @param locale locale of the end user
+ * @param name name of property
+ * @return descriptor of the property
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name);
+
+ /**
+ * Sets the value of the given value property by name.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @param value value to be set in the given request
+ * @exception EPropertyException failed to set property
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value) throws EPropertyException;
+
+ /**
+ * Retrieves the value of the given value
+ * property by name.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @exception EPropertyException failed to get property
+ */
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EPropertyException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java
new file mode 100644
index 000000000..262d3eafb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java
@@ -0,0 +1,407 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+
+/**
+ * This interface represents a profile. A profile contains
+ * a list of input policies, default policies, constraint
+ * policies and output policies.
+ * <p>
+ *
+ * The input policy is for building the enrollment page.
+ * <p>
+ *
+ * The default policy is for populating user-supplied and
+ * system-supplied values into the request.
+ * <p>
+ *
+ * The constraint policy is for validating the request before
+ * processing.
+ * <p>
+ *
+ * The output policy is for building the result page.
+ * <p>
+ *
+ * Each profile can have multiple policy set. Each set
+ * is composed of zero or more default policies and zero
+ * or more constraint policies.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfile {
+
+ /**
+ * Initializes this profile.
+ *
+ * @param owner profile subsystem
+ * @param config configuration store for this profile
+ * @exception EBaseException failed to initialize
+ */
+ public void init(IProfileSubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Retrieves the request queue that is associated with
+ * this profile. The request queue is for creating
+ * new requests.
+ *
+ * @return request queue
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Sets id of this profile.
+ *
+ * @param id profile identifier
+ */
+ public void setId(String id);
+
+ /**
+ * Returns the identifier of this profile.
+ *
+ * @return profile id
+ */
+ public String getId();
+
+ /**
+ * Retrieves a localized string that represents
+ * requestor's distinguished name. This string
+ * displayed in the request listing user interface.
+ *
+ * @param request request
+ * @return distringuished name of the request owner
+ */
+ public String getRequestorDN(IRequest request);
+
+ /**
+ * Retrieves the configuration store of this profile.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Retrieves the instance id of the authenticator for this profile.
+ *
+ * @return authenticator instance id
+ */
+ public String getAuthenticatorId();
+
+ public String getAuthzAcl();
+
+ /**
+ * Sets the instance id of the authenticator for this profile.
+ *
+ * @param id authenticator instance id
+ */
+ public void setAuthenticatorId(String id);
+
+ /**
+ * Retrieves the associated authenticator instance.
+ *
+ * @return profile authenticator instance.
+ * if no associated authenticator, null is returned
+ * @exception EProfileException failed to retrieve
+ */
+ public IProfileAuthenticator getAuthenticator()
+ throws EProfileException;
+
+ /**
+ * Retrieves a list of input policy IDs.
+ *
+ * @return input policy id list
+ */
+ public Enumeration getProfileInputIds();
+
+ /**
+ * Retrieves input policy by id.
+ *
+ * @param id input policy id
+ * @return input policy instance
+ */
+ public IProfileInput getProfileInput(String id);
+
+ /**
+ * Retrieves a list of output policy IDs.
+ *
+ * @return output policy id list
+ */
+ public Enumeration getProfileOutputIds();
+
+ /**
+ * Retrieves output policy by id.
+ *
+ * @param id output policy id
+ * @return output policy instance
+ */
+ public IProfileOutput getProfileOutput(String id);
+
+ /**
+ * Checks if this profile is end-user profile or not.
+ * End-user profile will be displayed to the end user.
+ * Non end-user profile mainly is for registration
+ * manager.
+ *
+ * @return end-user profile or not
+ */
+ public boolean isVisible();
+
+ /**
+ * Sets this profile end-user profile or not.
+ *
+ * @param v end-user profile or not
+ */
+ public void setVisible(boolean v);
+
+ /**
+ * Retrieves the user id of the person who
+ * approves this profile.
+ *
+ * @return user id of the approver of this profile
+ */
+ public String getApprovedBy();
+
+ /*
+ * Is this a renewal profile
+ */
+ public String isRenewal();
+
+ /*
+ * is output going to be in xml?
+ */
+ public String isXmlOutput();
+
+ /**
+ * Returns the profile name.
+ *
+ * @param locale end-user locale
+ * @param name profile name
+ */
+ public void setName(Locale locale, String name);
+
+ /**
+ * Retrieves the profile name.
+ *
+ * @param locale end-user locale
+ * @return localized profile name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Returns the profile description.
+ *
+ * @param locale end-user locale
+ * @param desc profile description
+ */
+ public void setDescription(Locale locale, String desc);
+
+ /**
+ * Retrieves the profile description.
+ *
+ * @param locale end-user locale
+ * @return localized profile description
+ */
+ public String getDescription(Locale locale);
+
+ /**
+ * Retrieves profile context. The context stores
+ * information about the requestor before the
+ * actual request is created.
+ *
+ * @return profile context.
+ */
+ public IProfileContext createContext();
+
+ /**
+ * Returns the profile policy set identifiers.
+ *
+ * @return a list of policy set id
+ */
+ public Enumeration getProfilePolicySetIds();
+
+ /**
+ * Creates a profile policy.
+ *
+ * @param setId id of the policy set that owns this policy
+ * @param id policy id
+ * @param defaultClassId id of the registered default implementation
+ * @param constraintClassId id of the registered constraint implementation
+ * @exception EProfileException failed to create policy
+ * @return profile policy instance
+ */
+ public IProfilePolicy createProfilePolicy(String setId, String id,
+ String defaultClassId, String constraintClassId)
+ throws EProfileException;
+
+ /**
+ * Deletes input policy by id.
+ *
+ * @param inputId id of the input policy
+ * @exception EProfileException failed to delete
+ */
+ public void deleteProfileInput(String inputId) throws EProfileException;
+
+ /**
+ * Deletes output policy by id.
+ *
+ * @param outputId id of the output policy
+ * @exception EProfileException failed to delete
+ */
+ public void deleteProfileOutput(String outputId) throws EProfileException;
+
+ /**
+ * Creates a input policy.
+ *
+ * @param id input policy id
+ * @param inputClassId id of the registered input implementation
+ * @param nvp default parameters
+ * @return input policy
+ * @exception EProfileException failed to create
+ */
+ public IProfileInput createProfileInput(String id, String inputClassId,
+ NameValuePairs nvp)
+ throws EProfileException;
+
+ /**
+ * Creates a output policy.
+ *
+ * @param id output policy id
+ * @param outputClassId id of the registered output implementation
+ * @param nvp default parameters
+ * @return output policy
+ * @exception EProfileException failed to create
+ */
+ public IProfileOutput createProfileOutput(String id, String outputClassId,
+ NameValuePairs nvp) throws EProfileException;
+
+ /**
+ * Deletes a policy.
+ *
+ * @param setId id of the policy set
+ * @param policyId id of policy to delete
+ * @exception EProfileException failed to delete
+ */
+ public void deleteProfilePolicy(String setId, String policyId)
+ throws EProfileException;
+
+ /**
+ * Retrieves a policy.
+ *
+ * @param setId set id
+ * @param id policy id
+ * @return profile policy
+ */
+ public IProfilePolicy getProfilePolicy(String setId, String id);
+
+ /**
+ * Retrieves all the policy id within a set.
+ *
+ * @param setId set id
+ * @return a list of policy id
+ */
+ public Enumeration getProfilePolicyIds(String setId);
+
+ /**
+ * Retrieves a default set id for the given request.
+ * It is the profile's responsibility to return
+ * an appropriate set id for the request.
+ *
+ * @param req request
+ * @return policy set id
+ */
+ public String getPolicySetId(IRequest req);
+
+ /**
+ * Returns a list of profile policies.
+ *
+ * @param setId set id
+ * @return a list of policies
+ */
+ public Enumeration getProfilePolicies(String setId);
+
+ /**
+ * Creates one or more requests. Normally, only one request will
+ * be created. In case of CRMF request, multiple requests may be
+ * created for one submission.
+ *
+ * @param ctx profile context
+ * @param locale user locale
+ * @return a list of requests
+ * @exception EProfileException failed to create requests
+ */
+ public IRequest[] createRequests(IProfileContext ctx, Locale locale)
+ throws EProfileException;
+
+ /**
+ * Populates user-supplied input values into the requests.
+ *
+ * @param ctx profile context
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public void populateInput(IProfileContext ctx, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Passes the request to the set of default policies that
+ * populate the profile information against the profile.
+ *
+ * @param request request
+ * @exception EProfileException failed to populate default values
+ */
+ public void populate(IRequest request)
+ throws EProfileException;
+
+ /**
+ * Passes the request to the set of constraint policies
+ * that validate the request against the profile.
+ *
+ * @param request request
+ * @exception ERejectException validation violation
+ */
+ public void validate(IRequest request)
+ throws ERejectException;
+
+ /**
+ * Process a request after validation.
+ *
+ * @param request request to be processed
+ * @exception EProfileException failed to process
+ */
+ public void execute(IRequest request)
+ throws EProfileException;
+
+ /**
+ * Handles end-user request submission.
+ *
+ * @param token authentication token
+ * @param request request to be processed
+ * @exception EDeferException defer request
+ * @exception EProfileException failed to submit
+ */
+ public void submit(IAuthToken token, IRequest request)
+ throws EDeferException, EProfileException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java
new file mode 100644
index 000000000..149cf33c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java
@@ -0,0 +1,118 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * This interface represents an authenticator for profile.
+ * An authenticator is responsibile for authenting
+ * the end-user. If authentication is successful, request
+ * can be processed immediately. Otherwise, the request will
+ * be defered and manual approval is then required.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileAuthenticator extends IAuthManager {
+
+ public static final String AUTHENTICATED_NAME = "authenticatedName";
+
+ /**
+ * Initializes this default policy.
+ *
+ * @param profile owner of this authenticator
+ * @param config configuration store
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Retrieves the configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Populates authentication specific information into the
+ * request for auditing purposes.
+ *
+ * @param token authentication token
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale end user locale
+ * @return localized authenticator name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale end user locale
+ * @return localized authenticator description
+ */
+ public String getText(Locale locale);
+
+ /**
+ * Retrieves a list of names of the property.
+ *
+ * @return a list of property names
+ */
+ public Enumeration getValueNames();
+
+ /**
+ * Checks if the value of the given property should be
+ * serializable into the request. Passsword or other
+ * security-related value may not be desirable for
+ * storage.
+ *
+ * @param name property name
+ * @return true if the property is not security related
+ */
+ public boolean isValueWriteable(String name);
+
+ /**
+ * Retrieves the descriptor of the given value
+ * property by name.
+ *
+ * @param locale user locale
+ * @param name property name
+ * @return descriptor of the requested property
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name);
+
+ /**
+ * Checks if this authenticator requires SSL client authentication.
+ *
+ * @return client authentication required or not
+ */
+ public boolean isSSLClientRequired();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileContext.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileContext.java
new file mode 100644
index 000000000..aa8492210
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileContext.java
@@ -0,0 +1,48 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+
+/**
+ * This interface represents a profile context which
+ * stores system-wide and user-provided information for
+ * assisting request creation.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileContext {
+
+ /**
+ * Sets a value into the context.
+ *
+ * @param name property name
+ * @param value property value
+ */
+ public void set(String name, String value);
+
+ /**
+ * Retrieves a value from the context.
+ *
+ * @param name property name
+ * @return property value
+ */
+ public String get(String name);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileEx.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileEx.java
new file mode 100644
index 000000000..20b9af977
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileEx.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+
+/**
+ * This interface represents the extension version of
+ * profile.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileEx extends IProfile {
+
+ /**
+ * Called after initialization. It populates default
+ * policies, inputs, and outputs.
+ */
+ public void populate() throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileInput.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileInput.java
new file mode 100644
index 000000000..1b6bea720
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileInput.java
@@ -0,0 +1,116 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+
+/**
+ * This interface represents a input policy which
+ * provides information on how to create the
+ * end-user enrollment page.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileInput extends IConfigTemplate {
+
+ /**
+ * Initializes this default policy.
+ *
+ * @param profile owner of this input
+ * @param config configuration store
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Returns configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * @param ctx profile context
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale user locale
+ * @return localized input name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale user locale
+ * @return localized input description
+ */
+ public String getText(Locale locale);
+
+ /**
+ * Retrieves a list of names of the property.
+ *
+ * @return a list of property names
+ */
+ public Enumeration getValueNames();
+
+ /**
+ * Retrieves the descriptor of the given value
+ * property by name.
+ *
+ * @param locale user locale
+ * @param name property name
+ * @return descriptor of the property
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name);
+
+ /**
+ * Retrieves value from the request.
+ *
+ * @param name property name
+ * @param locale user locale
+ * @param request request
+ * @exception EProfileException failed to get value
+ */
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Sets the value of the given property by name.
+ *
+ * @param name property name
+ * @param locale user locale
+ * @param request request
+ * @param value value
+ * @exception EProfileException failed to get value
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value) throws EPropertyException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java
new file mode 100644
index 000000000..ad9484648
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java
@@ -0,0 +1,117 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+
+/**
+ * This interface represents a output policy which
+ * provides information on how to build the result
+ * page for the enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileOutput extends IConfigTemplate {
+
+ /**
+ * Initializes this default policy.
+ *
+ * @param profile owner of this policy
+ * @param config configuration store
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Retrieves configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * @param ctx profile context
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale user locale
+ * @return output policy name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale user locale
+ * @return output policy description
+ */
+ public String getText(Locale locale);
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ *
+ * @return a list of property names
+ */
+ public Enumeration getValueNames();
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ *
+ * @param locale user locale
+ * @param name property name
+ * @return property descriptor
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name);
+
+ /**
+ * Retrieves the value of the given value parameter by name.
+ *
+ * @param name property name
+ * @param locale user locale
+ * @param request request
+ * @return property value
+ * @exception EProfileException failed to retrieve value
+ */
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Sets the value of the given value parameter by name.
+ *
+ * @param name property name
+ * @param locale user locale
+ * @param request request
+ * @param value property value
+ * @exception EProfileException failed to retrieve value
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value) throws EPropertyException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java
new file mode 100644
index 000000000..9577cb08f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java
@@ -0,0 +1,49 @@
+// --- 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.certsrv.profile;
+
+/**
+ * This interface represents a profile policy
+ * which consists a default policy and a
+ * constraint policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfilePolicy {
+
+ /**
+ * Retrieves the policy id
+ *
+ * @return policy id
+ */
+ public String getId();
+
+ /**
+ * Retrieves the default policy.
+ *
+ * @return default policy
+ */
+ public IPolicyDefault getDefault();
+
+ /**
+ * Retrieves the constraint policy.
+ *
+ * @return constraint policy
+ */
+ public IPolicyConstraint getConstraint();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java
new file mode 100644
index 000000000..cf54a4ba4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java
@@ -0,0 +1,136 @@
+// --- 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.certsrv.profile;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * This represents the profile subsystem that manages
+ * a list of profiles.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileSubsystem extends ISubsystem {
+ public static final String ID = "profile";
+
+ /**
+ * Retrieves a profile by id.
+ *
+ * @return profile
+ * @exception EProfileException failed to retrieve
+ */
+ public IProfile getProfile(String id)
+ throws EProfileException;
+
+ /**
+ * Checks if a profile is approved by an agent or not.
+ *
+ * @param id profile id
+ * @return true if profile is approved
+ */
+ public boolean isProfileEnable(String id);
+
+ /**
+ * Retrieves the approver of the given profile.
+ *
+ * @param id profile id
+ * @return user id of the agent who has approved the profile
+ */
+ public String getProfileEnableBy(String id);
+
+ /**
+ * Creates new profile.
+ *
+ * @param id profile id
+ * @param classid implementation id
+ * @param className class Name
+ * @param configFile configuration file
+ * @exception EProfileException failed to create profile
+ */
+ public IProfile createProfile(String id, String classid,
+ String className, String configFile)
+ throws EProfileException;
+
+ /**
+ * Deletes profile.
+ *
+ * @param id profile id
+ * @param configFile configuration file
+ * @exception EProfileException failed to delete profile
+ */
+ public void deleteProfile(String id, String configFile)
+ throws EProfileException;
+
+ /**
+ * Creates a new profile configuration file.
+ *
+ * @param id profile id
+ * @param classId implementation id
+ * @param configPath location to create the configuration file
+ * @exception failed to create profile
+ */
+ public void createProfileConfig(String id, String classId,
+ String configPath) throws EProfileException;
+
+ /**
+ * Enables a profile.
+ *
+ * @param id profile id
+ * @param enableBy agent's user id
+ * @exception EProfileException failed to enable profile
+ */
+ public void enableProfile(String id, String enableBy)
+ throws EProfileException;
+
+ /**
+ * Disables a profile.
+ *
+ * @param id profile id
+ * @exception EProfileException failed to disable
+ */
+ public void disableProfile(String id)
+ throws EProfileException;
+
+ /**
+ * Retrieves the id of the implementation of the given profile.
+ *
+ * @param id profile id
+ * @return implementation id managed by the registry
+ */
+ public String getProfileClassId(String id);
+
+ /**
+ * Retrieves a list of profile ids. The return
+ * list is of type String.
+ *
+ * @return a list of profile ids
+ */
+ public Enumeration getProfileIds();
+
+ /**
+ * Checks if owner id should be enforced during profile approval.
+ *
+ * @return true if approval should be checked
+ */
+ public boolean checkOwner();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java
new file mode 100644
index 000000000..a550b6445
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java
@@ -0,0 +1,75 @@
+// --- 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.certsrv.profile;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+
+/**
+ * This interface represents an updater that will be
+ * called when the request's state changes.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IProfileUpdater extends IConfigTemplate {
+
+ /**
+ * Initializes this default policy.
+ *
+ * @param profile owner of this policy
+ * @param config configuration store
+ * @exception EProfileException failed to initialize
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException;
+
+ /**
+ * Retrieves configuration store.
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore();
+
+ /**
+ * Notifies of state change.
+ *
+ * @param req request
+ * @param status The status to check for.
+ * @exception EProfileException failed to populate
+ */
+ public void update(IRequest req, RequestStatus status)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale user locale
+ * @return output policy name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale user locale
+ * @return output policy description
+ */
+ public String getText(Locale locale);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/property/Descriptor.java b/pki/base/common/src/com/netscape/certsrv/property/Descriptor.java
new file mode 100644
index 000000000..a4b0ecb2d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/property/Descriptor.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.certsrv.property;
+
+import java.util.*;
+
+
+/**
+ * This interface represents a property descriptor. A descriptor
+ * includes information that describe a property.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Descriptor implements IDescriptor {
+
+ protected String mSyntax = null;
+ protected String mConstraint = null;
+ protected String mDescription = null;
+ protected String mDef = null;
+
+ /**
+ * Constructs a descriptor.
+ *
+ * @param syntax syntax
+ * @param constraint constraint
+ * @param defValue default value
+ * @param description description
+ */
+ public Descriptor(String syntax, String constraint, String defValue, String description) {
+ mSyntax = syntax;
+ mConstraint = constraint;
+ mDef = defValue;
+ mDescription = description;
+ }
+
+ /**
+ * Returns the syntax of the property.
+ *
+ * @return syntax
+ */
+ public String getSyntax() {
+ return mSyntax;
+ }
+
+ /**
+ * Returns the default value of the property.
+ *
+ * @return default value
+ */
+ public String getDefaultValue() {
+ return mDef;
+ }
+
+ /**
+ * Constraint for the given syntax. For example,
+ * <p>
+ * - number(1-5): 1-5 is the constraint, and it indicates
+ * that the number must be in the range of 1 to 5.
+ * <p>
+ * - choice(cert,crl): cert,crl is the constraint
+ * for choice
+ * <p>
+ * If null, no constraint shall be enforced.
+ * <p>
+ * @return constraint
+ */
+ public String getConstraint() {
+ return mConstraint;
+ }
+
+ /**
+ * Retrieves the description of the property.
+ * @param locale user locale
+ * @return description
+ */
+ public String getDescription(Locale locale) {
+ return mDescription;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/property/EPropertyException.java b/pki/base/common/src/com/netscape/certsrv/property/EPropertyException.java
new file mode 100644
index 000000000..3be0aa1ea
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/property/EPropertyException.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.property;
+
+
+import com.netscape.certsrv.base.*;
+
+/**
+ * This is the base exception for property handling.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EPropertyException extends EBaseException {
+
+ /**
+ * Constructs property exception
+ *
+ * @param msg exception message
+ */
+ public EPropertyException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java b/pki/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java
new file mode 100644
index 000000000..c37d484b8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java
@@ -0,0 +1,70 @@
+// --- 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.certsrv.property;
+
+
+import java.util.*;
+
+
+/**
+ * This interface provides a standard way to describe
+ * a set of configuration parameters and its associated syntax.
+ * It provides programmatic methods for querying
+ * template description.
+ * <p>
+ * A plugin, for example, can be described as a
+ * property template.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IConfigTemplate {
+
+ /**
+ * Returns a list of configuration parameter names.
+ *
+ * @return parameter names
+ */
+ public Enumeration getConfigNames();
+
+ /**
+ * Returns the descriptors of configuration parameter.
+ *
+ * @param locale user locale
+ * @param name configuration parameter name
+ * @return descriptor
+ */
+ public IDescriptor getConfigDescriptor(Locale locale, String name);
+
+ /**
+ * Sets configuration parameter.
+ *
+ * @param name parameter name
+ * @param value parameter value
+ * @exception EPropertyException failed to set parameter
+ */
+ public void setConfig(String name, String value)
+ throws EPropertyException;
+
+ /**
+ * Retrieves configuration parameter by name.
+ *
+ * @return parameter
+ */
+ public String getConfig(String name);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java b/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java
new file mode 100644
index 000000000..d3db4b494
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java
@@ -0,0 +1,88 @@
+// --- 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.certsrv.property;
+
+
+import java.util.*;
+
+
+/**
+ * This interface represents a property descriptor.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IDescriptor {
+
+ // syntax
+ public static String DATE = "date";
+ public static String PASSWORD = "password";
+ public static String PRETTY_PRINT = "pretty_print";
+ public static String IMAGE_URL = "image_url";
+ public static String INTEGER = "integer";
+ public static String BOOLEAN = "boolean";
+ public static String STRING = "string";
+ public static String STRING_LIST = "string_list";
+ public static String KEYGEN_REQUEST = "keygen_request";
+ public static String KEYGEN_REQUEST_TYPE = "keygen_request_type";
+ public static String DUAL_KEYGEN_REQUEST = "dual_keygen_request";
+ public static String DUAL_KEYGEN_REQUEST_TYPE = "dual_keygen_request_type";
+ public static String CERT_REQUEST = "cert_request";
+ public static String CERT_REQUEST_TYPE = "cert_request_type";
+ public static String CHOICE = "choice"; // choice of strings
+ public static String DN = "dn";
+ public static String IP = "ip";
+ public static String EMAIL = "email";
+
+ // constraint
+ public static String READONLY = "readonly";
+ public static String HIDDEN = "hidden";
+
+ /**
+ * Returns the syntax of the property.
+ *
+ * @return syntax
+ */
+ public String getSyntax();
+
+ /**
+ * Constraint for the given syntax. For example,
+ * - number(1-5): 1-5 is the constraint, and it indicates
+ * that the number must be in the range of 1 to 5.
+ * - choice(cert,crl): cert,crl is the constraint
+ * for choice
+ * If null, no constraint shall be enforced.
+ *
+ * @return constraint
+ */
+ public String getConstraint();
+
+ /**
+ * Retrieves the description of the property.
+ *
+ * @param locale user locale
+ * @return localized description
+ */
+ public String getDescription(Locale locale);
+
+ /**
+ * Retrieves the default value of the property.
+ *
+ * @return default value
+ */
+ public String getDefaultValue();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/property/PropertySet.java b/pki/base/common/src/com/netscape/certsrv/property/PropertySet.java
new file mode 100644
index 000000000..c6d66b43b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/property/PropertySet.java
@@ -0,0 +1,58 @@
+// --- 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.certsrv.property;
+
+import java.util.*;
+
+
+/**
+ * A set of properties.
+ */
+public class PropertySet {
+
+ private Hashtable mProperties = new Hashtable();
+
+ public PropertySet()
+ {
+ }
+
+ public void add(String name, IDescriptor desc)
+ {
+ mProperties.put(name, desc);
+ }
+
+ public Enumeration getNames()
+ {
+ return mProperties.keys();
+ }
+
+ public IDescriptor getDescriptor(String name)
+ {
+ return (IDescriptor)mProperties.get(name);
+ }
+
+ public void remove(String name)
+ {
+ mProperties.remove(name);
+ }
+
+ public int size()
+ {
+ return mProperties.size();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java b/pki/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java
new file mode 100644
index 000000000..be33dc599
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java
@@ -0,0 +1,42 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * This type of exception is thrown in cases where an parsing
+ * error is found while evaluating a PKI component. An example
+ * would be in trying to evaluate a PKI authentication message and
+ * the parsing operation fails due to a missing token.
+ *
+ * @version $Revision$ $Date$
+ */
+public class ECompSyntaxErr extends ELdapException {
+
+ /**
+ * Construct a ECompSyntaxErr
+ * @param errorString The descriptive error condition.
+ */
+
+ public ECompSyntaxErr(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java
new file mode 100644
index 000000000..16ad10b4d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Publish Mapper not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EMapperNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing required mapper
+ * @param errorString Detailed error message.
+ */
+ public EMapperNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java
new file mode 100644
index 000000000..6e0a98121
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Mapper Plugin not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EMapperPluginNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing mapper plugin
+ * @param errorString Detailed error message.
+ */
+ public EMapperPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java
new file mode 100644
index 000000000..f7198edef
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Publisher not found. Required for successful publishing.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EPublisherNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing required publisher.
+ * @param errorString Detailed error message.
+ */
+ public EPublisherNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java
new file mode 100644
index 000000000..325207a32
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Publisher Plugin not found. Plugin implementation is required to actually publish.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EPublisherPluginNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing publisher plugin.
+ * @param errorString Detailed error message.
+ */
+ public EPublisherPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java
new file mode 100644
index 000000000..8294c6772
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java
@@ -0,0 +1,38 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Ldap Publishing Rule not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class ERuleNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing required rule, which links a publisher and mapper.
+ * @param errorString Detailed error message.
+ */
+ public ERuleNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java b/pki/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java
new file mode 100644
index 000000000..ed1592aab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Exception for Publisher Rule plugin not found. Plugin required to implement Ldap Rule.
+ *
+ * @version $Revision$ $Date$
+ */
+public class ERulePluginNotFound extends ELdapException {
+
+ /**
+ * Constructs a exception for a missing rule plugin.
+ * @param errorString Detailed error message.
+ */
+ public ERulePluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java b/pki/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java
new file mode 100644
index 000000000..d7ac48046
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java
@@ -0,0 +1,106 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This interface represents a CRL publisher that is
+ * invoked when CRL publishing is requested by CMS.
+ * Note that CMS, by default, shipped with a LDAP-based
+ * CRL publisher that can be configured via
+ * Certificiate Manager/LDAP Publishing panel. This
+ * interface provides administrator additional capability
+ * of publishing CRL to different destinations.
+ *
+ * The CRL publishing frequency is configured via
+ * Netscape Certificate Server Console's
+ * Certificate Manager/Revocation List panel.
+ * The CRL publishing may occur either everytime a
+ * certificate is revoked or at a pre-defined interval.
+ *
+ * To try out this new CRL publisher mechanism, do
+ * the following:
+ * (1) Write a sample CRL publisher class that implements
+ * ICRLPublisher interface. For example,
+ *
+ * <code>
+ * public class CRLPublisher implements ICRLPublisher
+ * {
+ * public void init(ISubsystem owner, IConfigStore config)
+ * throws EBaseException
+ * {
+ * log(ILogger.LL_DEBUG, "CRLPublisher: Initialized");
+ * }
+ *
+ * public void publish(String issuingPointId, X509CRLImpl crl)
+ * throws EBaseException
+ * {
+ * log(ILogger.LL_DEBUG, "CRLPublisher: " + issuingPointId +
+ * " crl=" + crl);
+ * }
+ *
+ * public void log(int level, String msg)
+ * {
+ * Logger.getLogger().log(ILogger.EV_SYSTEM,
+ * null, ILogger.S_OTHER, level,
+ * msg);
+ * }
+ * }
+ * </code>
+ *
+ * (2) Compile the class and place the class into
+ * <server-root>\bin\cert\classes directory.
+ * (3) Add the following parameter to CMS.cfg
+ * ca.crlPublisher.class=<implementation class>
+ * For example,
+ * ca.crlPublisher.class=myCRLPublisher
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICRLPublisher {
+
+ /**
+ * Initializes this CRL publisher.
+ *
+ * @param owner parent of the publisher. An object of type
+ * CertificateAuthority.
+ * @param config config store for this publisher. If this
+ * publisher requires configuration parameters for
+ * initialization, the parameters should be placed
+ * in CMS.cfg as ca.crlPublisher.<paramType>=<paramValue>
+ * @exception EBaseException failed to initialize this publisher
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Publishes CRL. This method is invoked by CMS based
+ * on the configured CRL publishing frequency.
+ *
+ * @param issuingPointId CRL issuing point identifier
+ * (i.e. MasterCRL)
+ * @param crl CRL that is publishing
+ * @exception EBaseException failed to publish
+ */
+ public void publish(String issuingPointId, X509CRLImpl crl)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java
new file mode 100644
index 000000000..51252c55a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java
@@ -0,0 +1,70 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for mapping a X509 certificate to a LDAP entry.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapCertMapper extends ILdapPlugin {
+
+ /**
+ * Returns implementation name.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the description of this mapper.
+ */
+ public String getDescription();
+
+ /**
+ * Returns the default parameters.
+ */
+ public Vector getDefaultParams();
+
+ /**
+ * Returns the instance parameters.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * maps a certificate to a LDAP entry.
+ * returns dn of the mapped LDAP entry.
+ * @param conn the LDAP connection
+ * @param cert the certificate to map
+ * @param checkForCert whether to check for the presence of the cert
+ * @exception ELdapException Failed to map.
+ * @return LdapCertMapResult indicates whether a mapping was successful
+ * and whether a certificate was found if checkForCert was true.
+ * If checkForCert was not set the hasCert method in LdapCertMapResult
+ * should be ignored.
+ */
+ public LdapCertMapResult map(LDAPConnection conn,
+ X509Certificate cert, boolean checkForCert)
+ throws ELdapException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java
new file mode 100644
index 000000000..5fa549025
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java
@@ -0,0 +1,59 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.ldap.*;
+import java.security.cert.*;
+import netscape.security.x509.X509CRLImpl;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for mapping a CRL to a LDAP entry.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapCrlMapper {
+
+ /**
+ * maps a crl to a LDAP entry.
+ * returns dn of the mapped LDAP entry.
+ * @param conn the LDAP connection
+ * @param crl the CRL to map
+ * @param checkForCrl whether to check for the presence of the CRL
+ * @exception ELdapException Failed to map CRL to entry.
+ * @return LdapCertMapResult indicates whether a mapping was successful
+ * and whether a certificate was found if checkForCert was true.
+ * If checkForCert was not set the hasCert method in LdapCertMapResult
+ * should be ignored.
+ */
+ public LdapCertMapResult
+ map(LDAPConnection conn, X509CRLImpl crl, boolean checkForCrl)
+ throws ELdapException;
+
+ /**
+ * initialize from config store.
+ * @param config the configuration store to initialize from.
+ * @exception ELdapException Initialization failed due to Ldap error.
+ * @exception EBaseException Initialization failed.
+ */
+ public void init(IConfigStore config)
+ throws ELdapException, EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java
new file mode 100644
index 000000000..bc9cda999
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java
@@ -0,0 +1,71 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for a Ldap predicate expression.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ILdapExpression {
+ public static final int OP_EQUAL = 1;
+ public static final int OP_NEQUAL = 2;
+ public static final int OP_GT = 3;
+ public static final int OP_LT = 4;
+ public static final int OP_GE = 5;
+ public static final int OP_LE = 6;
+ public static final String EQUAL_STR = "==";
+ public static final String NEQUAL_STR = "!=";
+ public static final String GT_STR = ">";
+ public static final String GE_STR = ">=";
+ public static final String LT_STR = "<";
+ public static final String LE_STR = "<=";
+
+ /**
+ * Evaluate the Expression.
+ *
+ * @param sc The SessionContext on which we are applying the condition.
+ * @return The return value.
+ * @exception ELdapExeption Failed to evaluate expression.
+ */
+ boolean evaluate(SessionContext sc)
+ throws ELdapException;
+
+ /**
+ * Evaluate the Expression.
+ *
+ * @param req The PKIRequest on which we are applying the condition.
+ * @return The return value.
+ * @exception ELdapExeption Failed to evaluate expression.
+ */
+ boolean evaluate(IRequest req)
+ throws ELdapException;
+
+ /**
+ * Convert to a string.
+ * @return String representation of expression.
+ */
+ public String toString();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java
new file mode 100644
index 000000000..2201c1bad
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java
@@ -0,0 +1,81 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for mapping a X509 certificate to a LDAP entry.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapMapper extends ILdapPlugin {
+
+ /**
+ * Returns implementation name.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the description of this mapper.
+ */
+ public String getDescription();
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams();
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * maps a certificate to a LDAP entry.
+ * returns dn of the mapped LDAP entry.
+ * @param conn the LDAP connection
+ * @param obj the object to map
+ * @return dn indicates whether a mapping was successful
+ * @exception ELdapException Map operation failed.
+ */
+ public String
+ map(LDAPConnection conn, Object obj)
+ throws ELdapException;
+
+ /**
+ * maps a certificate to a LDAP entry.
+ * returns dn of the mapped LDAP entry.
+ * @param conn the LDAP connection
+ * @param r the request to map
+ * @param obj the object to map
+ * @return dn indicates whether a mapping was successful
+ * @exception ELdapException Map operation failed.
+ */
+ public String
+ map(LDAPConnection conn, IRequest r, Object obj)
+ throws ELdapException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java
new file mode 100644
index 000000000..700e0c6de
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java
@@ -0,0 +1,46 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for any Ldap plugin.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapPlugin {
+
+ /**
+ * Initialize from config store.
+ * @param config the configuration store to initialize from.
+ * @exception ELdapException initialization failed due to Ldap error.
+ * @exception EBaseException initialization failed.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException, ELdapException;
+
+ /**
+ * Return config store.
+ */
+ public IConfigStore getConfigStore();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java
new file mode 100644
index 000000000..42e33af5d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java
@@ -0,0 +1,51 @@
+// --- 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.certsrv.publish;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for any ldap plugin. Plugin implementation is defined here.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapPluginImpl extends IPluginImpl {
+
+ /**
+ * initialize from config store.
+ * @param config the configuration store to initialize from.
+ * @exception ELdapException initializtion failed due to Ldap error.
+ * @exception EBaseException initialization failed.
+ */
+ public void init(ISubsystem sys, IConfigStore config)
+ throws EBaseException, ELdapException;
+
+ /**
+ * initialize from config store and Isubsystem.
+ * @param config the configuration store to initialize from.
+ * @exception ELdapException initializtion failed due to Ldap error.
+ * @exception EBaseException initialization failed.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException, ELdapException;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java
new file mode 100644
index 000000000..6f4b52586
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java
@@ -0,0 +1,47 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import java.security.cert.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Handles requests to perform Ldap publishing.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapPublishModule extends IRequestListener {
+
+ /**
+ * initialize ldap publishing module with config store
+ */
+ // public void init(ICertAuthority owner, IConfigStore config)
+ // throws EBaseException, ELdapException;
+
+ /**
+ * Accepts completed requests from an authority and
+ * performs ldap publishing.
+ * @param request The publishing request.
+ */
+ public void accept(IRequest request);
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java
new file mode 100644
index 000000000..8b51a8f79
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java
@@ -0,0 +1,86 @@
+// --- 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.certsrv.publish;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for publishing certificate or crl to database store.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapPublisher extends ILdapPlugin {
+ public static final String PROP_PREDICATE = "predicate";
+ public static final String PROP_ENABLE = "enable";
+ public static final String PROP_IMPLNAME = "implName";
+
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the description of the publisher.
+ */
+ public String getDescription();
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams();
+
+ /**
+ * Publish an object.
+ *
+ * @param conn a Ldap connection
+ * (null for non-LDAP publishing)
+ * @param dn dn of the ldap entry to publish cert
+ * (null for non-LDAP publishing)
+ * @param object object to publish
+ * (java.security.cert.X509Certificate or,
+ * java.security.cert.X509CRL)
+ * @exception ELdapException publish failed.
+ */
+ public void publish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException;
+
+ /**
+ * Unpublish an object.
+ *
+ * @param conn the Ldap connection
+ * (null for non-LDAP publishing)
+ * @param dn dn of the ldap entry to unpublish cert
+ * (null for non-LDAP publishing)
+ * @param object object to unpublish
+ * (java.security.cert.X509Certificate)
+ * @exception ELdapException unpublish failed.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/ILdapRule.java b/pki/base/common/src/com/netscape/certsrv/publish/ILdapRule.java
new file mode 100644
index 000000000..cbefe9ed6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/ILdapRule.java
@@ -0,0 +1,78 @@
+// --- 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.certsrv.publish;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for publishing rule which associates a Publisher with a Mapper.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ILdapRule extends ILdapPlugin {
+ public static final String PROP_PREDICATE = "predicate";
+ public static final String PROP_ENABLE = "enable";
+ public static final String PROP_IMPLNAME = "implName";
+
+ /**
+ * Initialize the plugin.
+ * @exception EBaseException Initialization failed.
+ */
+ public void init(IPublisherProcessor processor, IConfigStore
+ config) throws EBaseException;
+
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName();
+
+ /**
+ * Returns the description of the ldap publisher.
+ */
+ public String getDescription();
+
+ /**
+ * Sets the instance name.
+ */
+ public void setInstanceName(String name);
+
+ /**
+ * Returns the instance name.
+ */
+ public String getInstanceName();
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams();
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams();
+
+ /**
+ * Returns true if the rule is enabled, false if it's disabled.
+ */
+ public boolean enabled();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java b/pki/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java
new file mode 100644
index 000000000..245771e75
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java
@@ -0,0 +1,122 @@
+// --- 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.certsrv.publish;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Represents a set of publishing rules. Publishing rules are ordered from
+ * lowest priority to highest priority. The priority assignment for publishing
+ * rules is not enforced by this interface. Various implementation may
+ * use different mechanisms such as a linear ordering of publishing rules
+ * in a configuration file or explicit assignment of priority levels ..etc.
+ * The publishing rule initialization needs to deal with reading the
+ * publishing rules, sorting them in increasing order of priority and
+ * presenting an ordered vector of publishing rules via the IPublishRuleSet
+ * interface.
+ * When a request comes, the predicates of the publishing rules will be
+ * checked in the order to find the first matched publishing rule as the
+ * mapping rule to (un)publish the object.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPublishRuleSet {
+ void init(ISubsystem sys, IConfigStore conf) throws EBaseException;
+
+ /**
+ * Returns the name of the publishing rule set.
+ * <P>
+ *
+ * @return The name of the publishing rule set.
+ */
+ String getName();
+
+ /**
+ * Returns the no of publishing rules in a set.
+ * <P>
+ * @return the no of publishing rules.
+ */
+ int count();
+
+ /**
+ * Add a publishing rule
+ * <P>
+ *
+ * @param aliasName The name of the publishing rule to be added.
+ * @param rule rule The publishing rule to be added.
+ */
+ void addRule(String aliasName, ILdapRule rule);
+
+ /**
+ * Removes a publishing rule identified by the given name.
+ *
+ * @param ruleName The name of the publishing rule to be removed.
+ */
+ void removeRule(String ruleName);
+
+ /**
+ * Get the publishing rule identified by a given name.
+ * <P>
+ *
+ * @param ruleName The name of the publishing rule to be return.
+ * @return The publishing rule identified by the given name or null if none exists.
+ */
+ ILdapRule getRule(String ruleName);
+
+ /**
+ * Get the publishing rule identified by a corresponding request.
+ * <P>
+ *
+ * @param req The request from which rule will be identified.
+ * @return The publishing rule or null if none exists.
+ */
+ ILdapRule getRule(IRequest req);
+
+ /**
+ * Get an enumeration of publishing rules.
+ * <P>
+ *
+ * @return An enumeration of publishing rules.
+ */
+ Enumeration getRules();
+
+ /**
+ * Apply publishing rules on a request.
+ * The predicates of the publishing rules will be checked in the order
+ * to find the first matched publishing rule.
+ * Use the mapper to find the dn of the LDAP entry and use the publisher
+ * to publish the object in the request.
+ * <P>
+ *
+ * @param conn The Ldap connection
+ * @param req The request to apply policies on.
+ * @exception ELdapException publish failed due to Ldap error.
+ */
+ public void publish(LDAPConnection conn, IRequest req)
+ throws ELdapException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java b/pki/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java
new file mode 100644
index 000000000..445d0aa15
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java
@@ -0,0 +1,341 @@
+// --- 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.certsrv.publish;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import netscape.ldap.*;
+import java.security.cert.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Controls the publishing process from the top level. Maintains
+ * a collection of Publishers , Mappers, and Publish Rules.
+ *
+ * @version $Revision$ $Date$
+ */
+
+public interface IPublisherProcessor extends ISubsystem {
+
+ public final static String PROP_PUBLISH_SUBSTORE = "publish";
+ public final static String PROP_LDAP_PUBLISH_SUBSTORE = "ldappublish";
+ public final static String PROP_QUEUE_PUBLISH_SUBSTORE = "queue";
+
+ public static final String PROP_LOCAL_CA = "cacert";
+ public static final String PROP_LOCAL_CRL = "crl";
+ public static final String PROP_CERTS = "certs";
+ public static final String PROP_XCERT = "xcert";
+
+ public static final String PROP_CLASS = "class";
+ public static final String PROP_IMPL = "impl";
+ public static final String PROP_PLUGIN = "pluginName";
+ public static final String PROP_INSTANCE = "instance";
+
+ public static final String PROP_PREDICATE = "predicate";
+ public static final String PROP_ENABLE = "enable";
+ public static final String PROP_LDAP = "ldap";
+ public static final String PROP_MAPPER = "mapper";
+ public static final String PROP_PUBLISHER = "publisher";
+ public static final String PROP_TYPE = "type";
+
+ /**
+ *
+ * Returns Hashtable of rule plugins.
+ */
+
+ public Hashtable getRulePlugins();
+
+ /**
+ *
+ * Returns Hashtable of rule instances.
+ */
+
+ public Hashtable getRuleInsts();
+
+ /**
+ *
+ * Returns Hashtable of mapper plugins.
+ */
+
+ public Hashtable getMapperPlugins();
+
+ /**
+ *
+ * Returns Hashtable of publisher plugins.
+ */
+ public Hashtable getPublisherPlugins();
+
+ /**
+ *
+ * Returns Hashtable of rule mapper instances.
+ */
+ public Hashtable getMapperInsts();
+
+ /**
+ *
+ * Returns Hashtable of rule publisher instances.
+ */
+ public Hashtable getPublisherInsts();
+
+ /**
+ *
+ * Returns list of rules based on publishing type.
+ * @param publishingType Type for which to retrieve rule list.
+ */
+
+ public Enumeration getRules(String publishingType);
+
+ /**
+ *
+ * Returns list of rules based on publishing type and publishing request.
+ * @param publishingType Type for which to retrieve rule list.
+ * @param req Corresponding publish request.
+ */
+ public Enumeration getRules(String publishingType, IRequest req);
+
+ /**
+ *
+ * Returns mapper initial default parameters.
+ * @param implName name of MapperPlugin.
+ */
+
+ public Vector getMapperDefaultParams(String implName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns mapper current instance parameters.
+ * @param insName name of MapperProxy.
+ * @exception ELdapException failed due to Ldap error.
+ */
+
+ public Vector getMapperInstanceParams(String insName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns publisher initial default parameters.
+ * @param implName name of PublisherPlugin.
+ * @exception ELdapException failed due to Ldap error.
+ */
+ public Vector getPublisherDefaultParams(String implName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns true if MapperInstance is enabled.
+ * @param insName name of MapperProxy.
+ * @return true if enabled. false if disabled.
+ */
+
+ public boolean isMapperInstanceEnable(String insName);
+
+ /**
+ *
+ * Returns ILdapMapper instance that is currently active.
+ * @param insName name of MapperProxy.
+ * @return instance of ILdapMapper.
+ */
+ public ILdapMapper getActiveMapperInstance(String insName);
+
+ /**
+ *
+ * Returns ILdapMapper instance based on name of MapperProxy.
+ * @param insName name of MapperProxy.
+ * @return instance of ILdapMapper.
+ */
+ public ILdapMapper getMapperInstance(String insName);
+
+ /**
+ *
+ * Returns true publisher instance is currently enabled.
+ * @param insName name of PublisherProxy.
+ * @return true if enabled.
+ */
+ public boolean isPublisherInstanceEnable(String insName);
+
+ /**
+ *
+ * Returns ILdapPublisher instance that is currently active.
+ * @param insName name of PublisherProxy.
+ * @return instance of ILdapPublisher.
+ */
+ public ILdapPublisher getActivePublisherInstance(String insName);
+
+ /**
+ *
+ * Returns ILdapPublisher instance.
+ * @param insName name of PublisherProxy.
+ * @return instance of ILdapPublisher.
+ */
+ public ILdapPublisher getPublisherInstance(String insName);
+
+ /**
+ *
+ * Returns Vector of PublisherIntance's current instance parameters.
+ * @param insName name of PublisherProxy.
+ * @return Vector of current instance parameters.
+ */
+ public Vector getPublisherInstanceParams(String insName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns Vector of RulePlugin's initial default parameters.
+ * @param implName name of RulePlugin.
+ * @return Vector of initial default parameters.
+ * @exception ELdapException failed due to Ldap error.
+ */
+ public Vector getRuleDefaultParams(String implName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns Vector of RulePlugin's current instance parameters.
+ * @param implName name of RulePlugin.
+ * @return Vector of current instance parameters.
+ * @exception ELdapException failed due to Ldap error.
+ */
+ public Vector getRuleInstanceParams(String implName) throws
+ ELdapException;
+
+ /**
+ * Set published flag - true when published, false when unpublished.
+ * Not exist means not published.
+ * @param serialNo serial number of publishable object.
+ * @param published true for published, false for not.
+ */
+ public void setPublishedFlag(BigInteger serialNo, boolean published);
+
+ /**
+ * Publish ca cert, UpdateDir.java, jobs, request listeners
+ * @param cert X509 certificate to be published.
+ * @exception ELdapException publish failed due to Ldap error.
+ */
+ public void publishCACert(X509Certificate cert)
+ throws ELdapException;
+
+ /**
+ * This function is never called. CMS does not unpublish
+ * CA certificate.
+ */
+ public void unpublishCACert(X509Certificate cert)
+ throws ELdapException;
+
+ /**
+ * Publishs regular user certificate based on the criteria
+ * set in the request.
+ * @param cert X509 certificate to be published.
+ * @param req request which provides the criteria
+ * @exception ELdapException publish failed due to Ldap error.
+ */
+ public void publishCert(X509Certificate cert, IRequest req)
+ throws ELdapException;
+
+ /**
+ * Unpublish user certificate. This is used by
+ * UnpublishExpiredJob.
+ * @param cert X509 certificate to be unpublished.
+ * @param req request which provides the criteria
+ * @exception ELdapException unpublish failed due to Ldap error.
+ */
+ public void unpublishCert(X509Certificate cert, IRequest req)
+ throws ELdapException;
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ * Note that this is used by cmsgateway/cert/UpdateDir.java
+ * @param crl Certificate Revocation List
+ * @param crlIssuingPointId name of the issuing point.
+ * @exception ELdapException publish failed due to Ldap error.
+ */
+ public void publishCRL(X509CRLImpl crl,String crlIssuingPointId)
+ throws ELdapException;
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ * @param dn Distinguished name to publish.
+ * @param crl Certificate Revocation List
+ * @exception ELdapException publish failed due to Ldap error.
+ */
+ public void publishCRL(String dn, X509CRL crl)
+ throws ELdapException;
+
+ /**
+ *
+ * Return true if Ldap is enabled.
+ * @return true if Ldap is enabled,otherwise false.
+ */
+
+ public boolean ldapEnabled();
+
+ /**
+ *
+ * Return true of PublisherProcessor is enabled.
+ * @return true if is enabled, otherwise false.
+ *
+ */
+ public boolean enabled();
+
+ /**
+ *
+ * Return Authority for which this Processor operates.
+ * @return Authority.
+ */
+
+ public ISubsystem getAuthority();
+
+ /**
+ *
+ * Perform logging function for this Processor.
+ * @param level Log level to be used for this message
+ * @param msg Message to be logged.
+ */
+
+ public void log(int level, String msg);
+
+ /**
+ *
+ * Returns LdapConnModule belonging to this Processor.
+ * @return LdapConnModule.
+ */
+ public ILdapConnModule getLdapConnModule();
+
+ /**
+ * Sets the LdapConnModule belonging to this Processor.
+ * @param m ILdapConnModule.
+ */
+ public void setLdapConnModule(ILdapConnModule m);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java b/pki/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java
new file mode 100644
index 000000000..f9a47a1c5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Interface for a publisher that has the capability of publishing
+ * cross certs
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IXcertPublisherProcessor extends IPublisherProcessor {
+
+ /**
+ * Publish crossCertificatePair.
+ * @param pair Byte array representing cert pair.
+ * @exception EldapException publish failed due to Ldap error.
+ */
+ public void publishXCertPair(byte[] pair)
+ throws ELdapException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java b/pki/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java
new file mode 100644
index 000000000..4444fc947
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java
@@ -0,0 +1,58 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Class that represents the result of a Ldap Mapping operation.
+ * certificate map result:
+ * Represented by a mapped entry as a DN and whether entry has the certificate.
+ *
+ * @version $Revision$ $Date$
+ */
+public class LdapCertMapResult {
+ private String mDn;
+ private boolean mHasCert;
+
+ /**
+ * Constructs ldap cert map result with a dn and hasCert boolean.
+ */
+ public LdapCertMapResult(String dn, boolean hasCert) {
+ mDn = dn;
+ mHasCert = hasCert;
+ }
+
+ /**
+ * Gets DN from the result.
+ * @return Distinguished Name.
+ */
+ public String getDn() {
+ return mDn;
+ }
+
+ /**
+ * Gets whether the ldap entry had a certificate from result.
+ * @return true if cert is present, false otherwise.
+ */
+ public boolean hasCert() {
+ return mHasCert;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java b/pki/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java
new file mode 100644
index 000000000..56a8f92dd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.publish;
+
+
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * This class represents a registered mapper plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class MapperPlugin extends Plugin {
+
+ /**
+ * Constructs a MapperPlugin based on a name and a path.
+ * @param id Name of plugin.
+ * @param path Classpath of plugin.
+ */
+ public MapperPlugin (String id, String path) {
+ super(id, path);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/MapperProxy.java b/pki/base/common/src/com/netscape/certsrv/publish/MapperProxy.java
new file mode 100644
index 000000000..9a80083f6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/MapperProxy.java
@@ -0,0 +1,64 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ *
+ * Class representing a LdapMapper.
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class MapperProxy {
+ private boolean mEnable;
+ private ILdapMapper mMapper;
+
+ /**
+ *
+ * Contructs MapperProxy .
+ * @param enable Enabled or not.
+ * @param mapper Corresponding ILdapMapper object.
+ */
+ public MapperProxy(boolean enable, ILdapMapper mapper) {
+ mEnable = enable;
+ mMapper = mapper;
+ }
+
+ /**
+ *
+ * Returns if enabled.
+ * @return true if enabled, otherwise false.
+ */
+ public boolean isEnable() {
+ return mEnable;
+ }
+
+ /**
+ *
+ * Returns ILdapMapper object.
+ * @return Intance of ILdapMapper object.
+ */
+ public ILdapMapper getMapper() {
+ return mMapper;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java b/pki/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java
new file mode 100644
index 000000000..7408e9cbf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * This class represents a registered publisher plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PublisherPlugin extends Plugin {
+
+ /**
+ *
+ * Constructs a PublisherPlugin based on name and classpath.
+ * @param id name of plugin.
+ * @param path Classpath of plugin.
+ */
+ public PublisherPlugin (String id, String path) {
+ super(id, path);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java b/pki/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java
new file mode 100644
index 000000000..5a126cf9b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java
@@ -0,0 +1,63 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ *
+ * Class representing a proxy for a ILdapPublisher.
+ *
+ * @version $Revision$ $Date$
+ */
+
+
+public class PublisherProxy {
+ private boolean mEnable;
+ private ILdapPublisher mPublisher;
+
+ /**
+ *
+ * Constructs a PublisherProxy based on a ILdapPublisher object and enabled boolean.
+ * @param enable Proxy is enabled or not.
+ * @param publisher Corresponding ILdapPublisher object.
+ */
+ public PublisherProxy(boolean enable, ILdapPublisher publisher) {
+ mEnable = enable;
+ mPublisher = publisher;
+ }
+
+ /**
+ * Return if enabled or not.
+ * @return true if enabled, otherwise false.
+ */
+ public boolean isEnable() {
+ return mEnable;
+ }
+
+ /**
+ * Return ILdapPublisher object.
+ * @return Instance of ILdapPublisher.
+ */
+ public ILdapPublisher getPublisher() {
+ return mPublisher;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/publish/RulePlugin.java b/pki/base/common/src/com/netscape/certsrv/publish/RulePlugin.java
new file mode 100644
index 000000000..1de355906
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/publish/RulePlugin.java
@@ -0,0 +1,42 @@
+// --- 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.certsrv.publish;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * This class represents a registered Publishing Rule plugin.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class RulePlugin extends Plugin {
+
+ /**
+ *
+ * Constructs a RulePlugin based on name and classpath.
+ * @param id name of RulePlugin.
+ * @param path Classpath of RulePlugin.
+ */
+ public RulePlugin (String id, String path) {
+ super(id, path);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ra/IRAService.java b/pki/base/common/src/com/netscape/certsrv/ra/IRAService.java
new file mode 100644
index 000000000..09b37e39c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ra/IRAService.java
@@ -0,0 +1,74 @@
+// --- 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.certsrv.ra;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * An interface representing a RA request services.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRAService extends IService {
+
+ /**
+ * Services request.
+ *
+ * @param req request data
+ */
+ public boolean serviceRequest(IRequest req);
+
+ /**
+ * Services profile request.
+ *
+ * @param request profile enrollment request information
+ * @exception EBaseException failed to service profile enrollment request
+ */
+ public void serviceProfileRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Returns CA connector.
+ *
+ * @return CA connector
+ */
+ public IConnector getCAConnector();
+
+ /**
+ * Returns KRA connector.
+ *
+ * @return KRA connector
+ */
+ public IConnector getKRAConnector();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java b/pki/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java
new file mode 100644
index 000000000..9eb438c4f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java
@@ -0,0 +1,175 @@
+// --- 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.certsrv.ra;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * An interface represents a Registration Authority that is
+ * responsible for certificate enrollment operations.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRegistrationAuthority extends ISubsystem {
+ public static final String ID = "ra";
+
+ public static final String PROP_POLICY = "Policy";
+ public static final String PROP_REGISTRATION = "Registration";
+ public static final String PROP_GATEWAY = "gateway";
+ public static final String PROP_NICKNAME = "certNickname";
+ //public final static String PROP_PUBLISH_SUBSTORE = "publish";
+ //public final static String PROP_LDAP_PUBLISH_SUBSTORE = "ldappublish";
+ public final static String PROP_CONNECTOR = "connector";
+ public final static String PROP_NEW_NICKNAME = "newNickname";
+
+ // for the notification listeners
+ public final static String PROP_NOTIFY_SUBSTORE = "notification";
+ public final static String PROP_CERT_ISSUED_SUBSTORE = "certIssued";
+ public final static String PROP_CERT_REVOKED_SUBSTORE = "certRevoked";
+ public final static String PROP_REQ_IN_Q_SUBSTORE = "requestInQ";
+
+ /**
+ * Retrieves the request queue of this registration authority.
+ *
+ * @return RA's request queue
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Retrieves the publishing processor of this registration authority.
+ *
+ * @return RA's publishing processor
+ */
+ public IPublisherProcessor getPublisherProcessor();
+
+ /**
+ * Retrieves the policy processor of this registration authority.
+ *
+ * @return RA's policy processor
+ */
+ public IPolicyProcessor getPolicyProcessor();
+
+ /**
+ * Retrieves the RA certificate.
+ *
+ * @return the RA certificate
+ */
+ public org.mozilla.jss.crypto.X509Certificate getRACert();
+
+ /**
+ * Retrieves the request in queue listener.
+ *
+ * @return the request in queue listener
+ */
+ public IRequestListener getRequestInQListener();
+
+ /**
+ * Retrieves the request listener for issued certificates.
+ *
+ * @return the request listener for issued certificates
+ */
+ public IRequestListener getCertIssuedListener();
+
+ /**
+ * Retrieves the request listener for revoked certificates.
+ *
+ * @return the request listener for revoked certificates
+ */
+ public IRequestListener getCertRevokedListener();
+
+ /**
+ * Returns the nickname of the RA certificate.
+ *
+ * @return the nickname of the RA certificate
+ */
+ public String getNickname();
+
+ /**
+ * Retrieves the nickname of the RA certificate from configuration store.
+ *
+ * @return the nickname of the RA certificate
+ * @exception EBaseException failed to get nickname
+ */
+ public String getNewNickName() throws EBaseException;
+
+ /**
+ * Sets the new nickname of the RA certifiate.
+ *
+ * @param name new nickname
+ */
+ public void setNewNickName(String name);
+
+ /**
+ * Sets the nickname of the RA certifiate.
+ *
+ * @param str nickname
+ */
+ public void setNickname(String str);
+
+ /**
+ * Retrieves the default validity period.
+ *
+ * @return the default validity length in days
+ */
+ public long getDefaultValidity();
+
+ /**
+ * Retrieves the issuer name of this registration authority.
+ *
+ * @return the issuer name of this registration authority
+ */
+ public X500Name getX500Name();
+
+ /**
+ * Retrieves the RA service object that is responsible for
+ * processing requests.
+ *
+ * @return RA service object
+ */
+ public IRAService getRAService();
+
+ /**
+ * Retrieves the request listener by name.
+ *
+ * @param name request listener name
+ * @return the request listener
+ */
+ public IRequestListener getRequestListener(String name);
+
+ /**
+ * Retrieves all request listeners.
+ *
+ * @return name enumeration of all request listeners
+ */
+ public Enumeration getRequestListenerNames();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/registry/ERegistryException.java b/pki/base/common/src/com/netscape/certsrv/registry/ERegistryException.java
new file mode 100644
index 000000000..6d9f89d5d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/registry/ERegistryException.java
@@ -0,0 +1,39 @@
+// --- 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.certsrv.registry;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This represents a registry exception.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ERegistryException extends EBaseException {
+
+ /**
+ * Constructs a registry exception.
+ *
+ * @param msg message carried along with the exception
+ */
+ public ERegistryException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java b/pki/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java
new file mode 100644
index 000000000..b7bdfbf2c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java
@@ -0,0 +1,65 @@
+// --- 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.certsrv.registry;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * The plugin information includes name,
+ * class name, and description. The localizable
+ * name and description are information
+ * for end-users.
+ * <p>
+ *
+ * The class name can be used to create
+ * an instance of the plugin.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPluginInfo {
+
+ /**
+ * Retrieves the localized plugin name.
+ *
+ * @param locale end-user locale
+ * @return plugin name
+ */
+ public String getName(Locale locale);
+
+ /**
+ * Retrieves the localized plugin description.
+ *
+ * @param locale end-user locale
+ * @return plugin description
+ */
+ public String getDescription(Locale locale);
+
+ /**
+ * Retrieves the class name of the plugin.
+ * Instance of plugin can be created with
+ * <p>
+ * Class.forName(info.getClassName());
+ *
+ * @return java class name
+ */
+ public String getClassName();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java b/pki/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java
new file mode 100644
index 000000000..d567e8f46
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java
@@ -0,0 +1,91 @@
+// --- 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.certsrv.registry;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This represents the registry subsystem that manages
+ * mulitple types of plugin information.
+ *
+ * The plugin information includes id, name,
+ * classname, and description.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPluginRegistry extends ISubsystem {
+
+ public static final String ID = "registry";
+
+ /**
+ * Returns handle to the registry configuration file.
+ *
+ * @return configuration store of registry subsystem
+ */
+ public IConfigStore getFileConfigStore();
+
+ /**
+ * Returns all type names.
+ *
+ * @return a list of String-based names
+ */
+ public Enumeration getTypeNames();
+
+ /**
+ * Returns a list of plugin identifiers of the given type.
+ *
+ * @param type plugin type
+ * @return a list of plugin IDs
+ */
+ public Enumeration getIds(String type);
+
+ /**
+ * Retrieves the plugin information.
+ *
+ * @param type plugin type
+ * @param id plugin id
+ * @return plugin info
+ */
+ public IPluginInfo getPluginInfo(String type, String id);
+
+ /**
+ * Adds plugin info.
+ *
+ * @param type plugin type
+ * @param id plugin id
+ * @param info plugin info
+ * @exception ERegistryException failed to add plugin
+ */
+ public void addPluginInfo(String type, String id, IPluginInfo info)
+ throws ERegistryException;
+
+ /**
+ * Removes plugin info.
+ */
+ public void removePluginInfo(String type, String id)
+ throws ERegistryException;
+
+ /**
+ * Creates a pluginInfo
+ */
+ public IPluginInfo createPluginInfo(String name, String desc,
+ String classPath);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java b/pki/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java
new file mode 100644
index 000000000..a2704eed1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java
@@ -0,0 +1,538 @@
+// --- 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.certsrv.request;
+
+
+import java.util.*;
+import java.math.*;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+
+/**
+ * The ARequestNotifier class implements the IRequestNotifier interface,
+ * which notifies all registered request listeners.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ARequestNotifier implements IRequestNotifier {
+ private Hashtable mListeners = new Hashtable();
+ private Vector mNotifierThreads = new Vector();
+ private Vector mRequests = new Vector();
+ private int mMaxRequests = 100;
+ private boolean mSearchForRequests = false;
+ private int mMaxThreads = 1;
+ private ICertificateAuthority mCA = null;
+ private boolean mIsPublishingQueueEnabled = false;
+ private int mPublishingQueuePriority = 0;
+ private int mMaxPublishingQueuePageSize = 1;
+ private IRequestQueue mRequestQueue = null;
+ private String mPublishingStatus = null;
+ private int mSavePublishingStatus = 0;
+ private int mSavePublishingCounter = 0;
+
+
+ public ARequestNotifier() {
+ mPublishingQueuePriority = Thread.currentThread().getPriority();
+ }
+
+ public ARequestNotifier (ICertificateAuthority ca) {
+ mCA = ca;
+ if (mCA != null) mRequestQueue = mCA.getRequestQueue();
+ }
+
+ public void setPublishingQueue (boolean isPublishingQueueEnabled,
+ int publishingQueuePriorityLevel,
+ int maxNumberOfPublishingThreads,
+ int publishingQueuePageSize,
+ int savePublishingStatus) {
+ CMS.debug("setPublishingQueue: Publishing Queue Enabled: " + isPublishingQueueEnabled+
+ " Priority Level: " + publishingQueuePriorityLevel+
+ " Maximum Number of Threads: " + maxNumberOfPublishingThreads+
+ " Page Size: "+ publishingQueuePageSize);
+ mIsPublishingQueueEnabled = isPublishingQueueEnabled;
+ mMaxThreads = maxNumberOfPublishingThreads;
+ mMaxRequests = publishingQueuePageSize;
+ mSavePublishingStatus = savePublishingStatus;
+
+ // Publishing Queue Priority Levels: 2 - maximum, 1 - higher, 0 - normal, -1 - lower, -2 - minimum
+ if (publishingQueuePriorityLevel > 1) {
+ mPublishingQueuePriority = Thread.MAX_PRIORITY;
+ } else if (publishingQueuePriorityLevel > 0) {
+ mPublishingQueuePriority = (Thread.currentThread().getPriority() + Thread.MAX_PRIORITY) / 2;
+ } else if (publishingQueuePriorityLevel < -1) {
+ mPublishingQueuePriority = Thread.MIN_PRIORITY;
+ } else if (publishingQueuePriorityLevel < 0) {
+ mPublishingQueuePriority = (Thread.currentThread().getPriority() + Thread.MIN_PRIORITY) / 2;
+ } else {
+ mPublishingQueuePriority = Thread.currentThread().getPriority();
+ }
+
+ if (mCA != null && mRequestQueue == null) mRequestQueue = mCA.getRequestQueue();
+ if (mIsPublishingQueueEnabled && mSavePublishingStatus > 0 && mRequestQueue != null) {
+ mPublishingStatus = mRequestQueue.getPublishingStatus();
+ BigInteger status = new BigInteger("-2");
+ try {
+ status = new BigInteger(mPublishingStatus);
+ if (status.compareTo(BigInteger.ZERO) > -1) {
+ recoverPublishingQueue(mPublishingStatus);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ }
+
+ /**
+ * Registers a request listener.
+ *
+ * @param listener listener to be registered
+ */
+ public void registerListener(IRequestListener listener) {
+ // XXX should check for duplicates here or allow listeners
+ // to register twice and call twice ?
+ mListeners.put(listener.getClass().getName(), listener);
+ }
+
+ /**
+ * Registers a request listener.
+ *
+ * @param name listener name
+ * @param listener listener to be registered
+ */
+ public void registerListener(String name, IRequestListener listener) {
+ mListeners.put(name, listener);
+ }
+
+ /**
+ * Removes listener from the list of registered listeners.
+ *
+ * @param listener listener to be removed from the list
+ */
+ public void removeListener(IRequestListener listener) {
+ // XXX should check for duplicates here or allow listeners
+ // to register twice and call twice ?
+ mListeners.remove(listener.getClass().getName());
+ }
+
+ /**
+ * Gets list of listener names.
+ *
+ * @return enumeration of listener names
+ */
+ public Enumeration getListenerNames() {
+ return mListeners.keys();
+ }
+
+ /**
+ * Removes listener from the list of registered listeners.
+ *
+ * @param name listener name to be removed from the list
+ */
+ public void removeListener(String name) {
+ mListeners.remove(name);
+ }
+
+ /**
+ * Gets listener from the list of registered listeners.
+ *
+ * @param name listener name
+ * @return listener
+ */
+ public IRequestListener getListener(String name) {
+ return (IRequestListener) mListeners.get(name);
+ }
+
+ /**
+ * Gets list of listeners.
+ *
+ * @return enumeration of listeners
+ */
+ public Enumeration getListeners() {
+ return mListeners.elements();
+ }
+
+
+ private Object publishingCounterMonitor = new Object();
+
+ public void updatePublishingStatus(String id) {
+ if (mRequestQueue != null) {
+ synchronized (publishingCounterMonitor) {
+ if (mSavePublishingCounter == 0) {
+ CMS.debug("updatePublishingStatus requestId: "+id);
+ mRequestQueue.setPublishingStatus(id);
+ }
+ mSavePublishingCounter++;
+ CMS.debug("updatePublishingStatus mSavePublishingCounter: "+mSavePublishingCounter+
+ " mSavePublishingStatus: "+mSavePublishingStatus);
+ if (mSavePublishingCounter >= mSavePublishingStatus) {
+ mSavePublishingCounter = 0;
+ }
+ }
+ } else {
+ CMS.debug("updatePublishingStatus mRequestQueue == null");
+ }
+ }
+
+ /**
+ * Gets request from publishing queue.
+ *
+ * @return request
+ */
+ public synchronized IRequest getRequest() {
+ IRequest r = null;
+ String id = null;
+
+ CMS.debug("getRequest mRequests=" + mRequests.size() + " mSearchForRequests=" + mSearchForRequests);
+ if (mSearchForRequests && mRequests.size() == 1) {
+ id = (String)mRequests.elementAt(0);
+ if (mCA != null && mRequestQueue == null) mRequestQueue = mCA.getRequestQueue();
+ if (id != null && mRequestQueue != null) {
+ CMS.debug("getRequest request id=" + id);
+ IRequestVirtualList list = mRequestQueue.getPagedRequestsByFilter(
+ new RequestId(id),
+ "(requeststate=complete)", mMaxRequests, "requestId");
+ int s = list.getSize() - list.getCurrentIndex();
+ CMS.debug("getRequest list size: "+s);
+ for (int i = 0; i < s; i++) {
+ r = null;
+ try {
+ r = list.getElementAt(i);
+ } catch (Exception e) {
+ // handled below
+ }
+ if (r == null) {
+ continue;
+ }
+ String requestType = r.getRequestType();
+ if (requestType == null) {
+ continue;
+ }
+ if (!(requestType.equals(IRequest.ENROLLMENT_REQUEST) ||
+ requestType.equals(IRequest.RENEWAL_REQUEST) ||
+ requestType.equals(IRequest.REVOCATION_REQUEST) ||
+ requestType.equals(IRequest.CMCREVOKE_REQUEST) ||
+ requestType.equals(IRequest.UNREVOCATION_REQUEST))) {
+ continue;
+ }
+ if (i == 0 && id.equals(r.getRequestId().toString())) {
+ if (s == 1) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (mRequests.size() < mMaxRequests) {
+ mRequests.addElement(r.getRequestId().toString());
+ CMS.debug("getRequest added "+r.getRequestType()+" request "+r.getRequestId().toString()+
+ " to mRequests: " + mRequests.size()+" ("+mMaxRequests+")");
+ } else {
+ break;
+ }
+ }
+ CMS.debug("getRequest done with adding requests to mRequests: " + mRequests.size());
+ } else {
+ CMS.debug("getRequest has no access to the request queue");
+ }
+ }
+ if (mRequests.size() > 0) {
+ id = (String)mRequests.elementAt(0);
+ if (id != null) {
+ CMS.debug("getRequest getting request: " + id);
+ if (mCA != null && mRequestQueue == null) mRequestQueue = mCA.getRequestQueue();
+ if (mRequestQueue != null) {
+ try {
+ r = mRequestQueue.findRequest(new RequestId(id));
+ mRequests.remove(0);
+ CMS.debug("getRequest request "+ id + ((r != null)?" found":" not found"));
+ //updatePublishingStatus(id);
+ } catch (EBaseException e) {
+ CMS.debug("getRequest EBaseException " + e.toString());
+ }
+ } else {
+ CMS.debug("getRequest has no access to the request queue");
+ }
+ }
+ if (mRequests.size() == 0) {
+ mSearchForRequests = false;
+ }
+ }
+ CMS.debug("getRequest mRequests=" + mRequests.size() + " mSearchForRequests=" + mSearchForRequests + " done");
+
+ return r;
+ }
+
+ /**
+ * Gets number of requests in publishing queue.
+ *
+ * @return number of requests in publishing queue
+ */
+ public int getNumberOfRequests() {
+ return mRequests.size();
+ }
+
+ /**
+ * Checks if publishing queue is enabled.
+ *
+ * @return true if publishing queue is enabled, false otherwise
+ */
+ public boolean isPublishingQueueEnabled() {
+ return mIsPublishingQueueEnabled;
+ }
+
+ /**
+ * Removes a notifier thread from the pool of publishing queue threads.
+ *
+ * @param notifierThread Thread
+ */
+ public void removeNotifierThread(Thread notifierThread) {
+ if (mNotifierThreads.size() > 0) {
+ mNotifierThreads.remove(notifierThread);
+ if (mNotifierThreads.size() == 0) {
+ mRequestQueue.setPublishingStatus("-1");
+ }
+ }
+ CMS.debug("Number of publishing threads: " + mNotifierThreads.size());
+ }
+
+ /**
+ * Notifies all registered listeners about request.
+ *
+ * @param r request
+ */
+ public void notify(IRequest r) {
+ CMS.debug("ARequestNotifier notify mIsPublishingQueueEnabled="+mIsPublishingQueueEnabled+
+ " mMaxThreads="+mMaxThreads);
+ if (mIsPublishingQueueEnabled) {
+ addToNotify(r);
+ } else if (mMaxThreads == 0) {
+ Enumeration listeners = mListeners.elements();
+ if (listeners != null && r != null) {
+ while (listeners.hasMoreElements()) {
+ IRequestListener l = (IRequestListener) listeners.nextElement();
+ CMS.debug("RunListeners: IRequestListener = " + l.getClass().getName());
+ l.accept(r);
+ }
+ }
+ } else {
+ // spawn a seperate thread to call the listeners and return.
+ try {
+ new Thread(new RunListeners(r, mListeners.elements())).start();
+ } catch (Throwable e) {
+
+ /*
+ CMS.getLogger().log(
+ ILogger.EV_SYSTEM, ILogger.S_REQQUEUE, ILogger.LL_FAILURE,
+ "Could not run listeners for request " + r.getRequestId() +
+ ". Error " + e + ";" + e.getMessage());
+ */
+ }
+ }
+ }
+
+ /**
+ * Checks for available publishing connections
+ *
+ * @return true if there are available publishing connections, false otherwise
+ */
+ private boolean checkAvailablePublishingConnections() {
+ boolean availableConnections = false;
+
+ IPublisherProcessor pp = null;
+ if (mCA != null) pp = mCA.getPublisherProcessor();
+ if (pp != null && pp.enabled()) {
+ ILdapConnModule ldapConnModule = pp.getLdapConnModule();
+ if (ldapConnModule != null) {
+ ILdapConnFactory ldapConnFactory = ldapConnModule.getLdapConnFactory();
+ if (ldapConnFactory != null) {
+ CMS.debug("checkAvailablePublishingConnections maxConn: " + ldapConnFactory.maxConn() +
+ " totalConn: " + ldapConnFactory.totalConn());
+ if (ldapConnFactory.maxConn() > ldapConnFactory.totalConn()) {
+ availableConnections = true;
+ }
+ } else {
+ CMS.debug("checkAvailablePublishingConnections ldapConnFactory is not accessible");
+ }
+ } else {
+ CMS.debug("checkAvailablePublishingConnections ldapConnModule is not accessible");
+ }
+ } else {
+ CMS.debug("checkAvailablePublishingConnections PublisherProcessor is not " +
+ ((pp != null)?"enabled":"accessible"));
+ }
+
+ return availableConnections;
+ }
+
+ /**
+ * Checks if more publishing threads can be added.
+ *
+ * @return true if more publishing threads can be added, false otherwise
+ */
+ private boolean morePublishingThreads() {
+ boolean moreThreads = false;
+
+ if (mNotifierThreads.size() == 0) {
+ moreThreads = true;
+ } else if (mNotifierThreads.size() < mMaxThreads) {
+ CMS.debug("morePublishingThreads ("+mRequests.size()+">"+
+ ((mMaxRequests * mNotifierThreads.size()) / mMaxThreads)+
+ " "+"("+mMaxRequests+"*"+mNotifierThreads.size()+"):"+mMaxThreads);
+ // gradually add new publishing threads
+ if (mRequests.size() > ((mMaxRequests * mNotifierThreads.size()) / mMaxThreads)) {
+ // check for available publishing connections
+ if (checkAvailablePublishingConnections()) {
+ moreThreads = true;
+ }
+ }
+ }
+ CMS.debug("morePublishingThreads moreThreads: " + moreThreads);
+
+ return moreThreads;
+ }
+
+
+ /**
+ * Notifies all registered listeners about request.
+ *
+ * @param r request
+ */
+ public synchronized void addToNotify(IRequest r) {
+ if (!mSearchForRequests) {
+ if (mRequests.size() < mMaxRequests) {
+ mRequests.addElement(r.getRequestId().toString());
+ CMS.debug("addToNotify extended buffer to "+mRequests.size()+"("+mMaxRequests+")"+
+ " requests by adding request "+r.getRequestId().toString());
+ if (morePublishingThreads()) {
+ try {
+ Thread notifierThread = new Thread(new RunListeners((IRequestNotifier)this));
+ if (notifierThread != null) {
+ mNotifierThreads.addElement(notifierThread);
+ CMS.debug("Number of publishing threads: " + mNotifierThreads.size());
+ if (mPublishingQueuePriority > 0) {
+ notifierThread.setPriority(mPublishingQueuePriority);
+ }
+ notifierThread.start();
+ }
+ } catch (Throwable e) {
+ CMS.debug("addToNotify exception: " + e.toString());
+ }
+ }
+ } else {
+ mSearchForRequests = true;
+ }
+ }
+ }
+
+
+ /**
+ * Recovers publishing queue.
+ *
+ * @param id request request
+ */
+ public void recoverPublishingQueue(String id) {
+ CMS.debug("recoverPublishingQueue mRequests.size()="+mRequests.size()+"("+mMaxRequests+")"+
+ " requests by adding request "+id);
+ if (mRequests.size() == 0) {
+ mRequests.addElement(id);
+ CMS.debug("recoverPublishingQueue extended buffer to "+mRequests.size()+"("+mMaxRequests+")"+
+ " requests by adding request "+id);
+ if (morePublishingThreads()) {
+ mSearchForRequests = true;
+ try {
+ Thread notifierThread = new Thread(new RunListeners((IRequestNotifier)this));
+ if (notifierThread != null) {
+ mNotifierThreads.addElement(notifierThread);
+ CMS.debug("Number of publishing threads: " + mNotifierThreads.size());
+ if (mPublishingQueuePriority > 0) {
+ notifierThread.setPriority(mPublishingQueuePriority);
+ }
+ notifierThread.start();
+ }
+ } catch (Throwable e) {
+ CMS.debug("recoverPublishingQueue exception: " + e.toString());
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * The RunListeners class implements Runnable interface.
+ * This class executes notification of registered listeners.
+ */
+class RunListeners implements Runnable {
+ IRequest mRequest = null;
+ Enumeration mListeners = null;
+ IRequestNotifier mRequestNotifier = null;
+
+ /**
+ * RunListeners class constructor.
+ *
+ * @param r request
+ * @param listeners list of listeners
+ */
+ public RunListeners(IRequest r, Enumeration listeners) {
+ mRequest = r;
+ mListeners = listeners;
+ }
+
+ /**
+ * RunListeners class constructor.
+ *
+ * @param r request
+ * @param listeners list of listeners
+ */
+ public RunListeners(IRequestNotifier requestNotifier) {
+ mRequestNotifier = requestNotifier;
+ mListeners = mRequestNotifier.getListeners();
+ }
+
+ /**
+ * RunListeners thread implementation.
+ */
+ public void run() {
+ CMS.debug("RunListeners::"+((mRequestNotifier != null && mRequestNotifier.getNumberOfRequests() > 0)?" Queue: "+mRequestNotifier.getNumberOfRequests():" noQueue")+
+ " "+((mRequest != null)?" SingleRequest":" noSingleRequest"));
+ do {
+ if (mRequestNotifier != null) mRequest = (IRequest)mRequestNotifier.getRequest();
+ if (mListeners != null && mRequest != null) {
+ while (mListeners.hasMoreElements()) {
+ IRequestListener l = (IRequestListener) mListeners.nextElement();
+ CMS.debug("RunListeners: IRequestListener = " + l.getClass().getName());
+ l.accept(mRequest);
+ }
+ if (mRequestNotifier != null) {
+ CMS.debug("RunListeners: mRequest = " + mRequest.getRequestId().toString());
+ mRequestNotifier.updatePublishingStatus(mRequest.getRequestId().toString());
+ }
+ }
+ CMS.debug("RunListeners: "+((mRequestNotifier != null && mRequestNotifier.getNumberOfRequests() > 0)?" Queue: "+mRequestNotifier.getNumberOfRequests():" noQueue")+
+ " "+((mRequest != null)?" SingleRequest":" noSingleRequest"));
+ if (mRequestNotifier != null) mListeners = mRequestNotifier.getListeners();
+ } while (mRequestNotifier != null && mRequestNotifier.getNumberOfRequests() > 0);
+
+ if (mRequestNotifier != null) mRequestNotifier.removeNotifierThread(Thread.currentThread());
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/AgentApproval.java b/pki/base/common/src/com/netscape/certsrv/request/AgentApproval.java
new file mode 100644
index 000000000..5e41b54f2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/AgentApproval.java
@@ -0,0 +1,64 @@
+// --- 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.certsrv.request;
+
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+
+/**
+ * The AgentApproval class contains the record of a
+ * single agent approval.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AgentApproval
+ implements Serializable {
+
+ /**
+ * Returns the approving agent's user name.
+ *
+ * @return an identifier for the agent
+ */
+ public String getUserName() {
+ return mUserName;
+ }
+
+ /**
+ * Returns the date of the approval
+ *
+ * @return date and time of the approval
+ */
+ public Date getDate() {
+ return mDate;
+ }
+
+ /**
+ * AgentApproval class constructor
+ *
+ * @param userName user name of the approving agent
+ */
+ AgentApproval(String userName) {
+ mUserName = userName;
+ }
+
+ String mUserName;
+ Date mDate = new Date(); /* CMS.getCurrentDate(); */
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/AgentApprovals.java b/pki/base/common/src/com/netscape/certsrv/request/AgentApprovals.java
new file mode 100644
index 000000000..9bd7fa857
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/AgentApprovals.java
@@ -0,0 +1,156 @@
+// --- 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.certsrv.request;
+
+
+import java.io.Serializable;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+
+/**
+ * A collection of AgentApproval objects.
+ * <single-threaded>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AgentApprovals
+ implements Serializable {
+
+ /**
+ * Adds an approval to approval's list.
+ * <p>
+ * If an approval is already present for this user,
+ * it is updated with a new date. Otherwise a new
+ * value is inserted.
+ *
+ * @param userName user name of the approving agent
+ */
+ public void addApproval(String userName) {
+ AgentApproval a = findApproval(userName);
+
+ // update existing approval
+ if (a != null) {
+ a.mDate = new Date(); /* CMS.getCurrentDate(); */
+ return;
+ }
+
+ a = new AgentApproval(userName);
+ mVector.addElement(a);
+ }
+
+ /**
+ * Removes an approval from approval's list.
+ * <p>
+ * If there is no approval for this userName, this
+ * call does nothing.
+ *
+ * @param userName user name of the approving agent
+ */
+ public void removeApproval(String userName) {
+ AgentApproval a = findApproval(userName);
+
+ if (a != null)
+ mVector.removeElement(a);
+ }
+
+ /**
+ * Finds an existing AgentApproval for the named user.
+ *
+ * @param userName user name of the approving agent
+ * @return an AgentApproval object
+ */
+ public AgentApproval findApproval(String userName) {
+ AgentApproval a = null;
+
+ // search
+ for (int i = 0; i < mVector.size(); i++) {
+ a = (AgentApproval) mVector.elementAt(i);
+
+ if (a.mUserName.equals(userName)) break;
+ }
+
+ return a;
+ }
+
+ /**
+ * Returns an enumeration of the agent approvals
+ *
+ * @return an enumeration of the agent approvals
+ */
+ public Enumeration elements() {
+ return mVector.elements();
+ }
+
+ /**
+ * Returns the AgentApprovals as a Vector of strings.
+ * Each entry in the vector is of the format:
+ * epoch;username
+ * where epoch is the date.getTime()
+ * <p>
+ * This is used for serialization in Request.setExtData().
+ * @return The string vector.
+ */
+ public Vector toStringVector() {
+ Vector retval = new Vector(mVector.size());
+ for (int i = 0; i < mVector.size(); i++) {
+ AgentApproval a = (AgentApproval) mVector.elementAt(i);
+ retval.add(a.getDate().getTime() + ";" + a.getUserName());
+ }
+
+ return retval;
+ }
+
+ /**
+ * Recreates an AgentApprovals instance from a Vector of strings that
+ * was created by toStringVector().
+ * @param stringVector The vector of strings to translate
+ * @return the AgentApprovals instance or null if it can't be translated.
+ */
+ public static AgentApprovals fromStringVector(Vector stringVector) {
+ if (stringVector == null) {
+ return null;
+ }
+ AgentApprovals approvals = new AgentApprovals();
+ for (int i = 0; i < stringVector.size(); i++) {
+ try {
+ String approvalString = (String)stringVector.get(i);
+ String[] parts = approvalString.split(";", 2);
+ if (parts.length != 2) {
+ return null;
+ }
+ Long epoch = new Long(parts[0]);
+ Date date = new Date(epoch.longValue());
+
+ AgentApproval approval = new AgentApproval(parts[1]);
+ approval.mDate = date;
+
+ approvals.mVector.add(approval);
+ } catch (ClassCastException e) {
+ return null;
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ return approvals;
+ }
+
+ protected Vector mVector = new Vector();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java b/pki/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java
new file mode 100644
index 000000000..e7036d1ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java
@@ -0,0 +1,31 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * An example of a more specialized request interface.
+ * This version (currently) doesn't supply any additional
+ * data, but is implementated only for testing and
+ * demonstration purposes.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEnrollmentRequest
+ extends IRequest {
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/INotify.java b/pki/base/common/src/com/netscape/certsrv/request/INotify.java
new file mode 100644
index 000000000..d4ff15b7c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/INotify.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * The INotify interface defines operations that are invoked
+ * when a request is completely processed. A class implementing
+ * this interface may be registered with a IRequestQueue.
+ * The interface will be invoked when a request is completely
+ * serviced by the IService object.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface INotify {
+
+ /**
+ * Provides notification that a request has been completed.
+ * The implementation may use values stored in the IRequest
+ * object, and may implement any type publishing (such as email
+ * or writing values into a directory)
+ *
+ * @param request the request that is completed.
+ */
+ public void notify(IRequest request);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IPolicy.java b/pki/base/common/src/com/netscape/certsrv/request/IPolicy.java
new file mode 100644
index 000000000..d74a32a43
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IPolicy.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * Interface to a policy. The policy evaluates the request for
+ * correctness and completeness. It may change or add to values
+ * stored in the request. The policy object also decides
+ * whether a request should be queue to await approval by
+ * an agent.
+ * FUTURE: In this case, the policy should set the
+ * 'agentGroup' entry in the request to indicate the group
+ * of agents allowed to perform further processing. If none
+ * is set, a default value ("defaultAgentGroup") will be
+ * set instead.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPolicy {
+
+ /**
+ * Applies the policy check to the request. The policy should
+ * determine whether the request can be processed immediately,
+ * or should be held pending manual approval.
+ * <p>
+ * The policy can update fields in the request, to add additional values
+ * or to restrict the values to pre-determined ranges.
+ * <p>
+ * @param request
+ * the request to check
+ * @return
+ * a result code indicating the result of the evaluation. The
+ * processor will determine the next request processing step based
+ * on this value
+ */
+ PolicyResult apply(IRequest request);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequest.java b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java
new file mode 100644
index 000000000..f54352ce1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -0,0 +1,729 @@
+// --- 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.certsrv.request;
+
+
+//import java.io.Serializable;
+
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IAttrSet;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+
+/**
+ * An interface that defines abilities of request objects,
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRequest {
+
+ public static final String REQ_VERSION = "requestVersion";
+
+ public static final String REQ_STATUS = "requestStatus";
+ public static final String REQ_TYPE = "requestType";
+ public static final String REQ_FORMAT = "requestFormat";
+
+ // request type values.
+ public static final String ENROLLMENT_REQUEST = "enrollment";
+ public static final String RENEWAL_REQUEST = "renewal";
+ public static final String REVOCATION_REQUEST = "revocation";
+ public static final String CMCREVOKE_REQUEST = "CMCRevReq";
+ public static final String UNREVOCATION_REQUEST = "unrevocation";
+ public static final String KEYARCHIVAL_REQUEST = "archival";
+ public static final String KEYRECOVERY_REQUEST = "recovery";
+ public static final String KEY_RECOVERY_REQUEST = "keyRecovery";
+ public static final String KEY_ARCHIVAL_REQUEST = "keyArchival";
+ public static final String GETCACHAIN_REQUEST = "getCAChain";
+ public static final String GETREVOCATIONINFO_REQUEST = "getRevocationInfo";
+ public static final String GETCRL_REQUEST = "getCRL";
+ public static final String GETCERTS_REQUEST = "getCertificates";
+ public static final String REVOCATION_CHECK_CHALLENGE_REQUEST = "revocationChallenge";
+ public static final String GETCERT_STATUS_REQUEST = "getCertStatus";
+ public static final String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+ public static final String CLA_CERT4CRL_REQUEST = "cert4crl";
+ public static final String CLA_UNCERT4CRL_REQUEST = "uncert4crl";
+ public static final String NETKEY_KEYGEN_REQUEST = "netkeyKeygen";
+ public static final String NETKEY_KEYRECOVERY_REQUEST = "netkeyKeyRecovery";
+
+ public static final String REQUESTOR_NAME = "csrRequestorName";
+ public static final String REQUESTOR_PHONE = "csrRequestorPhone";
+ public static final String REQUESTOR_EMAIL = "csrRequestorEmail";
+ public static final String REQUESTOR_COMMENTS = "csrRequestorComments";
+
+ // request attributes for all
+ public static final String AUTH_TOKEN = "AUTH_TOKEN";
+ public static final String HTTP_PARAMS = "HTTP_PARAMS";
+ public static final String HTTP_HEADERS = "HTTP_HEADERS";
+ // Params added by agents on agent approval page
+ public static final String AGENT_PARAMS = "AGENT_PARAMS";
+ // server attributes: attributes generated by server modules.
+ public static final String SERVER_ATTRS = "SERVER_ATTRS";
+
+ public static final String RESULT = "Result"; // service result.
+ public static final Integer RES_SUCCESS = Integer.valueOf(1); // result value
+ public static final Integer RES_ERROR = Integer.valueOf(2); // result value
+ public static final String REMOTE_SERVICE_AUTHORITY = "RemServiceAuthority";
+ public static final String SVCERRORS = "serviceErrors";
+ public static final String REMOTE_STATUS = "remoteStatus";
+ public static final String REMOTE_REQID = "remoteReqID";
+ public static final String CERT_STATUS = "certStatus";
+
+ // enrollment request attributes (from http request)
+ public static final String CERT_TYPE = "certType";
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String PKCS10_REQID = "pkcs10ReqId";
+ // CMC request attributes
+ public static final String CMC_REQIDS = "cmcReqIds";
+ public static final String CMC_TRANSID = "transactionId";
+ public static final String CMC_SENDERNONCE = "senderNonce";
+ public static final String CMC_RECIPIENTNONCE = "recipientNonce";
+ public static final String CMC_REGINFO = "regInfo";
+
+ // enrollment request attributes (generated internally)
+ // also used for renewal
+ public static final String CERT_INFO = "CERT_INFO";
+ public static final String ISSUED_CERTS = "issuedCerts";
+ public static final String
+ REQUEST_TRUSTEDMGR_PRIVILEGE = "requestTrustedManagerPrivilege";
+ public static final String FINGERPRINTS = "fingerprints";
+
+ // enrollment request values
+ public static final String SERVER_CERT = "server";
+ public static final String CLIENT_CERT = "client";
+ public static final String CA_CERT = "ca";
+ public static final String RA_CERT = "ra";
+ public static final String OCSP_CERT = "ocsp";
+ public static final String OBJECT_SIGNING_CERT = "objSignClient";
+ public static final String OTHER_CERT = "other";
+ public static final String ROUTER_CERT = "router"; // deprecated
+ public static final String CEP_CERT = "CEP-Request";
+
+ // renewal request attributes. (internally set)
+ // also used for revocation
+ public static final String OLD_CERTS = "OLD_CERTS";
+ public static final String OLD_SERIALS = "OLD_SERIALS";
+ public static final String ISSUERDN = "issuerDN";
+
+ // revocation request attributes (internally set)
+ public static final String REVOKED_CERTS = "revokedCerts";
+ public static final String REVOKED_REASON = "revocationReason";
+ // CCA -> CLA request attributes
+ public static final String REVOKED_CERT_RECORDS = "revokedCertRecs";
+ // crl update status after a revocation.
+ public final static String CRL_UPDATE_STATUS = "crlUpdateStatus";
+ public final static String CRL_UPDATE_ERROR = "crlUpdateError";
+ public final static String CRL_PUBLISH_STATUS = "crlPublishStatus";
+ public final static String CRL_PUBLISH_ERROR = "crlPublishError";
+ public static final String REQUESTOR_TYPE = "requestorType";
+
+ // Netkey request attributes
+ public final static String NETKEY_ATTR_CUID = "CUID";
+ public final static String NETKEY_ATTR_USERID = "USERID";
+ public final static String NETKEY_ATTR_DRMTRANS_DES_KEY = "drm_trans_desKey";
+ public final static String NETKEY_ATTR_ARCHIVE_FLAG ="archive";
+ public final static String NETKEY_ATTR_SERVERSIDE_MUSCLE_FLAG ="serverSideMuscle";
+ public final static String NETKEY_ATTR_ENC_PRIVKEY_FLAG ="encryptPrivKey";
+ public final static String NETKEY_ATTR_USER_CERT = "cert";
+ public final static String NETKEY_ATTR_KEY_SIZE = "keysize";
+
+ // requestor type values.
+ public static final String REQUESTOR_EE = "EE";
+ public static final String REQUESTOR_RA = "RA";
+ public static final String REQUESTOR_NETKEY_RA = "NETKEY_RA";
+ public static final String REQUESTOR_KRA = "KRA";
+ public static final String REQUESTOR_AGENT = "Agent";
+
+ // others (internally set)
+ public final static String CACERTCHAIN = "CACertChain";
+ public final static String CRL = "CRL";
+ public final static String DOGETCACHAIN = "doGetCAChain";
+ public final static String CERT_FILTER = "certFilter";
+
+ // used by policy
+ public static final String ERRORS = "errors";
+ public static final String SMIME = "SMIME";
+ public static final String OBJECT_SIGNING = "ObjectSigning";
+ public static final String SSL_CLIENT = "SSLClient";
+
+ /**
+ * Gets the primary identifier for this request.
+ *
+ * @return request id
+ */
+ RequestId getRequestId();
+
+ /**
+ * Gets the current state of this request.
+ *
+ * @return request status
+ */
+ RequestStatus getRequestStatus();
+
+ /**
+ * Gets the "sourceId" for the request. The sourceId is
+ * assigned by the originator of the request (for example,
+ * the EE servlet or the RA servlet.
+ * <p>
+ * The sourceId should be unique so that it can be used
+ * to retrieve request later without knowing the locally
+ * assigned primary id (RequestID)
+ * <p>
+ * @return
+ * the sourceId value (or null if none has been set)
+ */
+ public String getSourceId();
+
+ /**
+ * Sets the "sourceId" for this request. The request must be updated
+ * in the database for this change to take effect. This can be done
+ * by calling IRequestQueue.update() or by performing one of the
+ * other operations like processRequest or approveRequest.
+ *
+ * @param id source id for this request
+ */
+ public void setSourceId(String id);
+
+ /**
+ * Gets the current owner of this request.
+ *
+ * @return request owner
+ */
+ public String getRequestOwner();
+
+ /**
+ * Sets the current owner of this request.
+ *
+ * @param owner
+ * The new owner of this request. If this value is set to null
+ * there will be no current owner
+ */
+ public void setRequestOwner(String owner);
+
+ /**
+ * Gets the type of this request.
+ *
+ * @return request type
+ */
+ public String getRequestType();
+
+ /**
+ * Sets the type or this request.
+ *
+ * @param type request type
+ */
+ public void setRequestType(String type);
+
+ /**
+ * Gets the version of this request.
+ *
+ * @return request version
+ */
+ public String getRequestVersion();
+
+ /**
+ * Gets the time this request was created.
+ *
+ * @return request creation time
+ */
+ Date getCreationTime();
+
+ /**
+ * Gets the time this request was last modified (defined
+ * as updated in the queue) (See IRequestQueue.update)
+ *
+ * @return request last modification time
+ */
+ Date getModificationTime();
+
+ /*
+ * Attribute names for performing searches.
+ */
+ public final static String ATTR_REQUEST_OWNER = "requestOwner";
+ public final static String ATTR_REQUEST_STATUS = "requestStatus";
+ public final static String ATTR_SOURCE_ID = "requestSourceId";
+ public final static String ATTR_REQUEST_TYPE = "requestType";
+
+ /*
+ * Other attributes stored in the attribute set
+ */
+ public final static String UPDATED_BY = "updatedBy";
+ // String error messages
+ public static final String ERROR = "Error";
+
+ /**
+ * Copies meta attributes (excluding request Id, etc.) of another request
+ * to this request.
+ *
+ * @param req another request
+ */
+ public void copyContents(IRequest req);
+
+ /**
+ * Gets context of this request.
+ *
+ * @return request context
+ */
+ public String getContext();
+
+ /**
+ * Sets context of this request.
+ *
+ * @param ctx request context
+ */
+ public void setContext(String ctx);
+
+ /**
+ * Sets status of this request.
+ *
+ * @param s request status
+ */
+ public void setRequestStatus(RequestStatus s);
+
+ /**
+ * Gets status of connector transfer.
+ *
+ * @return status of connector transfer
+ */
+ public boolean isSuccess();
+
+ /**
+ * Gets localized error message from connector transfer.
+ *
+ * @param locale request locale
+ * @return error message from connector transfer
+ */
+ public String getError(Locale locale);
+
+
+ /**************************************************************
+ * ExtData data methods:
+ *
+ * These methods should be used in place of the mAttrData methods
+ * deprecated above.
+ *
+ * These methods all store Strings in LDAP. This means they can no longer
+ * be used as a garbage dump for all sorts of objects. A limited number
+ * of helper methods are provided for Vectors/Arrays/Hashtables but the
+ * keys and values for all of these should be Strings.
+ *
+ * The keys are used in the LDAP attribute names, and so much obey LDAP
+ * key syntax rules: A-Za-z0-9 and hyphen.
+ */
+
+ /**
+ * Sets an Extended Data string-key string-value pair.
+ * All keys are lower cased because LDAP does not preserve case.
+ *
+ * @param key The extended data key
+ * @param value The extended data value
+ * @return false if key is invalid.
+ */
+ public boolean setExtData(String key, String value);
+
+ /**
+ * Sets an Extended Data string-key string-value pair.
+ * The key and hashtable keys are all lowercased because LDAP does not
+ * preserve case.
+ *
+ * @param key The extended data key
+ * @param value The extended data value
+ * the Hashtable contains an illegal key.
+ * @return false if the key or hashtable keys are invalid
+ */
+ public boolean setExtData(String key, Hashtable value);
+
+ /**
+ * Checks whether the key is storing a simple String value, or a complex
+ * (Vector/hashtable) structure.
+ * @param key The key to check for.
+ * @return True if the key maps to a string. False if it maps to a
+ * hashtable.
+ */
+ public boolean isSimpleExtDataValue(String key);
+
+ /**
+ * Returns the String value stored for the String key. Returns null
+ * if not found. Throws exception if key stores a complex data structure
+ * (Vector/Hashtable).
+ * @param key The key to lookup (case-insensitive)
+ * @return The value associated with the key. null if not found or if the
+ * key is associated with a non-string value.
+ */
+ public String getExtDataInString(String key);
+
+ /**
+ * Returns the Hashtable value for the String key. Returns null if not
+ * found. Throws exception if the key stores a String value.
+ *
+ * The Hashtable returned is actually a subclass of Hashtable that
+ * lowercases all keys used to access the hashtable. Its purpose is to
+ * to make lookups seemless, but be aware it is not a normal hashtable and
+ * might behave strangely in some cases (e.g., iterating keys)
+ *
+ * @param key The key to lookup (case-insensitive)
+ * @return The hashtable value associated with the key. null if not found
+ * or if the key is associated with a string-value.
+ */
+ public Hashtable getExtDataInHashtable(String key);
+
+ /**
+ * Returns all the keys stored in ExtData
+ * @return Enumeration of all the keys.
+ */
+ public Enumeration getExtDataKeys();
+
+ /**
+ * Stores an array of Strings in ExtData.
+ * The indices of the array are used as subkeys.
+ * @param key the ExtData key
+ * @param values the array of string values to store
+ * @return False if the key is invalid
+ */
+ public boolean setExtData(String key, String[] values);
+
+ /**
+ * Retrieves an array of Strings stored with the key.
+ * This only works if the data was stored as an array. If the data
+ * is not correct, this method will return null.
+ * @param key The ExtData key
+ * @return The value. Null if not found or the data isn't an array.
+ */
+ public String[] getExtDataInStringArray(String key);
+
+ /**
+ * Removes the value of an extdata attribute.
+ *
+ * @param type key to delete
+ */
+ void deleteExtData(String type);
+
+ /*****************************
+ * Helper methods for ExtData
+ ****************************/
+
+ /**
+ * Helper method to add subkey/value pair to a ExtData hashtable.
+ * If the hashtable it exists, the subkey/value are added to it. Otherwise
+ * a new hashtable is created.
+ *
+ * The key and subkey are lowercased because LDAP does not preserve case.
+ *
+ * @param key The top level key
+ * @param subkey The hashtable data key
+ * @param value The hashtable value
+ * @return False if the key or subkey are invalid
+ */
+ public boolean setExtData(String key, String subkey, String value);
+
+ /**
+ * Helper method to retrieve an individual value from a Hashtable value.
+ * @param key the ExtData key
+ * @param subkey the key in the Hashtable value (case insensitive)
+ * @return the value corresponding to the key/subkey
+ */
+ public String getExtDataInString(String key, String subkey);
+
+ /**
+ * Helper method to store an Integer value. It converts the integer value
+ * to a String and stores it.
+ *
+ * @param key the ExtData key
+ * @param value the Integer to store (as a String)
+ * @return False if the key or value are invalid
+ */
+ public boolean setExtData(String key, Integer value);
+
+ /**
+ * Retrieves an integer value. Returns null if not found or
+ * the value can't be represented as an Integer.
+ *
+ * @param key The ExtData key to lookup
+ * @return The integer value or null if not possible.
+ */
+ public Integer getExtDataInInteger(String key);
+
+ /**
+ * Stores an array of Integers
+ * @param key The extdata key
+ * @param values The array of Integers to store
+ * @return false if the key is invalid
+ */
+ public boolean setExtData(String key, Integer[] values);
+
+ /**
+ * Retrieves an array of Integers
+ * @param key The extdata key
+ * @return The array of Integers or null on error.
+ */
+ public Integer[] getExtDataInIntegerArray(String key);
+
+ /**
+ * Helper method to store a BigInteger value. It converts the integer value
+ * to a String and stores it.
+ *
+ * @param key the ExtData key
+ * @param value the BigInteger to store (as a String)
+ * @return False if the key or value are invalid
+ */
+ public boolean setExtData(String key, BigInteger value);
+
+ /**
+ * Retrieves a BigInteger value. Returns null if not found or
+ * the value can't be represented as a BigInteger.
+ *
+ * @param key The ExtData key to lookup
+ * @return The integer value or null if not possible.
+ */
+ public BigInteger getExtDataInBigInteger(String key);
+
+ /**
+ * Stores an array of BigIntegers
+ * @param key The extdata key
+ * @param values The array of BigIntegers to store
+ * @return false if the key is invalid
+ */
+ public boolean setExtData(String key, BigInteger[] values);
+
+ /**
+ * Retrieves an array of BigIntegers
+ * @param key The extdata key
+ * @return The array of BigIntegers or null on error.
+ */
+ public BigInteger[] getExtDataInBigIntegerArray(String key);
+
+ /**
+ * Helper method to store an exception.
+ * It actually stores the e.toString() value.
+ *
+ * @param key The ExtData key to store under
+ * @param e The throwable to store
+ * @return False if the key is invalid.
+ */
+ public boolean setExtData(String key, Throwable e);
+
+ /**
+ * Stores a byte array as base64 encoded text
+ * @param key The ExtData key
+ * @param data The byte array to store
+ * @return False if the key is invalid.
+ */
+ public boolean setExtData(String key, byte[] data);
+
+ /**
+ * Retrieves the data, which should be base64 encoded as a byte array.
+ * @param key The ExtData key
+ * @return The data, or null if an error occurs.
+ */
+ public byte[] getExtDataInByteArray(String key);
+
+ /**
+ * Stores a X509CertImpl as base64 encoded text using the getEncode()
+ * method.
+ * @param key The ExtData key
+ * @param data certificate
+ * @return False if the key is invalid.
+ */
+ public boolean setExtData(String key, X509CertImpl data);
+
+ /**
+ * Retrieves the data, which should be base64 encoded as a byte array.
+ * @param key The ExtData key
+ * @return The data, or null if an error occurs.
+ */
+ public X509CertImpl getExtDataInCert(String key);
+
+ /**
+ * Stores an array of X509CertImpls as a base64 encoded text.
+ * @param key The ExtData key
+ * @param data The array of certs to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, X509CertImpl[] data);
+
+ /**
+ * Retrieves an array of X509CertImpl.
+ * @param key The ExtData key
+ * @return Array of certs, or null if not found or invalid data.
+ */
+ public X509CertImpl[] getExtDataInCertArray(String key);
+
+ /**
+ * Stores a X509CertInfo as base64 encoded text using the getEncodedInfo()
+ * method.
+ * @param key The ExtData key
+ * @param data certificate
+ * @return False if the key is invalid.
+ */
+ public boolean setExtData(String key, X509CertInfo data);
+
+ /**
+ * Retrieves the data, which should be base64 encoded as a byte array.
+ * @param key The ExtData key
+ * @return The data, or null if an error occurs.
+ */
+ public X509CertInfo getExtDataInCertInfo(String key);
+
+ /**
+ * Stores an array of X509CertInfos as a base64 encoded text.
+ * @param key The ExtData key
+ * @param data The array of cert infos to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, X509CertInfo[] data);
+
+ /**
+ * Retrieves an array of X509CertInfo.
+ * @param key The ExtData key
+ * @return Array of cert infos, or null if not found or invalid data.
+ */
+ public X509CertInfo[] getExtDataInCertInfoArray(String key);
+
+ /**
+ * Stores an array of RevokedCertImpls as a base64 encoded text.
+ * @param key The ExtData key
+ * @param data The array of cert infos to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, RevokedCertImpl[] data);
+
+ /**
+ * Retrieves an array of RevokedCertImpl.
+ * @param key The ExtData key
+ * @return Array of cert infos, or null if not found or invalid data.
+ */
+ public RevokedCertImpl[] getExtDataInRevokedCertArray(String key);
+
+ /**
+ * Stores the contents of the String Vector in ExtData.
+ * TODO - as soon as we're allowed to use JDK5 this should be changed
+ * to use Vector<String> data.
+ *
+ * Note that modifications to the Vector are not automatically reflected
+ * after it is stored. You must call set() again to make the changes.
+ *
+ * @param key The extdata key to store
+ * @param data A vector of Strings to store
+ * @return False on key error or invalid data.
+ */
+ public boolean setExtData(String key, Vector data);
+
+ /**
+ * Returns a vector of strings for the key.
+ * Note that the returned vector, if modified, does not make changes
+ * in ExtData. You must call setExtData() to propogate changes back
+ * into ExtData.
+ *
+ * @param key The extdata key
+ * @return A Vector of strings, or null on error.
+ */
+ public Vector getExtDataInStringVector(String key);
+
+ /**
+ * Gets boolean value for given type or default value
+ * if attribute is absent.
+ *
+ * @param type attribute type
+ * @param defVal default attribute value
+ * @return attribute value
+ */
+ boolean getExtDataInBoolean(String type, boolean defVal);
+
+
+ /**
+ * Gets extdata boolean value for given type or default value
+ * if attribute is absent for this request with this prefix.
+ *
+ * @param prefix request prefix
+ * @param type attribute type
+ * @param defVal default attribute value
+ * @return attribute value
+ */
+ public boolean getExtDataInBoolean(String prefix, String type, boolean defVal);
+
+
+ /**
+ * Stores an AuthToken the same as a Hashtable.
+ * @param key The ExtData key
+ * @param data The authtoken to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, IAuthToken data);
+
+ /**
+ * Retrieves an authtoken.
+ * @param key The ExtData key
+ * @return AuthToken, or null if not found or invalid data.
+ */
+ public IAuthToken getExtDataInAuthToken(String key);
+
+ /**
+ * Stores a CertificateExtensions in extdata.
+ * @param key The ExtData key
+ * @param data The CertificateExtensions to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, CertificateExtensions data);
+
+ /**
+ * Retrieves the CertificateExtensions associated with the key.
+ * @param key The ExtData key
+ * @return the object, or null if not found or invalid data.
+ */
+ public CertificateExtensions getExtDataInCertExts(String key);
+
+ /**
+ * Stores a CertificateSubjectName in extdata.
+ * @param key The ExtData key
+ * @param data The CertificateSubjectName to store
+ * @return False if the key or data is invalid.
+ */
+ public boolean setExtData(String key, CertificateSubjectName data);
+
+ /**
+ * Retrieves the CertificateSubjectName associated with the key.
+ * @param key The ExtData key
+ * @return the object, or null if not found or invalid data.
+ */
+ public CertificateSubjectName getExtDataInCertSubjectName(String key);
+
+ /**
+ * This method returns an IAttrSet wrapper for the IRequest.
+ * Use of this method is strongly discouraged. It provides extremely
+ * limited functionality, and is only provided for the two places IRequest
+ * is being used as such in the code. If you are considering using this
+ * method, please don't.
+ *
+ * @return IAttrSet wrapper with basic "get" functionality.
+ * @deprecated
+ */
+ public IAttrSet asIAttrSet();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestList.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestList.java
new file mode 100644
index 000000000..a01ceb8cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestList.java
@@ -0,0 +1,58 @@
+// --- 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.certsrv.request;
+
+
+import java.util.Enumeration;
+
+
+/**
+ * An interface providing a list of RequestIds that match
+ * some criteria. It could be a list of all elements in a
+ * queue, or just some defined sub-set.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRequestList
+ extends Enumeration {
+
+ /**
+ * Gets the next RequestId from this list. null is
+ * returned when there are no more elements in the list.
+ * <p>
+ * Callers should be sure there is another element in the
+ * list by calling hasMoreElements first.
+ * <p>
+ * @return next request id
+ */
+ RequestId nextRequestId();
+
+ /**
+ * Gets next request from the list.
+ *
+ * @return next request
+ */
+ public Object nextRequest();
+
+ /**
+ * Gets next request Object from the list.
+ *
+ * @return next request
+ */
+ public IRequest nextRequestObject();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestListener.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestListener.java
new file mode 100644
index 000000000..29adf3a0f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestListener.java
@@ -0,0 +1,55 @@
+// --- 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.certsrv.request;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * An interface that defines abilities of request listener,
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRequestListener {
+
+ /**
+ * Initializes request listener for the specific subsystem
+ * and configuration store.
+ *
+ * @param sub subsystem
+ * @param config configuration store
+ */
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException;
+
+ /**
+ * Accepts request.
+ *
+ * @param request request
+ */
+ public void accept(IRequest request);
+
+ /**
+ * Sets attribute.
+ *
+ * @param name attribute name
+ * @param val attribute value
+ */
+ public void set(String name, String val);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java
new file mode 100644
index 000000000..7cf31557f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java
@@ -0,0 +1,133 @@
+// --- 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.certsrv.request;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * IRequestNotifier interface defines methods to register listeners,
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRequestNotifier extends INotify {
+
+ /**
+ * Registers a request listener.
+ *
+ * @param listener listener to be registered
+ */
+ public void registerListener(IRequestListener listener);
+
+ /**
+ * Registers a request listener.
+ *
+ * @param name listener name
+ * @param listener listener to be registered
+ */
+ public void registerListener(String name, IRequestListener listener);
+
+ /**
+ * Removes listener from the list of registered listeners.
+ *
+ * @param listener listener to be removed from the list
+ */
+ public void removeListener(IRequestListener listener);
+
+ /**
+ * Removes listener from the list of registered listeners.
+ *
+ * @param name listener name to be removed from the list
+ */
+ public void removeListener(String name);
+
+ /**
+ * Gets list of listener names.
+ *
+ * @return enumeration of listener names
+ */
+ public Enumeration getListenerNames();
+
+ /**
+ * Gets listener from the list of registered listeners.
+ *
+ * @param name listener name
+ * @return listener
+ */
+ public IRequestListener getListener(String name);
+
+ /**
+ * Gets list of listeners.
+ *
+ * @return enumeration of listeners
+ */
+ public Enumeration getListeners();
+
+ /**
+ * Gets request from publishing queue.
+ *
+ * @return request
+ */
+ public IRequest getRequest();
+
+ /**
+ * Gets number of requests in publishing queue.
+ *
+ * @return number of requests in publishing queue
+ */
+ public int getNumberOfRequests();
+
+ /**
+ * Checks if publishing queue is enabled.
+ *
+ * @return true if publishing queue is enabled, false otherwise
+ */
+ public boolean isPublishingQueueEnabled();
+
+ /**
+ * Removes a notifier thread from the pool of publishing queue threads.
+ *
+ * @param notifierThread Thread
+ */
+ public void removeNotifierThread(Thread notifierThread);
+
+ /**
+ * Notifies all registered listeners about request.
+ *
+ * @param r request
+ */
+ public void addToNotify(IRequest r);
+
+ /**
+ * Sets publishing queue parameters.
+ *
+ * @param isPublishingQueueEnabled publishing queue switch
+ * @param publishingQueuePriorityLevel publishing queue priority level
+ * @param maxNumberOfPublishingThreads maximum number of publishing threads
+ * @param publishingQueuePageSize publishing queue page size
+ */
+ public void setPublishingQueue (boolean isPublishingQueueEnabled,
+ int publishingQueuePriorityLevel,
+ int maxNumberOfPublishingThreads,
+ int publishingQueuePageSize,
+ int savePublishingStatus);
+
+ public void updatePublishingStatus(String id);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java
new file mode 100644
index 000000000..9b2edf9b4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java
@@ -0,0 +1,414 @@
+// --- 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.certsrv.request;
+
+import java.math.*;
+import java.util.Enumeration;
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * The IRequestQueue interface defines the operations on
+ * a collection of requests within the certificate server.
+ * There are may several collections, such as KRA, RA and CA
+ * requests. Each of these request collection has a defined
+ * set of policies, a notification service (for request
+ * completion) and a service routine. The request queue
+ * provides an interface for creating and viewing requests,
+ * as well as performing operations on them.
+ * <p>
+ * @version $Revision$ $Date$
+ */
+public interface IRequestQueue {
+
+ /**
+ * Creates a new request object. A request id is
+ * assigned to it - see IRequest.getRequestId, and
+ * the status is set to RequestStatus.BEGIN
+ * <p>
+ * The request is LOCKED. The caller MUST release the
+ * request object by calling releaseRequest().
+ * <p>
+ * TODO: provide other required values (such as type
+ * and sourceId)
+ *
+ * @param requestType request type
+ * @return new request
+ * @exception EBaseException failed to create new request
+ */
+ public IRequest newRequest(String requestType)
+ throws EBaseException;
+
+ /**
+ * Clones a request object. A new request id is assigned
+ * and all attributes of the request is copied to cloned request,
+ * except for the sourceID of the original request
+ * (remote authority's request Id).
+ * <p>
+ * The cloned request that is returned is LOCKED. The caller MUST
+ * release the request object by calling releaseRequest().
+ *
+ * @param r request to be cloned
+ * @return cloned request
+ * @exception EBaseException failed to clone request
+ */
+ public IRequest cloneRequest(IRequest r)
+ throws EBaseException;
+
+ /**
+ * Gets the Request corresponding to id.
+ * Returns null if the id does not correspond
+ * to a valid request id.
+ * <p>
+ * Errors may be generated for other conditions.
+ *
+ * @param id request id
+ * @return found request
+ * @exception EBaseException failed to access request queue
+ */
+ public IRequest findRequest(RequestId id)
+ throws EBaseException;
+
+ /**
+ * Begins processing for this request. This call
+ * is valid only on requests with status BEGIN
+ * An error is generated for other cases.
+ *
+ * @param req request to be processed
+ * @exception EBaseException failed to process request
+ */
+ public void processRequest(IRequest req)
+ throws EBaseException;
+
+ /**
+ * Sets request scheduler.
+ *
+ * @param scheduler request scheduler
+ */
+ public void setRequestScheduler(IRequestScheduler scheduler);
+
+ /**
+ * Gets request scheduler.
+ *
+ * @return request scheduler
+ */
+ public IRequestScheduler getRequestScheduler();
+
+ /**
+ * Puts a new request into the PENDING state. This call is
+ * only valid for requests with status BEGIN. An error is
+ * generated for other cases.
+ * <p>
+ * This call might be used by agent servlets that want to
+ * copy a previous request, and resubmit it. By putting it
+ * into PENDING state, the normal agent screens can be used
+ * for further processing.
+ *
+ * @param req
+ * the request to mark PENDING
+ * @exception EBaseException failed to mark request as pending
+ */
+ public void markRequestPending(IRequest req)
+ throws EBaseException;
+
+ /**
+ * Clones a request object and mark it pending. A new request id is assigned
+ * and all attributes of the request is copied to cloned request,
+ * except for the sourceID of the original request
+ * (remote authority's request Id).
+ * <p>
+ * The cloned request that is returned is LOCKED. The caller MUST
+ * release the request object by calling releaseRequest().
+ *
+ * @param r request to be cloned
+ * @return cloned request mark PENDING
+ * @exception EBaseException failed to clone or mark request
+ */
+ public IRequest cloneAndMarkPending(IRequest r)
+ throws EBaseException;
+
+ /**
+ * Approves a request. The request must be locked.
+ * <p>
+ * This call will fail if:
+ * the request is not in PENDING state
+ * the policy modules do not accept the request
+ * <p>
+ * If the policy modules reject the request, then the request
+ * will remain in the PENDING state. Messages from the policy
+ * module can be display to the agent to indicate the source
+ * of the problem.
+ * <p>
+ * The request processing code adds an AgentApproval to this
+ * request that contains the authentication id of the agent. This
+ * data is retrieved from the Session object (qv).
+ *
+ * @param request
+ * the request that is being approved
+ * @exception EBaseException failed to approve request
+ */
+ public void approveRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Rejects a request. The request must be locked.
+ * <p>
+ * This call will fail if:
+ * the request is not in PENDING state
+ * <p>
+ * The agent servlet (or other application) may wish to store
+ * AgentMessage values to indicate the reason for the action
+ *
+ * @param request
+ * the request that is being rejected
+ * @exception EBaseException failed to reject request
+ */
+ public void rejectRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Cancels a request. The request must be locked.
+ * <p>
+ * This call will fail if:
+ * the request is not in PENDING state
+ * <p>
+ * The agent servlet (or other application) may wish to store
+ * AgentMessage values to indicate the reason for the action
+ *
+ * @param request
+ * the request that is being canceled
+ * @exception EBaseException failed to cancel request
+ */
+ public void cancelRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Updates the request in the permanent data store.
+ * <p>
+ * This call can be made after changing a value like source
+ * id or owner, to force the new value to be written.
+ * <p>
+ * The request must be locked to make this call.
+ *
+ * @param request
+ * the request that is being updated
+ * @exception EBaseException failed to update request
+ */
+ public void updateRequest(IRequest request)
+ throws EBaseException;
+
+ /**
+ * Returns an enumerator that lists all RequestIds in the
+ * queue. The caller should use the RequestIds to locate
+ * each request by calling findRequest().
+ * <p>
+ * NOTE: This interface will not be useful for large databases.
+ * This needs to be replace by a VLV (paged) search object.
+ *
+ * @return request list
+ */
+ public IRequestList listRequests();
+
+ /**
+ * Returns an enumerator that lists all RequestIds for requests
+ * that are in the given status. For example, all the PENDING
+ * requests could be listed by specifying RequestStatus.PENDING
+ * as the <i>status</i> argument
+ * <p>
+ * NOTE: This interface will not be useful for large databases.
+ * This needs to be replace by a VLV (paged) search object.
+ *
+ * @param status request status
+ * @return request list
+ */
+ public IRequestList listRequestsByStatus(RequestStatus status);
+
+ /**
+ * Returns an enumerator that lists all RequestIds for requests
+ * that match the filter.
+ * <p>
+ * NOTE: This interface will not be useful for large databases.
+ * This needs to be replace by a VLV (paged) search object.
+ *
+ * @param filter search filter
+ * @return request list
+ */
+ public IRequestList listRequestsByFilter(String filter);
+
+ /**
+ * Returns an enumerator that lists all RequestIds for requests
+ * that match the filter.
+ * <p>
+ * NOTE: This interface will not be useful for large databases.
+ * This needs to be replace by a VLV (paged) search object.
+ *
+ * @param filter search filter
+ * @param maxSize max size to return
+ * @return request list
+ */
+ public IRequestList listRequestsByFilter(String filter, int maxSize);
+
+ /**
+ * Returns an enumerator that lists all RequestIds for requests
+ * that match the filter.
+ * <p>
+ * NOTE: This interface will not be useful for large databases.
+ * This needs to be replace by a VLV (paged) search object.
+ *
+ * @param filter search filter
+ * @param maxSize max size to return
+ * @param timeLimit timeout value for the search
+ * @return request list
+ */
+ public IRequestList listRequestsByFilter(String filter, int maxSize, int timeLimit);
+
+ /**
+ * Gets requests that are pending on handling by the service
+ * <p>
+ * @return list of pending requests
+ */
+ // public IRequestList listServicePendingRequests();
+
+ /**
+ * Locates a request from the SourceId.
+ *
+ * @param id
+ * a unique identifier for the record that is based on the source
+ * of the request, and possibly an identify assigned by the source.
+ * @return
+ * The requestid corresponding to this source id. null is
+ * returned if the source id does not exist.
+ */
+ public RequestId findRequestBySourceId(String id);
+
+ /**
+ * Locates all requests with a particular SourceId.
+ * <p>
+ * @param id
+ * an identifier for the record that is based on the source
+ * of the request
+ * @return
+ * A list of requests corresponding to this source id. null is
+ * returned if the source id does not exist.
+ */
+ public IRequestList findRequestsBySourceId(String id);
+
+ /**
+ * Releases the LOCK on a request obtained from findRequest() or
+ * newRequest()
+ * <p>
+ * @param r request
+ */
+ public void releaseRequest(IRequest r);
+
+ /**
+ * Marks as serviced after destination authority has serviced request.
+ * Used by connector.
+ *
+ * @param r request
+ */
+ public void markAsServiced(IRequest r);
+
+ /**
+ * Resends requests
+ */
+ public void recover();
+
+ /**
+ * Gets a pageable list of IRequest entries in this queue.
+ *
+ * @param pageSize page size
+ * @return request list
+ */
+ public IRequestVirtualList getPagedRequests(int pageSize);
+
+ /**
+ * Gets a pageable list of IRequest entries in this queue.
+ *
+ * @param filter search filter
+ * @param pageSize page size
+ * @param sortKey the attributes to sort by
+ * @return request list
+ */
+ public IRequestVirtualList getPagedRequestsByFilter(String filter,
+ int pageSize,
+ String sortKey);
+ /**
+ * Gets a pageable list of IRequest entries in this queue.
+ *
+ * @param fromId request id to start with
+ * @param filter search filter
+ * @param pageSize page size
+ * @param sortKey the attributes to sort by
+ * @return request list
+ */
+ public IRequestVirtualList getPagedRequestsByFilter(RequestId fromId,
+ String filter,
+ int pageSize,
+ String sortKey);
+
+ /**
+ * Gets a pageable list of IRequest entries in this queue. This
+ * jumps right to the end of the list
+ *
+ * @param fromId request id to start with
+ * @param jumpToEnd jump to end of list (set fromId to null)
+ * @param filter search filter
+ * @param pageSize page size
+ * @param sortKey the attributes to sort by
+ * @return request list
+ */
+ public IRequestVirtualList getPagedRequestsByFilter(RequestId fromId,
+ boolean jumpToEnd, String filter,
+ int pageSize,
+ String sortKey);
+
+
+ /**
+ * Retrieves the notifier for pending request.
+ *
+ * @return notifier for pending request
+ */
+ public INotify getPendingNotify();
+
+
+ public BigInteger getLastRequestIdInRange(BigInteger reqId_low_bound, BigInteger reqId_upper_bound);
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException;
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException;
+
+ /**
+ * Gets request repository.
+ *
+ * @return request repository
+ */
+ public IRepository getRequestRepository();
+
+ public String getPublishingStatus();
+
+ public void setPublishingStatus(String status);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestRecord.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestRecord.java
new file mode 100644
index 000000000..a04c6b342
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestRecord.java
@@ -0,0 +1,113 @@
+// --- 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.certsrv.request;
+
+
+import java.util.Enumeration;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.request.RequestId;
+
+
+/**
+ * A request record is the stored version of a request.
+ * It has a set of attributes that are mapped into LDAP
+ * attributes for actual directory operations.
+ * <p>
+ * @version $Revision$ $Date$
+ */
+public interface IRequestRecord
+ extends IDBObj {
+ //
+ // The names of the attributes stored in this record
+ //
+
+ // RequestId - identifies the record
+ public final static String ATTR_REQUEST_ID = "requestId";
+
+ // RequestStatus - indicates the current state
+ public final static String ATTR_REQUEST_STATE = "requestState";
+
+ // CreateTime - indicates the current state
+ public final static String ATTR_CREATE_TIME = "requestCreateTime";
+
+ // ModifyTime - indicates the current state
+ public final static String ATTR_MODIFY_TIME = "requestModifyTime";
+
+ // SourceId - indicates the current state
+ public final static String ATTR_SOURCE_ID = "requestSourceId";
+
+ // SourceId - indicates the current state
+ public final static String ATTR_REQUEST_OWNER = "requestOwner";
+
+ public final static String ATTR_REQUEST_TYPE = "requestType";
+
+ // Placeholder for ExtAttr data. this attribute is not in LDAP, but
+ // is used to trigger the ExtAttrDynMapper during conversion between LDAP
+ // and the RequestRecord.
+ public final static String ATTR_EXT_DATA = "requestExtData";
+
+ /**
+ * Gets the request id.
+ *
+ * @return request id
+ */
+ public RequestId getRequestId();
+
+ /**
+ * Gets attribute names of the request.
+ *
+ * @return list of attribute names
+ */
+ public Enumeration getAttrNames();
+
+ /**
+ * Gets the request attribute value by the name.
+ *
+ * @param name attribute name
+ * @return attribute value
+ */
+ public Object get(String name);
+
+ /**
+ * Sets new attribute for the request.
+ *
+ * @param name attribute name
+ * @param o attribute value
+ */
+ public void set(String name, Object o);
+
+ /**
+ * Removes attribute from the request.
+ *
+ * @param name attribute name
+ */
+ public void delete(String name)
+ throws EBaseException;
+
+ /**
+ * Gets attribute list of the request.
+ *
+ * @return attribute list
+ */
+ public Enumeration getElements();
+
+ // IDBObj.getSerializableAttrNames
+ //public Enumeration getSerializableAttrNames();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java
new file mode 100644
index 000000000..ecb2e0fa3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java
@@ -0,0 +1,53 @@
+// --- 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.certsrv.request;
+
+
+//import java.io.Serializable;
+
+import java.util.Date;
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IAttrSet;
+
+
+/**
+ * This is an interface to a request scheduler that prioritizes
+ * the threads based on the request processing order.
+ * The request that enters the request queue first should
+ * be processed first.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface IRequestScheduler {
+
+ /**
+ * Request entered the request queue processing.
+ *
+ * @param r request
+ */
+ public void requestIn(IRequest r);
+
+ /**
+ * Request exited the request queue processing.
+ *
+ * @param r request
+ */
+ public void requestOut(IRequest r);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java
new file mode 100644
index 000000000..c32c66985
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java
@@ -0,0 +1,105 @@
+// --- 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.certsrv.request;
+
+
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * This interface defines storage of request objects
+ * in the local database.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public interface IRequestSubsystem {
+ public static final String SUB_ID = "request";
+
+ /**
+ * Creates a new request queue.
+ * (Currently unimplemented. Just use getRequestQueue to create
+ * an in-memory queue.)
+ * <p>
+ * @param name The name of the queue object. This name can be used
+ * in getRequestQueue to retrieve the queue later.
+ * @exception EBaseException failed to create request queue
+ */
+ public void createRequestQueue(String name)
+ throws EBaseException;
+
+ /**
+ * Retrieves a request queue. This operation should only be done
+ * once on each queue. For example, the RA subsystem should retrieve
+ * its queue, and store it somewhere for use by related services, and
+ * servlets.
+ * <p>
+ * WARNING: retrieving the same queue twice with result in multi-thread
+ * race conditions.
+ * <p>
+ * @param name
+ * the name of the request queue. (Ex: "ca" "ra")
+ * @param p
+ * A policy enforcement module. This object is called to make
+ * adjustments to the request, and decide whether it needs agent
+ * approval.
+ * @param s
+ * The service object. This object actually performs the request
+ * after it is finalized and approved.
+ * @param n
+ * A notifier object (optional). The notify() method of this object
+ * is invoked when the request is completed (COMPLETE, REJECTED or
+ * CANCELED states).
+ * @exception EBaseException failed to retrieve request queue
+ */
+ public IRequestQueue
+ getRequestQueue(String name, int increment, IPolicy p, IService s, INotify n)
+ throws EBaseException;
+
+ /**
+ * Retrieves a request queue. This operation should only be done
+ * once on each queue. For example, the RA subsystem should retrieve
+ * its queue, and store it somewhere for use by related services, and
+ * servlets.
+ * <p>
+ * WARNING: retrieving the same queue twice with result in multi-thread
+ * race conditions.
+ * <p>
+ * @param name
+ * the name of the request queue. (Ex: "ca" "ra")
+ * @param p
+ * A policy enforcement module. This object is called to make
+ * adjustments to the request, and decide whether it needs agent
+ * approval.
+ * @param s
+ * The service object. This object actually performs the request
+ * after it is finalized and approved.
+ * @param n
+ * A notifier object (optional). The notify() method of this object
+ * is invoked when the request is completed (COMPLETE, REJECTED or
+ * CANCELED states).
+ * @param pendingNotifier
+ * A notifier object (optional). Like the 'n' argument, except the
+ * notification happens if the request is made PENDING. May be the
+ * same as the 'n' argument if desired.
+ * @exception EBaseException failed to retrieve request queue
+ */
+ public IRequestQueue
+ getRequestQueue(String name, int increment, IPolicy p, IService s, INotify n,
+ INotify pendingNotifier)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java
new file mode 100644
index 000000000..4d877a775
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * This interface defines access to request virtual list.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public interface IRequestVirtualList {
+
+ /**
+ * Gets the total size of the result set. Elements of the
+ * list are numbered from 0..(size-1)
+ *
+ * @return size of the result set
+ */
+ int getSize();
+
+ /**
+ * Gets the element at the specified index
+ *
+ * @param index index of the element
+ * @return specified request
+ */
+ IRequest getElementAt(int index);
+
+ /**
+ * Gets the current index
+ *
+ * @return current index
+ */
+ int getCurrentIndex();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IService.java b/pki/base/common/src/com/netscape/certsrv/request/IService.java
new file mode 100644
index 000000000..aeaf757a6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/IService.java
@@ -0,0 +1,48 @@
+// --- 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.certsrv.request;
+
+
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * This interface defines how requests are serviced.
+ * This covers certificate generation, revocation, renewals,
+ * revocation checking, and much more.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public interface IService {
+
+ /**
+ * Performs the service (such as certificate generation)
+ * represented by this request.
+ * <p>
+ * @param request
+ * The request that needs service. The service may use
+ * attributes stored in the request, and may update the
+ * values, or store new ones.
+ * @return
+ * an indication of whether this request is still pending.
+ * 'false' means the request will wait for further notification.
+ * @exception EBaseException indicates major processing failure.
+ */
+ boolean serviceRequest(IRequest request)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/PolicyMessage.java b/pki/base/common/src/com/netscape/certsrv/request/PolicyMessage.java
new file mode 100644
index 000000000..6c750903d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/PolicyMessage.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.request;
+
+
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * A (localizable) message recorded by a policy module that describes
+ * the reason for rejecting a request.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public class PolicyMessage
+ extends EBaseException {
+
+ /**
+ * Class constructor that registers policy message.
+ * <p>
+ * @param message message string
+ */
+ public PolicyMessage(String message) {
+ super(message);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/PolicyResult.java b/pki/base/common/src/com/netscape/certsrv/request/PolicyResult.java
new file mode 100644
index 000000000..2750e3d82
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/PolicyResult.java
@@ -0,0 +1,36 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * This class defines results for policy actions.
+ *
+ * @version $Revision$, $Date$
+ */
+public final class PolicyResult {
+ public final static PolicyResult REJECTED = new PolicyResult();
+ public final static PolicyResult DEFERRED = new PolicyResult();
+ public final static PolicyResult ACCEPTED = new PolicyResult();
+
+ /**
+ * Class constructor.
+ */
+ private PolicyResult() {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/RequestId.java b/pki/base/common/src/com/netscape/certsrv/request/RequestId.java
new file mode 100644
index 000000000..01bd65d3b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/RequestId.java
@@ -0,0 +1,72 @@
+// --- 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.certsrv.request;
+
+
+/**
+ * The RequestId class represents the identifier for a particular
+ * request within a request queue. This identifier may be used to
+ * retrieve the request object itself from the request queue.
+ * <p>
+ * @version $Revision$ $Date$
+ */
+public final class RequestId {
+
+ /**
+ * Creates a new RequestId from its string representation.
+ * <p>
+ * @param id
+ * a string containing the decimal (base 10) value for the identifier.
+ */
+ public RequestId(String id) {
+ mString = id;
+ }
+
+ /**
+ * Converts the RequestId into its string representation. The string
+ * form can be stored in a database (such as the LDAP directory)
+ * <p>
+ * @return
+ * a string containing the decimal (base 10) value for the identifier.
+ */
+ public String toString() {
+ return mString;
+ }
+
+ /**
+ * Implements Object.hashCode.
+ * <p>
+ * @return hash code of the object
+ */
+ public int hashCode() {
+ return mString.hashCode();
+ }
+
+ /**
+ * Implements Object.equals.
+ * <p>
+ * @param obj object to compare
+ * @return true if objects are equal
+ */
+ public boolean equals(Object obj) {
+ return mString.equals(obj);
+ }
+
+ // instance variables
+ private final String mString;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/RequestStatus.java b/pki/base/common/src/com/netscape/certsrv/request/RequestStatus.java
new file mode 100644
index 000000000..ad3b91e78
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/RequestStatus.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.request;
+
+
+/**
+ * The RequestStatus class represents the current state of a request
+ * in a request queue. The state of the request changes as actions
+ * are performed on it.
+ *
+ * The request is created in the BEGIN state, then general progresses
+ * through the PENDING, APPROVED, SVC_PENDING, and COMPLETE states.
+ * Some requests may bypass the PENDING state if no agent action is
+ * required.
+ *
+ * Requests may be CANCELED (not implemented) or REJECTED. These are
+ * error conditions, and usually result because the request was invalid
+ * or was not approved by an agent.
+ *
+ * @version $Revision$ $Date$
+ */
+public final class RequestStatus {
+ public static String BEGIN_STRING = "begin";
+ public static String PENDING_STRING = "pending";
+ public static String APPROVED_STRING = "approved";
+ public static String SVC_PENDING_STRING = "svc_pending";
+ public static String CANCELED_STRING = "canceled";
+ public static String REJECTED_STRING = "rejected";
+ public static String COMPLETE_STRING = "complete";
+
+ /**
+ * The initial state of a request. Requests in this state have not
+ * been review by policy.
+ *
+ * While in this state the source of the request (usually the servlet,
+ * but it could be some other protocol module, such as email)
+ * should populate the request with data need to service it.
+ */
+ public static RequestStatus BEGIN = new RequestStatus(BEGIN_STRING);
+
+ /**
+ * The state of a request that is waiting for action by an agent.
+ * When the agent approves or rejects the request, process will
+ * continue as appropriate.
+ *
+ * In this state there may be PolicyMessages present that indicate
+ * the reason for the pending status.
+ */
+ public static RequestStatus PENDING = new RequestStatus(PENDING_STRING);
+
+ /**
+ * The state of a request that has been approved by an agent, or
+ * automatically by the policy engine, but have not been successfully
+ * transmitted to the service module.
+ *
+ * These requests are resent to the service during the recovery
+ * process that runs at server startup.
+ */
+ public static RequestStatus APPROVED = new RequestStatus(APPROVED_STRING);
+
+ /**
+ * The state of a request that has been sent to the service, but
+ * has not been fully processed. The service will invoke the
+ * serviceComplete() method to cause processing to continue.
+ */
+ public static RequestStatus SVC_PENDING =
+ new RequestStatus(SVC_PENDING_STRING);
+
+ /**
+ * Not implemented. This is intended to be a final state that is
+ * reached when a request is removed from the processing queue without
+ * normal notification occurring. (see REJECTED)
+ */
+ public static RequestStatus CANCELED = new RequestStatus(CANCELED_STRING);
+
+ /**
+ * The state of a request after it is rejected. When a request is
+ * rejected, the notifier is called prior to making the finl status
+ * change.
+ *
+ * Rejected requests may have PolicyMessages indicating the reason for
+ * the rejection, or AgentMessages, which allow the agent to give
+ * reasons for the action.
+ */
+ public static RequestStatus REJECTED = new RequestStatus(REJECTED_STRING);
+
+ /**
+ * The normal final state of a request. The completion status attribute
+ * gives other information about the request. The request is not
+ * necessarily successful, but may indicated that service processing
+ * did not succeed.
+ */
+ public static RequestStatus COMPLETE = new RequestStatus(COMPLETE_STRING);
+
+ /**
+ * Converts a string name for a request status into the
+ * request status enum object.
+ * <p>
+ * @param s
+ * The string representation of the state.
+ * @return
+ * request status
+ */
+ public static RequestStatus fromString(String s) {
+ if (s.equals(BEGIN_STRING)) return BEGIN;
+ if (s.equals(PENDING_STRING)) return PENDING;
+ if (s.equals(APPROVED_STRING)) return APPROVED;
+ if (s.equals(SVC_PENDING_STRING)) return SVC_PENDING;
+ if (s.equals(CANCELED_STRING)) return CANCELED;
+ if (s.equals(REJECTED_STRING)) return REJECTED;
+ if (s.equals(COMPLETE_STRING)) return COMPLETE;
+
+ return null;
+ }
+
+ /**
+ * Returns the string form of the RequestStatus, which may be used
+ * to record the status in a database.
+ *
+ * @return request status
+ */
+ public String toString() {
+ return mString;
+ }
+
+ /**
+ * Class constructor. Creates request status from the string.
+ *
+ * @param string string describing request status
+ */
+ private RequestStatus(String string) {
+ mString = string;
+ }
+
+ private String mString;
+
+ /**
+ * Compares request status with specified string.
+ *
+ * @param string string describing request status
+ */
+ public boolean equals(String string) {
+ if (string.equals(mString)) return true;
+ else return false;
+ }
+
+ /**
+ * Compares current request status with request status.
+ *
+ * @param rs request status
+ */
+ public boolean equals(RequestStatus rs) {
+ if (mString.equals(rs.mString)) return true;
+ else return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java b/pki/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java
new file mode 100644
index 000000000..17367befd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java
@@ -0,0 +1,56 @@
+// --- 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.certsrv.request.ldap;
+
+import java.util.Date;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * This interface defines how to update request record.
+ * <p>
+ * @version $Revision$, $Date$
+ */
+public interface IRequestMod
+{
+ /**
+ * Modifies request status.
+ *
+ * @param r request
+ * @param s request status
+ */
+ void modRequestStatus(IRequest r, RequestStatus s);
+
+ /**
+ * Modifies request creation time.
+ *
+ * @param r request
+ * @param d date
+ */
+ void modCreationTime(IRequest r, Date d);
+
+ /**
+ * Modifies request modification time.
+ *
+ * @param r request
+ * @param d date
+ */
+ void modModificationTime(IRequest r, Date d);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/Credential.java b/pki/base/common/src/com/netscape/certsrv/security/Credential.java
new file mode 100644
index 000000000..3b50d3294
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/Credential.java
@@ -0,0 +1,61 @@
+// --- 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.certsrv.security;
+
+
+/**
+ * A class represents a credential. A credential contains
+ * information that identifies a user. In this case,
+ * identifier and password are used.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Credential implements java.io.Serializable {
+
+ private String mId = null;
+ private String mPassword = null;
+
+ /**
+ * Constructs credential object.
+ *
+ * @param id user id
+ * @param password user password
+ */
+ public Credential(String id, String password) {
+ mId = id;
+ mPassword = password;
+ }
+
+ /**
+ * Retrieves identifier.
+ *
+ * @return user id
+ */
+ public String getIdentifier() {
+ return mId;
+ }
+
+ /**
+ * Retrieves password.
+ *
+ * @return user password
+ */
+ public String getPassword() {
+ return mPassword;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java b/pki/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java
new file mode 100644
index 000000000..2e4c0a9ee
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java
@@ -0,0 +1,462 @@
+// --- 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.certsrv.security;
+
+
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.CryptoManager.*;
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * This interface represents the cryptographics subsystem
+ * that provides all the security related functions.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICryptoSubsystem extends ISubsystem {
+
+ public static final String ID = "jss";
+
+ /**
+ * Retrieves a list of nicknames of certificates that are
+ * in the installed tokens.
+ *
+ * @return a list of comma-separated nicknames
+ * @exception EBaseException failed to retrieve nicknames
+ */
+ public String getAllCerts() throws EBaseException;
+
+ /**
+ * Retrieves certificate in pretty-print format by the nickname.
+ *
+ * @param nickname nickname of certificate
+ * @param date not after of the returned certificate must be date
+ * @param locale user locale
+ * @return certificate in pretty-print format
+ * @exception EBaseException failed to retrieve certificate
+ */
+ public String getCertPrettyPrint(String nickname, String date,
+ Locale locale) throws EBaseException;
+ public String getRootCertTrustBit(String nickname, String serialno,
+ String issuerName) throws EBaseException;
+ public String getCertPrettyPrint(String nickname, String serialno,
+ String issuername, Locale locale) throws EBaseException;
+ public String getCertPrettyPrintAndFingerPrint(String nickname, String serialno,
+ String issuername, Locale locale) throws EBaseException;
+
+ /**
+ * Retrieves the certificate in the pretty print format.
+ *
+ * @param b64E certificate in mime-64 encoded format
+ * @param locale end user locale
+ * @return certificate in pretty-print format
+ * @exception EBaseException failed to retrieve certificate
+ */
+ public String getCertPrettyPrint(String b64E, Locale locale)
+ throws EBaseException;
+
+ /**
+ * Imports certificate into the server.
+ *
+ * @param b64E certificate in mime-64 encoded format
+ * @param nickname nickname for the importing certificate
+ * @param certType certificate type
+ * @exception EBaseException failed to import certificate
+ */
+ public void importCert(String b64E, String nickname, String certType)
+ throws EBaseException;
+
+ /**
+ * Imports certificate into the server.
+ *
+ * @param signedCert certificate
+ * @param nickname nickname for the importing certificate
+ * @param certType certificate type
+ * @exception EBaseException failed to import certificate
+ */
+ public void importCert(X509CertImpl signedCert, String nickname,
+ String certType) throws EBaseException;
+
+ /**
+ * Generates a key pair based on the given parameters.
+ *
+ * @param properties key parameters
+ * @return key pair
+ * @exception EBaseException failed to generate key pair
+ */
+ public KeyPair getKeyPair(KeyCertData properties) throws EBaseException;
+
+ /**
+ * Retrieves the key pair based on the given nickname.
+ *
+ * @param nickname nickname of the public key
+ * @exception EBaseException failed to retrieve key pair
+ */
+ public KeyPair getKeyPair(String nickname) throws EBaseException;
+
+ /**
+ * Generates a key pair based on the given parameters.
+ *
+ * @param tokenName name of token where key is generated
+ * @param alg key algorithm
+ * @param keySize key size
+ * @return key pair
+ * @exception EBaseException failed to generate key pair
+ */
+ public KeyPair getKeyPair(String tokenName, String alg,
+ int keySize) throws EBaseException;
+
+ /**
+ * Generates a key pair based on the given parameters.
+ *
+ * @param tokenName name of token where key is generated
+ * @param alg key algorithm
+ * @param keySize key size
+ * @param pqg pqg parameters if DSA key, otherwise null
+ * @return key pair
+ * @exception EBaseException failed to generate key pair
+ */
+ public KeyPair getKeyPair(String tokenName, String alg,
+ int keySize, PQGParams pqg) throws EBaseException;
+
+ /**
+ * Generates an ECC key pair based on the given parameters.
+ *
+ * @param properties key parameters
+ * @return key pair
+ * @exception EBaseException failed to generate key pair
+ */
+ public KeyPair getECCKeyPair(KeyCertData properties) throws EBaseException;
+
+ /**
+ * Generates an ECC key pair based on the given parameters.
+ *
+ * @param token token name
+ * @param curveName curve name
+ * @param certType type of cert(sslserver etc..)
+ * @return key pair
+ * @exception EBaseException failed to generate key pair
+ */
+ public KeyPair getECCKeyPair(String token, String curveName, String certType) throws EBaseException;
+
+ /**
+ * Retrieves the signature algorithm of the certificate named
+ * by the given nickname.
+ *
+ * @param nickname nickname of the certificate
+ * @return signature algorithm
+ * @exception EBaseException failed to retrieve signature
+ */
+ public String getSignatureAlgorithm(String nickname) throws EBaseException;
+
+ /**
+ * Checks if the given dn is a valid distinguished name.
+ *
+ * @param dn distinguished name
+ * @exception EBaseException failed to check
+ */
+ public void isX500DN(String dn) throws EBaseException;
+
+ /**
+ * Retrieves CA's signing algorithm id. If it is DSA algorithm,
+ * algorithm is constructed by reading the parameters
+ * ca.dsaP, ca.dsaQ, ca.dsaG.
+ *
+ * @param algname DSA or RSA
+ * @param store configuration store.
+ * @return algorithm id
+ * @exception EBaseException failed to retrieve algorithm id
+ */
+ public AlgorithmId getAlgorithmId(String algname, IConfigStore store) throws EBaseException;
+
+ /**
+ * Retrieves subject name of the certificate that is identified by
+ * the given nickname.
+ *
+ * @param tokenname name of token where the nickname is valid
+ * @param nickname nickname of the certificate
+ * @return subject name
+ * @exception EBaseException failed to get subject name
+ */
+ public String getCertSubjectName(String tokenname, String nickname)
+ throws EBaseException;
+
+ /**
+ * Retrieves extensions of the certificate that is identified by
+ * the given nickname.
+ *
+ * @param tokenname name of token where the nickname is valid
+ * @param nickname nickname of the certificate
+ * @return certificate extensions
+ * @exception EBaseException failed to get extensions
+ */
+ public CertificateExtensions getExtensions(String tokenname, String nickname
+ )
+ throws EBaseException;
+
+ /**
+ * Deletes certificate of the given nickname.
+ *
+ * @param nickname nickname of the certificate
+ * @param pathname path where a copy of the deleted certificate is stored
+ * @exception EBaseException failed to delete certificate
+ */
+ public void deleteTokenCertificate(String nickname, String pathname)
+ throws EBaseException;
+
+ /**
+ * Delete certificate of the given nickname.
+ *
+ * @param nickname nickname of the certificate
+ * @param notAfterTime The notAfter of the certificate. It
+ * is possible to ge t multiple certificates under
+ * the same nickname. If one of the certificates match
+ * the notAfterTime, then the certificate will get
+ * deleted. The format of the notAfterTime has to be
+ * in "MMMMM dd, yyyy HH:mm:ss" format.
+ * @exception EBaseException failed to delete certificate
+ */
+ public void deleteCert(String nickname, String notAfterTime)
+ throws EBaseException;
+
+ /**
+ * Retrieves the subject DN of the certificate identified by
+ * the nickname.
+ *
+ * @param nickname nickname of the certificate
+ * @return subject distinguished name
+ * @exception EBaseException failed to retrieve subject DN
+ */
+ public String getSubjectDN(String nickname) throws EBaseException;
+
+ /**
+ * Trusts a certificate for all available purposes.
+ *
+ * @param nickname nickname of the certificate
+ * @param date certificate's not before
+ * @param trust "Trust" or other
+ * @exception EBaseException failed to trust certificate
+ */
+ public void trustCert(String nickname, String date, String trust)
+ throws EBaseException;
+
+ /**
+ * Checks if the given base-64 encoded string contains an extension
+ * or a sequence of extensions.
+ *
+ * @param ext extension or sequence of extension encoded in base-64
+ * @exception EBaseException failed to check encoding
+ */
+ public void checkCertificateExt(String ext) throws EBaseException;
+
+ /**
+ * Gets all certificates on all tokens for Certificate Database Management.
+ *
+ * @return all certificates
+ * @exception EBaseException failed to retrieve certificates
+ */
+ public NameValuePairs getAllCertsManage() throws EBaseException;
+ public NameValuePairs getUserCerts() throws EBaseException;
+
+ /**
+ * Gets all CA certificates on all tokens.
+ *
+ * @return all CA certificates
+ * @exception EBaseException failed to retrieve certificates
+ */
+ public NameValuePairs getCACerts() throws EBaseException;
+
+ public NameValuePairs getRootCerts() throws EBaseException;
+
+ public void setRootCertTrust(String nickname, String serialno,
+ String issuername, String trust) throws EBaseException;
+
+ public void deleteRootCert(String nickname, String serialno,
+ String issuername) throws EBaseException;
+
+ public void deleteUserCert(String nickname, String serialno,
+ String issuername) throws EBaseException;
+
+ /**
+ * Retrieves PQG parameters based on key size.
+ *
+ * @param keysize key size
+ * @return pqg parameters
+ */
+ public PQGParams getPQG(int keysize);
+
+ /**
+ * Retrieves PQG parameters based on key size.
+ *
+ * @param keysize key size
+ * @param store configuration store
+ * @return pqg parameters
+ */
+ public PQGParams getCAPQG(int keysize, IConfigStore store)
+ throws EBaseException;
+
+ /**
+ * Retrieves extensions of the certificate that is identified by
+ * the given nickname.
+ *
+ * @param tokenname token name
+ * @param nickname nickname
+ * @return certificate extensions
+ */
+ public CertificateExtensions getCertExtensions(String tokenname, String nickname
+ )
+ throws NotInitializedException, TokenException, ObjectNotFoundException,
+
+ IOException, CertificateException;
+
+ /**
+ * Checks if the given token is logged in.
+ *
+ * @param name token name
+ * @return true if token is logged in
+ * @exception EBaseException failed to login
+ */
+ public boolean isTokenLoggedIn(String name) throws EBaseException;
+
+ /**
+ * Logs into token.
+ *
+ * @param tokenName name of the token
+ * @param pwd token password
+ * @exception EBaseException failed to login
+ */
+ public void loggedInToken(String tokenName, String pwd)
+ throws EBaseException;
+
+ /**
+ * Generates certificate request from the given key pair.
+ *
+ * @param subjectName subject name to use in the request
+ * @param kp key pair that contains public key material
+ * @return certificate request in base-64 encoded format
+ * @exception EBaseException failed to generate request
+ */
+ public String getCertRequest(String subjectName, KeyPair kp)
+ throws EBaseException;
+
+ /**
+ * Checks if fortezza is enabled.
+ *
+ * @return "true" if fortezza is enabled
+ */
+ public String isCipherFortezza() throws EBaseException;
+
+ /**
+ * Retrieves the SSL cipher version.
+ *
+ * @return cipher version (i.e. "cipherdomestic")
+ */
+ public String getCipherVersion() throws EBaseException;
+
+ /**
+ * Retrieves the cipher preferences.
+ *
+ * @return cipher preferences (i.e. "rc4export,rc2export,...")
+ */
+ public String getCipherPreferences() throws EBaseException;
+
+ /**
+ * Sets the current SSL cipher preferences.
+ *
+ * @param cipherPrefs cipher preferences (i.e. "rc4export,rc2export,...")
+ * @exception EBaseException failed to set cipher preferences
+ */
+ public void setCipherPreferences(String cipherPrefs)
+ throws EBaseException;
+
+ /**
+ * Retrieves a list of currently registered token names.
+ *
+ * @return list of token names
+ * @exception EBaseException failed to retrieve token list
+ */
+ public String getTokenList() throws EBaseException;
+
+ /**
+ * Retrieves all certificates. The result list will not
+ * contain the token tag.
+ *
+ * @param name token name
+ * @return list of certificates without token tag
+ * @exception EBaseException failed to retrieve
+ */
+ public String getCertListWithoutTokenName(String name) throws EBaseException;
+
+ /**
+ * Retrieves the token name of the internal (software) token.
+ *
+ * @return the token name
+ * @exception EBaseException failed to retrieve token name
+ */
+ public String getInternalTokenName() throws EBaseException;
+
+ /**
+ * Checks to see if the certificate of the given nickname is a
+ * CA certificate.
+ *
+ * @param fullNickname nickname of the certificate to check
+ * @return true if it is a CA certificate
+ * @exception EBaseException failed to check
+ */
+ public boolean isCACert(String fullNickname) throws EBaseException;
+
+ /**
+ * Adds the specified number of bits of entropy from the system
+ * entropy generator to the RNG of the default PKCS#11 RNG token.
+ * The default token is set using the modutil command.
+ * Note that the system entropy generator (usually /dev/random)
+ * will block until sufficient entropy is collected.
+ *
+ * @param bits number of bits of entropy
+ * @exception org.mozilla.jss.util.NotImplementedException If the Crypto device does not support
+ * adding entropy
+ * @exception TokenException If there was some other problem with the Crypto device
+ * @exception IOException If there was a problem reading from the /dev/random
+ */
+
+ public void addEntropy(int bits)
+ throws org.mozilla.jss.util.NotImplementedException,
+ IOException,
+ TokenException;
+
+ /**
+ * Signs the certificate template into the given data and returns
+ * a signed certificate.
+ *
+ * @param data data that contains certificate template
+ * @param certType certificate type
+ * @param priKey CA signing key
+ * @return certificate
+ * @exception EBaseException failed to sign certificate template
+ */
+ public X509CertImpl getSignedCert(KeyCertData data, String certType, java.security.PrivateKey priKey) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java b/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
new file mode 100644
index 000000000..af7030f06
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
@@ -0,0 +1,130 @@
+// --- 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.certsrv.security;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.crypto.PrivateKey;
+
+
+/**
+ * An interface represents a encryption unit.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IEncryptionUnit extends IToken {
+
+ /**
+ * Retrieves the public key in this unit.
+ *
+ * @return public key
+ */
+ public PublicKey getPublicKey();
+
+ /**
+ * Wraps data. The given key will be wrapped by the
+ * private key in this unit.
+ *
+ * @param priKey private key to be wrapped
+ * @return wrapped data
+ * @exception EBaseException failed to wrap
+ */
+ public byte[] wrap(PrivateKey priKey) throws EBaseException;
+
+ /**
+ * Verifies the given key pair.
+ *
+ * @param publicKey public key
+ * @param privateKey private key
+ */
+ public void verify(PublicKey publicKey, PrivateKey privateKey) throws
+ EBaseException;
+
+ /**
+ * Unwraps data. This method rebuilds the private key by
+ * unwrapping the private key data.
+ *
+ * @param sessionKey session key that unwrap the private key
+ * @param symmAlgOID symmetric algorithm
+ * @param symmAlgParams symmetric algorithm parameters
+ * @param privateKey private key data
+ * @param pubKey public key
+ * @return private key object
+ * @exception EBaseException failed to unwrap
+ */
+ public PrivateKey unwrap(byte sessionKey[], String symmAlgOID,
+ byte symmAlgParams[], byte privateKey[],
+ PublicKey pubKey)
+ throws EBaseException;
+
+ /**
+ * Unwraps data. This method rebuilds the private key by
+ * unwrapping the private key data.
+ *
+ * @param privateKey private key data
+ * @param pubKey public key object
+ * @return private key object
+ * @exception EBaseException failed to unwrap
+ */
+ public PrivateKey unwrap(byte privateKey[], PublicKey pubKey)
+ throws EBaseException;
+
+ /**
+ * Encrypts the internal private key (private key to the KRA's
+ * internal storage).
+ *
+ * @param rawPrivate user's private key (key to be archived)
+ * @return encrypted data
+ * @exception EBaseException failed to encrypt
+ */
+ public byte[] encryptInternalPrivate(byte rawPrivate[])
+ throws EBaseException;
+
+ /**
+ * Decrypts the internal private key (private key from the KRA's
+ * internal storage).
+ *
+ * @param wrappedPrivateData unwrapped private key data (key to be recovered)
+ * @return raw private key
+ * @exception EBaseException failed to decrypt
+ */
+ public byte[] decryptInternalPrivate(byte wrappedPrivateData[])
+ throws EBaseException;
+
+ /**
+ * Decrypts the external private key (private key from the end-user).
+ *
+ * @param sessionKey session key that protects the user private
+ * @param symmAlgOID symmetric algorithm
+ * @param symmAlgParams symmetric algorithm parameters
+ * @param privateKey private key data
+ * @return private key data
+ * @exception EBaseException failed to decrypt
+ */
+ public byte[] decryptExternalPrivate(byte sessionKey[],
+ String symmAlgOID,
+ byte symmAlgParams[], byte privateKey[])
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/ISigningUnit.java b/pki/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
new file mode 100644
index 000000000..ac46a271d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
@@ -0,0 +1,165 @@
+// --- 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.certsrv.security;
+
+
+import java.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.Signature;
+import com.netscape.certsrv.base.*;
+import netscape.security.x509.*;
+
+/**
+ * A class represents the signing unit which is
+ * capable of signing data.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISigningUnit {
+
+ public static final String PROP_DEFAULT_SIGNALG = "defaultSigningAlgorithm";
+ public static final String PROP_CERT_NICKNAME = "cacertnickname";
+ // This signing unit is being used in OCSP and CRL also. So
+ // it is better to have a more generic name
+ public static final String PROP_RENAMED_CERT_NICKNAME = "certnickname";
+ public static final String PROP_TOKEN_NAME = "tokenname";
+ public static final String PROP_NEW_NICKNAME = "newNickname";
+
+ /**
+ * Retrieves the nickname of the signing certificate.
+ */
+ public String getNickname();
+
+ /**
+ * Retrieves the new nickname in the renewal process.
+ *
+ * @return new nickname
+ * @exception EBaseException failed to get new nickname
+ */
+ public String getNewNickName() throws EBaseException;
+
+ /**
+ * Sets new nickname of the signing certificate.
+ *
+ * @param name nickname
+ */
+ public void setNewNickName(String name);
+
+ /**
+ * Retrieves the signing certificate.
+ *
+ * @return signing certificate
+ */
+ public X509Certificate getCert();
+
+ /**
+ * Retrieves the signing certificate.
+ *
+ * @return signing certificate
+ */
+ public X509CertImpl getCertImpl();
+
+ /**
+ * Signs the given data in specific algorithm.
+ *
+ * @param data data to be signed
+ * @param algname signing algorithm to be used
+ * @return signed data
+ * @exception EBaseException failed to sign
+ */
+ public byte[] sign(byte[] data, String algname)
+ throws EBaseException;
+
+ /**
+ * Verifies the signed data.
+ *
+ * @param data signed data
+ * @param signature signature
+ * @param algname signing algorithm
+ * @return true if verification is good
+ * @exception EBaseException failed to verify
+ */
+ public boolean verify(byte[] data, byte[] signature, String algname)
+ throws EBaseException;
+
+ /**
+ * Retrieves the default algorithm.
+ *
+ * @return default signing algorithm
+ */
+ public SignatureAlgorithm getDefaultSignatureAlgorithm();
+
+ /**
+ * Retrieves the default algorithm name.
+ *
+ * @return default signing algorithm name
+ */
+ public String getDefaultAlgorithm();
+
+ /**
+ * Set default signing algorithm.
+ *
+ * @param algorithm signing algorithm
+ * @exception EBaseException failed to set default signing algorithm
+ */
+ public void setDefaultAlgorithm(String algorithm) throws EBaseException;
+
+ /**
+ * Retrieves all supported signing algorithm of this unit.
+ *
+ * @return a list of signing algorithms
+ * @exception EBaseException failed to list
+ */
+ public String[] getAllAlgorithms() throws EBaseException;
+
+ /**
+ * Retrieves the token name of this unit.
+ *
+ * @return token name
+ * @exception EBaseException failed to retrieve name
+ */
+ public String getTokenName() throws EBaseException;
+
+ /**
+ * Updates new nickname and tokename in the configuration file.
+ *
+ * @param nickname new nickname
+ * @param tokenname new tokenname
+ */
+ public void updateConfig(String nickname, String tokenname);
+
+ /**
+ * Checks if the given algorithm name is supported.
+ *
+ * @param algname algorithm name
+ * @return signing algorithm
+ * @exception EBaseException failed to check signing algorithm
+ */
+ public SignatureAlgorithm checkSigningAlgorithmFromName(String algname)
+ throws EBaseException;
+
+ /**
+ * Retrieves the public key associated in this unit.
+ *
+ * @return public key
+ */
+ public PublicKey getPublicKey();
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java b/pki/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
new file mode 100644
index 000000000..0b484bdc7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
@@ -0,0 +1,106 @@
+// --- 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.certsrv.security;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.PrivateKey;
+
+
+/**
+ * An interface represents a storage key unit. This storage
+ * unit contains a storage key pair that is used for
+ * encrypting the user private key for long term storage.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IStorageKeyUnit extends IEncryptionUnit {
+
+ /**
+ * Retrieves total number of recovery agents.
+ *
+ * @return total number of recovery agents
+ */
+ public int getNoOfAgents() throws EBaseException;
+
+ /**
+ * Retrieves number of recovery agents required to
+ * perform recovery operation.
+ *
+ * @return required number of recovery agents for recovery operation
+ */
+ public int getNoOfRequiredAgents() throws EBaseException;
+
+ /**
+ * Sets the numer of required recovery agents
+ *
+ * @param number number of required agents
+ */
+ public void setNoOfRequiredAgents(int number);
+
+ /**
+ * Retrieves a list of agents in this unit.
+ *
+ * @return a list of string-based agent identifiers
+ */
+ public Enumeration getAgentIdentifiers();
+
+ /**
+ * Changes agent password.
+ *
+ * @param id agent id
+ * @param oldpwd old password
+ * @param newpwd new password
+ * @return true if operation successful
+ * @exception EBaseException failed to change password
+ */
+ public boolean changeAgentPassword(String id, String oldpwd,
+ String newpwd) throws EBaseException;
+
+ /**
+ * Changes M-N recovery scheme.
+ *
+ * @param n total number of agents
+ * @param m required number of agents for recovery operation
+ * @param oldcreds all old credentials
+ * @param newcreds all new credentials
+ * @return true if operation successful
+ * @exception EBaseException failed to change schema
+ */
+ public boolean changeAgentMN(int n, int m, Credential oldcreds[],
+ Credential newcreds[]) throws EBaseException;
+
+ /**
+ * Logins to this unit.
+ *
+ * @param ac agent's credentials
+ * @exception EBaseException failed to login
+ */
+ public void login(Credential ac[]) throws EBaseException;
+
+ public CryptoToken getToken();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/IToken.java b/pki/base/common/src/com/netscape/certsrv/security/IToken.java
new file mode 100644
index 000000000..4211806fc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/IToken.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.security;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * An interface represents a generic token unit.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IToken {
+
+ /**
+ * Logins to the token unit.
+ *
+ * @param pin password to access the token
+ * @exception EBaseException failed to login to this token
+ */
+ public void login(String pin) throws EBaseException;
+
+ /**
+ * Logouts token.
+ */
+ public void logout();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java b/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java
new file mode 100644
index 000000000..1ad0e378c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java
@@ -0,0 +1,55 @@
+// --- 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.certsrv.security;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.PrivateKey;
+
+
+/**
+ * An interface represents the transport key pair.
+ * This key pair is used to protected EE's private
+ * key in transit.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ITransportKeyUnit extends IEncryptionUnit {
+
+ /**
+ * Retrieves public key.
+ *
+ * @return certificate
+ */
+ public org.mozilla.jss.crypto.X509Certificate getCertificate();
+ public SymmetricKey unwrap_sym(byte encSymmKey[]);
+ public SymmetricKey unwrap_encrypt_sym(byte encSymmKey[]);
+ public PrivateKey unwrap_temp(byte wrappedKeyData[], PublicKey
+ pubKey) throws EBaseException;
+ public CryptoToken getToken();
+ public String getSigningAlgorithm() throws EBaseException;
+ public void setSigningAlgorithm(String str) throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/security/KeyCertData.java b/pki/base/common/src/com/netscape/certsrv/security/KeyCertData.java
new file mode 100644
index 000000000..87dd298f7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/security/KeyCertData.java
@@ -0,0 +1,813 @@
+// --- 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.certsrv.security;
+
+
+import java.util.*;
+import java.security.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import org.mozilla.jss.crypto.*;
+import netscape.security.x509.*;
+
+/**
+ * This class represents a container for storaging
+ * data in the security package.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyCertData extends Properties {
+
+ /**
+ * Constructs a key certificate data.
+ */
+ public KeyCertData() {
+ super();
+ }
+
+ /**
+ * Retrieves the key pair from this container.
+ *
+ * @return key pair
+ */
+ public KeyPair getKeyPair() {
+ return (KeyPair) get("keypair");
+ }
+
+ /**
+ * Sets key pair into this container.
+ *
+ * @param keypair key pair
+ */
+ public void setKeyPair(KeyPair keypair) {
+ put("keypair", keypair);
+ }
+
+ /**
+ * Retrieves the issuer name from this container.
+ *
+ * @return issuer name
+ */
+ public String getIssuerName() {
+ return (String) get(Constants.PR_ISSUER_NAME);
+ }
+
+ /**
+ * Sets the issuer name in this container.
+ *
+ * @param name issuer name
+ */
+ public void setIssuerName(String name) {
+ put(Constants.PR_ISSUER_NAME, name);
+ }
+
+ /**
+ * Retrieves certificate server instance name.
+ *
+ * @return instance name
+ */
+ public String getCertInstanceName() {
+ return (String) get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+ }
+
+ /**
+ * Sets certificate server instance name.
+ *
+ * @param name instance name
+ */
+ public void setCertInstanceName(String name) {
+ put(ConfigConstants.PR_CERT_INSTANCE_NAME, name);
+ }
+
+ /**
+ * Retrieves certificate nickname.
+ *
+ * @return certificate nickname
+ */
+ public String getCertNickname() {
+ return (String) get(Constants.PR_NICKNAME);
+ }
+
+ /**
+ * Sets certificate nickname.
+ *
+ * @param nickname certificate nickname
+ */
+ public void setCertNickname(String nickname) {
+ put(Constants.PR_NICKNAME, nickname);
+ }
+
+ /**
+ * Retrieves key length.
+ *
+ * @return key length
+ */
+ public String getKeyLength() {
+ return (String) get(Constants.PR_KEY_LENGTH);
+ }
+
+ /**
+ * Sets key length.
+ *
+ * @param len key length
+ */
+ public void setKeyLength(String len) {
+ put(Constants.PR_KEY_LENGTH, len);
+ }
+
+ /**
+ * Retrieves key type.
+ *
+ * @return key type
+ */
+ public String getKeyType() {
+ return (String) get(Constants.PR_KEY_TYPE);
+ }
+
+ /**
+ * Sets key type.
+ *
+ * @param type key type
+ */
+ public void setKeyType(String type) {
+ put(Constants.PR_KEY_TYPE, type);
+ }
+
+ /**
+ * Retrieves key curve name.
+ *
+ * @return key curve name
+ */
+ public String getKeyCurveName() {
+ return (String) get(Constants.PR_KEY_CURVENAME);
+ }
+
+ /**
+ * Sets key curvename.
+ *
+ * @param len key curvename
+ */
+ public void setKeyCurveName(String len) {
+ put(Constants.PR_KEY_CURVENAME, len);
+ }
+
+ /**
+ * Retrieves signature algorithm.
+ *
+ * @return signature algorithm
+ */
+ public SignatureAlgorithm getSignatureAlgorithm() {
+ return (SignatureAlgorithm) get(Constants.PR_SIGNATURE_ALGORITHM);
+ }
+
+ /**
+ * Sets signature algorithm
+ *
+ * @param alg signature algorithm
+ */
+ public void setSignatureAlgorithm(SignatureAlgorithm alg) {
+ put(Constants.PR_SIGNATURE_ALGORITHM, alg);
+ }
+
+ /**
+ * Retrieves algorithm used to sign the root CA Cert.
+ *
+ * @return signature algorithm
+ */
+ public String getSignedBy() {
+ return (String) get(Constants.PR_SIGNEDBY_TYPE);
+ }
+
+ /**
+ * Sets signature algorithm used to sign root CA cert
+ *
+ * @param alg signature algorithm
+ */
+ public void setSignedBy(String alg) {
+ put(Constants.PR_SIGNEDBY_TYPE, alg);
+ }
+
+ /**
+ * Retrieves signature algorithm.
+ *
+ * @return signature algorithm
+ */
+ public AlgorithmId getAlgorithmId() {
+ return (AlgorithmId) get(Constants.PR_ALGORITHM_ID);
+ }
+
+ /**
+ * Sets algorithm identifier
+ *
+ * @param id signature algorithm
+ */
+ public void setAlgorithmId(AlgorithmId id) {
+ put(Constants.PR_ALGORITHM_ID, id);
+ }
+
+ /**
+ * Retrieves serial number.
+ *
+ * @return serial number
+ */
+ public BigInteger getSerialNumber() {
+ return (BigInteger) get("serialno");
+ }
+
+ /**
+ * Sets serial number.
+ *
+ * @param num serial number
+ */
+ public void setSerialNumber(BigInteger num) {
+ put("serialno", num);
+ }
+
+ /**
+ * Retrieves configuration file.
+ *
+ * @return configuration file
+ */
+ public IConfigStore getConfigFile() {
+ return (IConfigStore)(get("cmsFile"));
+ }
+
+ /**
+ * Sets configuration file.
+ *
+ * @param file configuration file
+ */
+ public void setConfigFile(IConfigStore file) {
+ put("cmsFile", file);
+ }
+
+ /**
+ * Retrieves begining year of validity.
+ *
+ * @return begining year
+ */
+ public String getBeginYear() {
+ return (String) get(Constants.PR_BEGIN_YEAR);
+ }
+
+ /**
+ * Sets begining year of validity.
+ *
+ * @param year begining year
+ */
+ public void setBeginYear(String year) {
+ put(Constants.PR_BEGIN_YEAR, year);
+ }
+
+ /**
+ * Retrieves ending year of validity.
+ *
+ * @return ending year
+ */
+ public String getAfterYear() {
+ return (String) get(Constants.PR_AFTER_YEAR);
+ }
+
+ /**
+ * Sets ending year of validity.
+ *
+ * @param year ending year
+ */
+ public void setAfterYear(String year) {
+ put(Constants.PR_AFTER_YEAR, year);
+ }
+
+ /**
+ * Retrieves begining month of validity.
+ *
+ * @return begining month
+ */
+ public String getBeginMonth() {
+ return (String) get(Constants.PR_BEGIN_MONTH);
+ }
+
+ /**
+ * Sets begining month of validity.
+ *
+ * @param month begining month
+ */
+ public void setBeginMonth(String month) {
+ put(Constants.PR_BEGIN_MONTH, month);
+ }
+
+ /**
+ * Retrieves ending month of validity.
+ *
+ * @return ending month
+ */
+ public String getAfterMonth() {
+ return (String) get(Constants.PR_AFTER_MONTH);
+ }
+
+ /**
+ * Sets ending month of validity.
+ *
+ * @param month ending month
+ */
+ public void setAfterMonth(String month) {
+ put(Constants.PR_AFTER_MONTH, month);
+ }
+
+ /**
+ * Retrieves begining date of validity.
+ *
+ * @return begining date
+ */
+ public String getBeginDate() {
+ return (String) get(Constants.PR_BEGIN_DATE);
+ }
+
+ /**
+ * Sets begining date of validity.
+ *
+ * @param date begining date
+ */
+ public void setBeginDate(String date) {
+ put(Constants.PR_BEGIN_DATE, date);
+ }
+
+ /**
+ * Retrieves ending date of validity.
+ *
+ * @return ending date
+ */
+ public String getAfterDate() {
+ return (String) get(Constants.PR_AFTER_DATE);
+ }
+
+ /**
+ * Sets ending date of validity.
+ *
+ * @param date ending date
+ */
+ public void setAfterDate(String date) {
+ put(Constants.PR_AFTER_DATE, date);
+ }
+
+ /**
+ * Retrieves starting hour of validity.
+ *
+ * @return starting hour
+ */
+ public String getBeginHour() {
+ return (String) get(Constants.PR_BEGIN_HOUR);
+ }
+
+ /**
+ * Sets starting hour of validity.
+ *
+ * @param hour starting hour
+ */
+ public void setBeginHour(String hour) {
+ put(Constants.PR_BEGIN_HOUR, hour);
+ }
+
+ /**
+ * Retrieves ending hour of validity.
+ *
+ * @return ending hour
+ */
+ public String getAfterHour() {
+ return (String) get(Constants.PR_AFTER_HOUR);
+ }
+
+ /**
+ * Sets ending hour of validity.
+ *
+ * @param hour ending hour
+ */
+ public void setAfterHour(String hour) {
+ put(Constants.PR_AFTER_HOUR, hour);
+ }
+
+ /**
+ * Retrieves starting minute of validity.
+ *
+ * @return starting minute
+ */
+ public String getBeginMin() {
+ return (String) get(Constants.PR_BEGIN_MIN);
+ }
+
+ /**
+ * Sets starting minute of validity.
+ *
+ * @param min starting minute
+ */
+ public void setBeginMin(String min) {
+ put(Constants.PR_BEGIN_MIN, min);
+ }
+
+ /**
+ * Retrieves ending minute of validity.
+ *
+ * @return ending minute
+ */
+ public String getAfterMin() {
+ return (String) get(Constants.PR_AFTER_MIN);
+ }
+
+ /**
+ * Sets ending minute of validity.
+ *
+ * @param min ending minute
+ */
+ public void setAfterMin(String min) {
+ put(Constants.PR_AFTER_MIN, min);
+ }
+
+ /**
+ * Retrieves starting second of validity.
+ *
+ * @return starting second
+ */
+ public String getBeginSec() {
+ return (String) get(Constants.PR_BEGIN_SEC);
+ }
+
+ /**
+ * Sets starting second of validity.
+ *
+ * @param sec starting second
+ */
+ public void setBeginSec(String sec) {
+ put(Constants.PR_BEGIN_SEC, sec);
+ }
+
+ /**
+ * Retrieves ending second of validity.
+ *
+ * @return ending second
+ */
+ public String getAfterSec() {
+ return (String) get(Constants.PR_AFTER_SEC);
+ }
+
+ /**
+ * Sets ending second of validity.
+ *
+ * @param sec ending second
+ */
+ public void setAfterSec(String sec) {
+ put(Constants.PR_AFTER_SEC, sec);
+ }
+
+ /**
+ * Retrieves CA key pair
+ *
+ * @return CA key pair
+ */
+ public KeyPair getCAKeyPair() {
+ return (KeyPair) get(Constants.PR_CA_KEYPAIR);
+ }
+
+ /**
+ * Sets CA key pair
+ *
+ * @param keypair key pair
+ */
+ public void setCAKeyPair(KeyPair keypair) {
+ put(Constants.PR_CA_KEYPAIR, keypair);
+ }
+
+ /**
+ * Retrieves extensions
+ *
+ * @return extensions
+ */
+ public String getDerExtension() {
+ return (String) get(Constants.PR_DER_EXTENSION);
+ }
+
+ /**
+ * Sets extensions
+ *
+ * @param ext extensions
+ */
+ public void setDerExtension(String ext) {
+ put(Constants.PR_DER_EXTENSION, ext);
+ }
+
+ /**
+ * Retrieves isCA
+ *
+ * @return "true" if it is CA
+ */
+ public String isCA() {
+ return (String) get(Constants.PR_IS_CA);
+ }
+
+ /**
+ * Sets isCA
+ *
+ * @param ext "true" if it is CA
+ */
+ public void setCA(String ext) {
+ put(Constants.PR_IS_CA, ext);
+ }
+
+ /**
+ * Retrieves key length
+ *
+ * @return certificate's key length
+ */
+ public String getCertLen() {
+ return (String) get(Constants.PR_CERT_LEN);
+ }
+
+ /**
+ * Sets key length
+ *
+ * @param len certificate's key length
+ */
+ public void setCertLen(String len) {
+ put(Constants.PR_CERT_LEN, len);
+ }
+
+ /**
+ * Retrieves SSL Client bit
+ *
+ * @return SSL Client bit
+ */
+ public String getSSLClientBit() {
+ return (String) get(Constants.PR_SSL_CLIENT_BIT);
+ }
+
+ /**
+ * Sets SSL Client bit
+ *
+ * @param sslClientBit SSL Client bit
+ */
+ public void setSSLClientBit(String sslClientBit) {
+ put(Constants.PR_SSL_CLIENT_BIT, sslClientBit);
+ }
+
+ /**
+ * Retrieves SSL Server bit
+ *
+ * @return SSL Server bit
+ */
+ public String getSSLServerBit() {
+ return (String) get(Constants.PR_SSL_SERVER_BIT);
+ }
+
+ /**
+ * Sets SSL Server bit
+ *
+ * @param sslServerBit SSL Server bit
+ */
+ public void setSSLServerBit(String sslServerBit) {
+ put(Constants.PR_SSL_SERVER_BIT, sslServerBit);
+ }
+
+ /**
+ * Retrieves SSL Mail bit
+ *
+ * @return SSL Mail bit
+ */
+ public String getSSLMailBit() {
+ return (String) get(Constants.PR_SSL_MAIL_BIT);
+ }
+
+ /**
+ * Sets SSL Mail bit
+ *
+ * @param sslMailBit SSL Mail bit
+ */
+ public void setSSLMailBit(String sslMailBit) {
+ put(Constants.PR_SSL_MAIL_BIT, sslMailBit);
+ }
+
+ /**
+ * Retrieves SSL CA bit
+ *
+ * @return SSL CA bit
+ */
+ public String getSSLCABit() {
+ return (String) get(Constants.PR_SSL_CA_BIT);
+ }
+
+ /**
+ * Sets SSL CA bit
+ *
+ * @param cabit SSL CA bit
+ */
+ public void setSSLCABit(String cabit) {
+ put(Constants.PR_SSL_CA_BIT, cabit);
+ }
+
+ /**
+ * Retrieves SSL Signing bit
+ *
+ * @return SSL Signing bit
+ */
+ public String getObjectSigningBit() {
+ return (String) get(Constants.PR_OBJECT_SIGNING_BIT);
+ }
+
+ /**
+ * Retrieves Time Stamping bit
+ *
+ * @return Time Stamping bit
+ */
+ public String getTimeStampingBit() {
+ return (String) get(Constants.PR_TIMESTAMPING_BIT);
+ }
+
+ /**
+ * Sets SSL Signing bit
+ *
+ * @param objectSigningBit SSL Signing bit
+ */
+ public void setObjectSigningBit(String objectSigningBit) {
+ put(Constants.PR_OBJECT_SIGNING_BIT, objectSigningBit);
+ }
+
+ /**
+ * Retrieves SSL Mail CA bit
+ *
+ * @return SSL Mail CA bit
+ */
+ public String getMailCABit() {
+ return (String) get(Constants.PR_MAIL_CA_BIT);
+ }
+
+ /**
+ * Sets SSL Mail CA bit
+ *
+ * @param mailCABit SSL Mail CA bit
+ */
+ public void setMailCABit(String mailCABit) {
+ put(Constants.PR_MAIL_CA_BIT, mailCABit);
+ }
+
+ /**
+ * Retrieves SSL Object Signing bit
+ *
+ * @return SSL Object Signing bit
+ */
+ public String getObjectSigningCABit() {
+ return (String) get(Constants.PR_OBJECT_SIGNING_CA_BIT);
+ }
+
+ /**
+ * Sets SSL Object Signing bit
+ *
+ * @param bit SSL Object Signing bit
+ */
+ public void setObjectSigningCABit(String bit) {
+ put(Constants.PR_OBJECT_SIGNING_CA_BIT, bit);
+ }
+
+ /**
+ * Retrieves OCSP Signing flag
+ *
+ * @return OCSP Signing flag
+ */
+ public String getOCSPSigning() {
+ return (String) get(Constants.PR_OCSP_SIGNING);
+ }
+
+ /**
+ * Sets OCSP Signing flag
+ *
+ * @param aki OCSP Signing flag
+ */
+ public void setOCSPSigning(String aki) {
+ put(Constants.PR_OCSP_SIGNING, aki);
+ }
+
+ /**
+ * Retrieves OCSP No Check flag
+ *
+ * @return OCSP No Check flag
+ */
+ public String getOCSPNoCheck() {
+ return (String) get(Constants.PR_OCSP_NOCHECK);
+ }
+
+ /**
+ * Sets OCSP No Check flag
+ *
+ * @param noCheck OCSP No Check flag
+ */
+ public void setOCSPNoCheck(String noCheck) {
+ put(Constants.PR_OCSP_NOCHECK, noCheck);
+ }
+
+ /**
+ * Retrieves Authority Information Access flag
+ *
+ * @return Authority Information Access flag
+ */
+ public String getAIA() {
+ return (String) get(Constants.PR_AIA);
+ }
+
+ /**
+ * Sets Authority Information Access flag
+ *
+ * @param aia Authority Information Access flag
+ */
+ public void setAIA(String aia) {
+ put(Constants.PR_AIA, aia);
+ }
+
+ /**
+ * Retrieves Authority Key Identifier flag
+ *
+ * @return Authority Key Identifier flag
+ */
+ public String getAKI() {
+ return (String) get(Constants.PR_AKI);
+ }
+
+ /**
+ * Sets Authority Key Identifier flag
+ *
+ * @param aki Authority Key Identifier flag
+ */
+ public void setAKI(String aki) {
+ put(Constants.PR_AKI, aki);
+ }
+
+ /**
+ * Retrieves Subject Key Identifier flag
+ *
+ * @return Subject Key Identifier flag
+ */
+ public String getSKI() {
+ return (String) get(Constants.PR_SKI);
+ }
+
+ /**
+ * Sets Subject Key Identifier flag
+ *
+ * @param ski Subject Key Identifier flag
+ */
+ public void setSKI(String ski) {
+ put(Constants.PR_SKI, ski);
+ }
+
+ /**
+ * Retrieves key usage extension
+ *
+ * @return true if key usage extension set
+ */
+ public boolean getKeyUsageExtension() {
+ String str = (String) get(Constants.PR_KEY_USAGE);
+
+ if (str == null || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ /**
+ * Sets CA extensions
+ *
+ * @param ext CA extensions
+ */
+ public void setCAExtensions(CertificateExtensions ext) {
+ put("CAEXTENSIONS", ext);
+ }
+
+ /**
+ * Retrieves CA extensions
+ *
+ * @return CA extensions
+ */
+ public CertificateExtensions getCAExtensions() {
+ return (CertificateExtensions) get("CAEXTENSIONS");
+ }
+
+ /**
+ * Retrieves hash type
+ *
+ * @return hash type
+ */
+ public String getHashType() {
+ return (String) get(ConfigConstants.PR_HASH_TYPE);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java b/pki/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java
new file mode 100644
index 000000000..697646493
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java
@@ -0,0 +1,225 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a duplicate self test exception.
+ * EDuplicateSelfTestExceptions are derived from ESelfTestExceptions
+ * in order to allow users to easily do self tests without try-catch clauses.
+ *
+ * EDuplicateSelfTestExceptions should be caught by SelfTestSubsystem managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDuplicateSelfTestException
+ extends ESelfTestException {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////
+ // helper parameters //
+ ///////////////////////
+
+ private String mInstanceName = null;
+ private String mInstanceStore = null;
+ private String mInstanceParameter = null;
+ private String mInstanceValue = null;
+
+ ////////////////////////////////////////////
+ // EDuplicateSelfTestException parameters //
+ ////////////////////////////////////////////
+
+
+
+ ///////////////////////////////////////////////
+ // ESelfTestException parameters (inherited) //
+ ///////////////////////////////////////////////
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Constructs a "duplicate" self test exception.
+ * <P>
+ *
+ * @param instanceName duplicate "instanceName" exception details
+ */
+ public EDuplicateSelfTestException(String instanceName) {
+ super("The self test plugin property named "
+ + instanceName
+ + " already exists.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ }
+
+ /**
+ * Constructs a "duplicate" self test exception where the value is always
+ * a duplicate from a name/value pair
+ * <P>
+ *
+ * @param instanceName duplicate "instanceName" exception details
+ * @param instanceValue duplicate "instanceValue" exception details
+ */
+ public EDuplicateSelfTestException(String instanceName,
+ String instanceValue) {
+ super("The self test plugin property named "
+ + instanceName
+ + " contains a value of "
+ + instanceValue
+ + " which already exists.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ mInstanceValue = instanceValue;
+ }
+
+ /**
+ * Constructs a "duplicate" self test exception where the parameter is a
+ * duplicate from a substore.parameter/value pair; (the value passed in may
+ * be null).
+ * <P>
+ *
+ * @param instanceStore duplicate "instanceStore" exception details
+ * @param instanceParameter duplicate "instanceParameter" exception details
+ * @param instanceValue duplicate "instanceValue" exception details
+ * (may be null)
+ */
+ public EDuplicateSelfTestException(String instanceStore,
+ String instanceParameter,
+ String instanceValue) {
+ super("The self test plugin property named "
+ + instanceStore + "." + instanceParameter
+ + " is a duplicate.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceStore != null) {
+ instanceStore = instanceStore.trim();
+ }
+ if (instanceParameter != null) {
+ instanceParameter = instanceParameter.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceStore = instanceStore;
+ mInstanceParameter = instanceParameter;
+ mInstanceValue = instanceValue;
+ }
+
+ ////////////////////
+ // helper methods //
+ ////////////////////
+
+ /**
+ * Returns the instance name associated with this self test.
+ * <P>
+ *
+ * @return name portion of the name/value pair
+ */
+ public String getInstanceName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the store associated with this self test.
+ * <P>
+ *
+ * @return substore portion of the substore.parameter/value pair
+ */
+ public String getInstanceStore() {
+ return mInstanceStore;
+ }
+
+ /**
+ * Returns the parameter associated with this self test.
+ * <P>
+ *
+ * @return parameter portion of the substore.parameter/value pair
+ */
+ public String getInstanceParameter() {
+ return mInstanceParameter;
+ }
+
+ /**
+ * Returns the value associated with this self test.
+ * <P>
+ *
+ * @return value portion of the name/value pair
+ */
+ public String getInstanceValue() {
+ return mInstanceValue;
+ }
+
+ /////////////////////////////////////////
+ // EDuplicateSelfTestException methods //
+ /////////////////////////////////////////
+
+
+
+ ////////////////////////////////////////////
+ // ESelfTestException methods (inherited) //
+ ////////////////////////////////////////////
+
+ /* Note that all of the following ESelfTestException methods
+ * are inherited from the ESelfTestException class:
+ *
+ * public ESelfTestException( String msg );
+ */
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java b/pki/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java
new file mode 100644
index 000000000..b38b574cf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java
@@ -0,0 +1,225 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements an invalid self test exception.
+ * EInvalidSelfTestExceptions are derived from ESelfTestExceptions
+ * in order to allow users to easily do self tests without try-catch clauses.
+ *
+ * EInvalidSelfTestExceptions should be caught by SelfTestSubsystem managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EInvalidSelfTestException
+ extends ESelfTestException {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////
+ // helper parameters //
+ ///////////////////////
+
+ private String mInstanceName = null;
+ private String mInstanceStore = null;
+ private String mInstanceParameter = null;
+ private String mInstanceValue = null;
+
+ //////////////////////////////////////////
+ // EInvalidSelfTestException parameters //
+ //////////////////////////////////////////
+
+
+
+ ///////////////////////////////////////////////
+ // ESelfTestException parameters (inherited) //
+ ///////////////////////////////////////////////
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Constructs an "invalid" self test exception.
+ * <P>
+ *
+ * @param instanceName invalid "instanceName" exception details
+ */
+ public EInvalidSelfTestException(String instanceName) {
+ super("The self test plugin named "
+ + instanceName
+ + " is invalid.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ }
+
+ /**
+ * Constructs a "invalid" self test exception where the value is always
+ * invalid from a name/value pair
+ * <P>
+ *
+ * @param instanceName invalid "instanceName" exception details
+ * @param instanceValue invalid "instanceValue" exception details
+ */
+ public EInvalidSelfTestException(String instanceName,
+ String instanceValue) {
+ super("The self test plugin named "
+ + instanceName
+ + " contains a value "
+ + instanceValue
+ + " which is invalid.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ mInstanceValue = instanceValue;
+ }
+
+ /**
+ * Constructs an "invalid" self test exception where the parameter is always
+ * invalid from a substore.parameter/value pair; (the value passed in may
+ * be null).
+ * <P>
+ *
+ * @param instanceStore invalid "instanceStore" exception details
+ * @param instanceParameter invalid "instanceParameter" exception details
+ * @param instanceValue invalid "instanceValue" exception details
+ * (may be null)
+ */
+ public EInvalidSelfTestException(String instanceStore,
+ String instanceParameter,
+ String instanceValue) {
+ super("The self test plugin parameter named "
+ + instanceStore + "." + instanceParameter
+ + " is invalid.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceStore != null) {
+ instanceStore = instanceStore.trim();
+ }
+ if (instanceParameter != null) {
+ instanceParameter = instanceParameter.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceStore = instanceStore;
+ mInstanceParameter = instanceParameter;
+ mInstanceValue = instanceValue;
+ }
+
+ ////////////////////
+ // helper methods //
+ ////////////////////
+
+ /**
+ * Returns the instance name associated with this self test.
+ * <P>
+ *
+ * @return name portion of the name/value pair
+ */
+ public String getInstanceName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the store associated with this self test.
+ * <P>
+ *
+ * @return substore portion of the substore.parameter/value pair
+ */
+ public String getInstanceStore() {
+ return mInstanceStore;
+ }
+
+ /**
+ * Returns the parameter associated with this self test.
+ * <P>
+ *
+ * @return parameter portion of the substore.parameter/value pair
+ */
+ public String getInstanceParameter() {
+ return mInstanceParameter;
+ }
+
+ /**
+ * Returns the value associated with this self test.
+ * <P>
+ *
+ * @return value portion of the name/value pair
+ */
+ public String getInstanceValue() {
+ return mInstanceValue;
+ }
+
+ ///////////////////////////////////////
+ // EInvalidSelfTestException methods //
+ ///////////////////////////////////////
+
+
+
+ ////////////////////////////////////////////
+ // ESelfTestException methods (inherited) //
+ ////////////////////////////////////////////
+
+ /* Note that all of the following ESelfTestException methods
+ * are inherited from the ESelfTestException class:
+ *
+ * public ESelfTestException( String msg );
+ */
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java b/pki/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java
new file mode 100644
index 000000000..8c2353287
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java
@@ -0,0 +1,234 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a missing self test exception.
+ * EMissingSelfTestExceptions are derived from ESelfTestExceptions
+ * in order to allow users to easily do self tests without try-catch clauses.
+ *
+ * EMissingSelfTestExceptions should be caught by SelfTestSubsystem managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EMissingSelfTestException
+ extends ESelfTestException {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////
+ // helper parameters //
+ ///////////////////////
+
+ private String mInstanceName = null;
+ private String mInstanceStore = null;
+ private String mInstanceParameter = null;
+ private String mInstanceValue = null;
+
+ //////////////////////////////////////////
+ // EMissingSelfTestException parameters //
+ //////////////////////////////////////////
+
+
+
+ ///////////////////////////////////////////////
+ // ESelfTestException parameters (inherited) //
+ ///////////////////////////////////////////////
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Constructs a "missing" self test exception where the name is null
+ * <P>
+ *
+ */
+ public EMissingSelfTestException() {
+ super("The self test plugin property name is null.");
+ }
+
+ /**
+ * Constructs a "missing" self test exception where the name is always
+ * missing from a name/value pair.
+ * <P>
+ *
+ * @param instanceName missing "instanceName" exception details
+ */
+ public EMissingSelfTestException(String instanceName) {
+ super("The self test plugin property named "
+ + instanceName
+ + " does not exist.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ }
+
+ /**
+ * Constructs a "missing" self test exception where the value is always
+ * missing from a name/value pair; (the value passed in is always null).
+ * <P>
+ *
+ * @param instanceName missing "instanceName" exception details
+ * @param instanceValue missing "instanceValue" exception details
+ * (always null)
+ */
+ public EMissingSelfTestException(String instanceName,
+ String instanceValue) {
+ super("The self test plugin property named "
+ + instanceName
+ + " contains no values.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceName = instanceName;
+ mInstanceValue = instanceValue;
+ }
+
+ /**
+ * Constructs a "missing" self test exception where the parameter is always
+ * missing from a substore.parameter/value pair; (the value passed in may
+ * be null).
+ * <P>
+ *
+ * @param instanceStore missing "instanceStore" exception details
+ * @param instanceParameter missing "instanceParameter" exception details
+ * @param instanceValue missing "instanceValue" exception details
+ * (may be null)
+ */
+ public EMissingSelfTestException(String instanceStore,
+ String instanceParameter,
+ String instanceValue) {
+ super("The self test plugin property named "
+ + instanceStore + "." + instanceParameter
+ + " is missing.");
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceStore != null) {
+ instanceStore = instanceStore.trim();
+ }
+ if (instanceParameter != null) {
+ instanceParameter = instanceParameter.trim();
+ }
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ }
+
+ // store passed-in parameters for use by helper methods
+ mInstanceStore = instanceStore;
+ mInstanceParameter = instanceParameter;
+ mInstanceValue = instanceValue;
+ }
+
+ ////////////////////
+ // helper methods //
+ ////////////////////
+
+ /**
+ * Returns the instance name associated with this self test.
+ * <P>
+ *
+ * @return name portion of the name/value pair
+ */
+ public String getInstanceName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the store associated with this self test.
+ * <P>
+ *
+ * @return substore portion of the substore.parameter/value pair
+ */
+ public String getInstanceStore() {
+ return mInstanceStore;
+ }
+
+ /**
+ * Returns the parameter associated with this self test.
+ * <P>
+ *
+ * @return parameter portion of the substore.parameter/value pair
+ */
+ public String getInstanceParameter() {
+ return mInstanceParameter;
+ }
+
+ /**
+ * Returns the value associated with this self test.
+ * <P>
+ *
+ * @return value portion of the name/value pair
+ */
+ public String getInstanceValue() {
+ return mInstanceValue;
+ }
+
+ ///////////////////////////////////////
+ // EMissingSelfTestException methods //
+ ///////////////////////////////////////
+
+
+
+ ////////////////////////////////////////////
+ // ESelfTestException methods (inherited) //
+ ////////////////////////////////////////////
+
+ /* Note that all of the following ESelfTestException methods
+ * are inherited from the ESelfTestException class:
+ *
+ * public ESelfTestException( String msg );
+ */
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java b/pki/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java
new file mode 100644
index 000000000..2124e5d4a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java
@@ -0,0 +1,123 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test exception. ESelfTestExceptions
+ * are derived from EBaseExceptions in order to allow users
+ * to easily do self tests without try-catch clauses.
+ *
+ * ESelfTestExceptions should be caught by SelfTestSubsystem managers.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ESelfTestException
+ extends EBaseException {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////////////
+ // ESelfTestException parameters //
+ ///////////////////////////////////
+
+ private static final String SELFTEST_RESOURCES = SelfTestResources.class.getName();
+
+
+ ///////////////////////////////////////////
+ // EBaseException parameters (inherited) //
+ ///////////////////////////////////////////
+
+ /* Note that all of the following EBaseException parameters
+ * are inherited from the EBaseException class:
+ *
+ * public Object mParams[];
+ */
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Constructs a self test exception.
+ * <P>
+ *
+ * @param msg exception details
+ */
+ public ESelfTestException(String msg) {
+ super(msg);
+ }
+
+
+ ////////////////////////////////
+ // ESelfTestException methods //
+ ////////////////////////////////
+
+ /**
+ * Returns the bundle file name.
+ * <P>
+ * @return name of bundle class associated with this exception.
+ */
+ protected String getBundleName() {
+ return SELFTEST_RESOURCES;
+ }
+
+
+ ////////////////////////////////////////
+ // EBaseException methods (inherited) //
+ ////////////////////////////////////////
+
+ /* Note that all of the following EBaseException methods
+ * are inherited from the EBaseException class:
+ *
+ * public EBaseException( String msgFormat );
+ *
+ * public EBaseException( String msgFormat, String param );
+ *
+ * public EBaseException( String msgFormat, Exception param );
+ *
+ * public EBaseException( String msgFormat, Object params[] );
+ *
+ * public Object[] getParameters();
+ *
+ * public String toString();
+ *
+ * public String toString( Locale locale );
+ */
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java b/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
new file mode 100644
index 000000000..783f8955d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
@@ -0,0 +1,140 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class defines the interface of an individual self test.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISelfTest {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ //////////////////////////
+ // ISelfTest parameters //
+ //////////////////////////
+
+ public static final String PROP_PLUGIN = "plugin";
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ///////////////////////
+ // ISelfTest methods //
+ ///////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest(ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters)
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException;
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException;
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest();
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName();
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore();
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription(Locale locale);
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest(ILogEventListener logger)
+ throws ESelfTestException;
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java b/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
new file mode 100644
index 000000000..a44626b64
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
@@ -0,0 +1,358 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class defines the interface of a container for self tests.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ISelfTestSubsystem
+ extends ISubsystem {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ //////////////////////////////////
+ // ISelfTestSubsystem constants //
+ //////////////////////////////////
+
+ public static final String ID = "selftests";
+ public static final String PROP_CONTAINER = "container";
+ public static final String PROP_INSTANCE = "instance";
+ public static final String PROP_LOGGER = "logger";
+ public static final String PROP_LOGGER_CLASS = "class";
+ public static final String PROP_ORDER = "order";
+ public static final String PROP_ON_DEMAND = "onDemand";
+ public static final String PROP_STARTUP = "startup";
+
+ ///////////////////////////////////////
+ // ISubsystem parameters (inherited) //
+ ///////////////////////////////////////
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////////////
+ // ISelfTestSubsystem methods //
+ ////////////////////////////////
+
+ //
+ // methods associated with the list of on demand self tests
+ //
+
+ /**
+ * List the instance names of all the self tests enabled to run on demand
+ * (in execution order); may return null.
+ * <P>
+ *
+ * @return list of self test instance names run on demand
+ */
+ public String[] listSelfTestsEnabledOnDemand();
+
+ /**
+ * Enable the specified self test to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ // public void enableSelfTestOnDemand( String instanceName,
+ // boolean isCritical )
+ // throws EInvalidSelfTestException, EMissingSelfTestException;
+
+
+ /**
+ * Disable the specified self test from being able to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ // public void disableSelfTestOnDemand( String instanceName )
+ // throws EMissingSelfTestException;
+
+
+ /**
+ * Determine if the specified self test is enabled to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if the specified self test is enabled on demand
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestEnabledOnDemand(String instanceName)
+ throws EMissingSelfTestException;
+
+ /**
+ * Determine if failure of the specified self test is fatal when
+ * it is executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if failure of the specified self test is fatal when
+ * it is executed on demand
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestCriticalOnDemand(String instanceName)
+ throws EMissingSelfTestException;
+
+ /**
+ * Execute all self tests specified to be run on demand.
+ * <P>
+ *
+ * @exception EMissingSelfTestException subsystem has missing name
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTestsOnDemand()
+ throws EMissingSelfTestException, ESelfTestException;
+
+ //
+ // methods associated with the list of startup self tests
+ //
+
+ /**
+ * List the instance names of all the self tests enabled to run
+ * at server startup (in execution order); may return null.
+ * <P>
+ *
+ * @return list of self test instance names run at server startup
+ */
+ public String[] listSelfTestsEnabledAtStartup();
+
+ /**
+ * Enable the specified self test at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ // public void enableSelfTestAtStartup( String instanceName,
+ // boolean isCritical )
+ // throws EInvalidSelfTestException, EMissingSelfTestException;
+
+
+ /**
+ * Disable the specified self test at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ // public void disableSelfTestAtStartup( String instanceName )
+ // throws EMissingSelfTestException;
+
+
+ /**
+ * Determine if the specified self test is executed automatically
+ * at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if the specified self test is executed at server startup
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestEnabledAtStartup(String instanceName)
+ throws EMissingSelfTestException;
+
+ /**
+ * Determine if failure of the specified self test is fatal to
+ * server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if failure of the specified self test is fatal to
+ * server startup
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestCriticalAtStartup(String instanceName)
+ throws EMissingSelfTestException;
+
+ /**
+ * Execute all self tests specified to be run at server startup.
+ * <P>
+ *
+ * @exception EMissingSelfTestException subsystem has missing name
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTestsAtStartup()
+ throws EMissingSelfTestException, ESelfTestException;
+
+ //
+ // methods associated with the list of self test instances
+ //
+
+ /**
+ * Retrieve an individual self test from the instances list
+ * given its instance name.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return individual self test
+ */
+ public ISelfTest getSelfTest(String instanceName);
+
+ //
+ // methods associated with multiple self test lists
+ //
+
+ /**
+ * Returns the ILogEventListener of this subsystem.
+ * This method may return null.
+ * <P>
+ *
+ * @return ILogEventListener of this subsystem
+ */
+ public ILogEventListener getSelfTestLogger();
+
+ /**
+ * This method represents the log interface for the self test subsystem.
+ * <P>
+ *
+ * @param logger log event listener
+ * @param msg self test log message
+ */
+ public void log(ILogEventListener logger, String msg);
+
+ /**
+ * Register an individual self test on the instances list AND
+ * on the "on demand" list (note that the specified self test
+ * will be appended to the end of each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @param instance individual self test
+ * @exception EDuplicateSelfTestException subsystem has duplicate name
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ // public void registerSelfTestOnDemand( String instanceName,
+ // boolean isCritical,
+ // ISelfTest instance )
+ // throws EDuplicateSelfTestException,
+ // EInvalidSelfTestException,
+ // EMissingSelfTestException;
+
+
+ /**
+ * Deregister an individual self test on the instances list AND
+ * on the "on demand" list (note that the specified self test
+ * will be removed from each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ // public void deregisterSelfTestOnDemand( String instanceName )
+ // throws EMissingSelfTestException;
+
+
+ /**
+ * Register an individual self test on the instances list AND
+ * on the "startup" list (note that the specified self test
+ * will be appended to the end of each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @param instance individual self test
+ * @exception EDuplicateSelfTestException subsystem has duplicate name
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ // public void registerSelfTestAtStartup( String instanceName,
+ // boolean isCritical,
+ // ISelfTest instance )
+ // throws EDuplicateSelfTestException,
+ // EInvalidSelfTestException,
+ // EMissingSelfTestException;
+
+
+ /**
+ * Deregister an individual self test on the instances list AND
+ * on the "startup" list (note that the specified self test
+ * will be removed from each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ // public void deregisterSelfTestAtStartup( String instanceName )
+ // throws EMissingSelfTestException;
+
+
+
+ ////////////////////////////////////
+ // ISubsystem methods (inherited) //
+ ////////////////////////////////////
+
+ /* Note that all of the following ISubsystem methods
+ * are inherited from the ISubsystem class:
+ *
+ * public String getId();
+ *
+ * public void setId( String id )
+ * throws EBaseException;
+ *
+ * public void init( ISubsystem owner, IConfigStore config )
+ * throws EBaseException;
+ *
+ * public void startup()
+ * throws EBaseException;
+ *
+ * public void shutdown();
+ *
+ * public IConfigStore getConfigStore();
+ */
+}
+
diff --git a/pki/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java b/pki/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java
new file mode 100644
index 000000000..1c1551c5a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java
@@ -0,0 +1,41 @@
+// --- 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.certsrv.selftests;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for Self Tests.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SelfTestResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ static final Object[][] contents = {
+ };
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/template/ArgList.java b/pki/base/common/src/com/netscape/certsrv/template/ArgList.java
new file mode 100644
index 000000000..f3b955c27
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/template/ArgList.java
@@ -0,0 +1,68 @@
+// --- 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.certsrv.template;
+
+import java.util.*;
+
+/**
+ * This class represents a list of arguments
+ * that will be returned to the end-user via
+ * the template framework.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ArgList implements IArgValue {
+
+ private Vector mList = new Vector();
+
+ /**
+ * Constructs a argument list object.
+ */
+ public ArgList() {
+ }
+
+ /**
+ * Adds an argument to the list.
+ *
+ * @param arg argument to be added
+ */
+ public void add(IArgValue arg) {
+ mList.addElement(arg);
+ }
+
+ /**
+ * Returns the number of arguments in the list.
+ *
+ * @return size of the list
+ */
+ public int size() {
+ return mList.size();
+ }
+
+ /**
+ * Returns the argument at the given position
+ * Position starts from 0.
+ *
+ * @param pos position
+ * @return argument
+ */
+ public IArgValue get(int pos) {
+ return (IArgValue) mList.elementAt(pos);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/template/ArgSet.java b/pki/base/common/src/com/netscape/certsrv/template/ArgSet.java
new file mode 100644
index 000000000..ca8d866ea
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/template/ArgSet.java
@@ -0,0 +1,74 @@
+// --- 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.certsrv.template;
+
+import java.util.*;
+
+/**
+ * This class represents a set of arguments.
+ * Unlike ArgList, this set of arguments is
+ * not ordered.
+ * <p>
+ * Each argument in the set is tagged with
+ * a name (key).
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ArgSet implements IArgValue {
+ private Hashtable mArgs = new Hashtable();
+
+ /**
+ * Returns a list of argument names.
+ *
+ * @return list of argument names
+ */
+ public Enumeration getNames() {
+ return mArgs.keys();
+ }
+
+ /**
+ * Sets string argument into the set with the given name.
+ *
+ * @param name argument name
+ * @param arg argument in string
+ */
+ public void set(String name, String arg) {
+ mArgs.put(name, new ArgString (arg));
+ }
+
+ /**
+ * Sets argument into the set with the given name.
+ *
+ * @param name argument name
+ * @param arg argument value
+ */
+ public void set(String name, IArgValue arg) {
+ mArgs.put(name, arg);
+ }
+
+ /**
+ * Retrieves argument from the set.
+ *
+ * @param name argument name
+ * @return argument value
+ */
+ public IArgValue get(String name) {
+ return (IArgValue) mArgs.get(name);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/template/ArgString.java b/pki/base/common/src/com/netscape/certsrv/template/ArgString.java
new file mode 100644
index 000000000..b932a1855
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/template/ArgString.java
@@ -0,0 +1,48 @@
+// --- 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.certsrv.template;
+
+
+import java.util.*;
+
+/**
+ * This class represents a string-based argument.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ArgString implements IArgValue {
+ private String mValue = null;
+
+ /**
+ * Constructs a string-based argument value.
+ *
+ * @param value argument value
+ */
+ public ArgString(String value) {
+ mValue = value;
+ }
+
+ /**
+ * Returns the argument value.
+ *
+ * @return argument value
+ */
+ public String getValue() {
+ return mValue;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/template/IArgValue.java b/pki/base/common/src/com/netscape/certsrv/template/IArgValue.java
new file mode 100644
index 000000000..d679f0a1f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/template/IArgValue.java
@@ -0,0 +1,28 @@
+// --- 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.certsrv.template;
+
+/**
+ * This interface presents a generic argument value.
+ * Argument value can be in string, in a list, or
+ * in a set.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IArgValue {
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java b/pki/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java
new file mode 100644
index 000000000..dfaa04cc4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java
@@ -0,0 +1,71 @@
+// --- 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.certsrv.tks;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * An interface represents a Registration Authority that is
+ * responsible for certificate enrollment operations.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ITKSAuthority extends ISubsystem {
+ public static final String ID = "tks";
+
+ public static final String PROP_POLICY = "Policy";
+ public static final String PROP_REGISTRATION = "Registration";
+ public static final String PROP_GATEWAY = "gateway";
+ public static final String PROP_NICKNAME = "certNickname";
+ //public final static String PROP_PUBLISH_SUBSTORE = "publish";
+ //public final static String PROP_LDAP_PUBLISH_SUBSTORE = "ldappublish";
+ public final static String PROP_CONNECTOR = "connector";
+ public final static String PROP_NEW_NICKNAME = "newNickname";
+
+
+
+ /**
+ * Retrieves the request queue of this registration authority.
+ *
+ * @return RA's request queue
+ */
+ public IRequestQueue getRequestQueue();
+
+ /**
+ * Returns the nickname of the RA certificate.
+ *
+ * @return the nickname of the RA certificate
+ */
+ public String getNickname();
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java
new file mode 100644
index 000000000..6d8ec2b8f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.security.*;
+import java.security.cert.*;
+
+
+/**
+ * This class defines the strong authentication basic elements,
+ * the X509 certificates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Certificates {
+
+ private X509Certificate mCerts[] = null;
+
+ /**
+ * Constructs strong authenticator.
+ * @param certs a list of X509Certificates
+ */
+ public Certificates(X509Certificate certs[]) {
+ mCerts = certs;
+ }
+
+ /**
+ * Retrieves certificates.
+ * @return a list of X509Certificates
+ */
+ public X509Certificate[] getCertificates() {
+ return mCerts;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java
new file mode 100644
index 000000000..db2aca24c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java
@@ -0,0 +1,83 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a Identity exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EUsrGrpException extends EBaseException {
+
+ /**
+ * Identity resource class name.
+ */
+ private static final String USRGRP_RESOURCES = UsrGrpResources.class.getName();
+
+ /**
+ * Constructs a usr/grp management exception
+ * @param msgFormat exception details in message string format
+ * <P>
+ */
+ public EUsrGrpException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * @param msgFormat exception details in message string format
+ * @param param message string parameter
+ * <P>
+ */
+ public EUsrGrpException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * @param e system exception
+ * <P>
+ */
+ public EUsrGrpException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a Identity exception.
+ * @param msgFormat exception details in message string format
+ * @param params list of message format parameters
+ * <P>
+ */
+ public EUsrGrpException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ /**
+ * Retrieves bundle name.
+ */
+ protected String getBundleName() {
+ return USRGRP_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java
new file mode 100644
index 000000000..8644e4f6f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java
@@ -0,0 +1,49 @@
+// --- 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.certsrv.usrgrp;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * This interface defines a certificate mapping strategy to locate
+ * a user
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICertUserLocator {
+
+ /**
+ * Returns a user whose certificates match with the given certificates
+ * @return an user interface
+ * @exception EUsrGrpException thrown when failed to build user
+ * @exception LDAPException thrown when LDAP internal database is not available
+ * @exception ELdapException thrown when the LDAP search failed
+ */
+ public IUser locateUser(Certificates certs) throws
+ EUsrGrpException, LDAPException, ELdapException;
+
+ /**
+ * Retrieves description.
+ * @return description
+ */
+ public String getDescription();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java
new file mode 100644
index 000000000..3e36d9cc2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java
@@ -0,0 +1,70 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This interface defines the basic interfaces for
+ * an identity group. (get/set methods for a group entry attributes)
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IGroup extends IAttrSet, IGroupConstants {
+
+ /**
+ * Retrieves the group name.
+ * @return the group name
+ */
+ public String getName();
+
+ /**
+ * Retrieves group identifier.
+ * @return the group id
+ */
+ public String getGroupID();
+
+ /**
+ * Retrieves group description.
+ * @return description
+ */
+ public String getDescription();
+
+ /**
+ * Checks if the given name is member of this group.
+ * @param name the given name
+ * @return true if the given name is the member of this group; otherwise false.
+ */
+ public boolean isMember(String name);
+
+ /**
+ * Adds new member.
+ * @param name the given name.
+ */
+ public void addMemberName(String name);
+
+ /**
+ * Retrieves a list of member names.
+ * @return a list of member names for this group.
+ */
+ public Enumeration getMemberNames();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java
new file mode 100644
index 000000000..2f7e10a71
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java
@@ -0,0 +1,50 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.util.*;
+
+
+/**
+ * This interface defines the attribute names for a group entry
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IGroupConstants {
+
+ /**
+ * Contant for groupName
+ */
+ public static final String ATTR_NAME = "groupName";
+
+ /**
+ * Constant for dn
+ */
+ public static final String ATTR_ID = "dn";
+
+ /**
+ * Constant for description
+ */
+ public static final String ATTR_DESCRIPTION = "description";
+
+ /**
+ * Constant for uniquemember
+ */
+ public static final String ATTR_MEMBERS = "uniquemember";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java
new file mode 100644
index 000000000..b34ba8f4a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java
@@ -0,0 +1,44 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.util.*;
+import java.security.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents an ID evaluator.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IIdEvaluator {
+
+ /**
+ * Evaluates if the given value satisfies the ID evaluation:
+ * is a user a member of a group
+ * @param type the type of evaluator, in this case, it is group
+ * @param id the user id for the given user
+ * @param op operator, only "=" and "!=" are supported
+ * @param value the name of the group, eg, "Certificate Manager Agents"
+ * @return true if the given user is a member of the group
+ */
+ public boolean evaluate(String type, IUser id, String op, String value);
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
new file mode 100644
index 000000000..59266fedc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
@@ -0,0 +1,232 @@
+// --- 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.certsrv.usrgrp;
+
+
+import java.util.*;
+import java.lang.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * This class defines low-level LDAP usr/grp management
+ * usr/grp information is located remotely on another
+ * LDAP server.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IUGSubsystem extends ISubsystem, IUsrGrp {
+
+ /**
+ * Constant for ID
+ */
+ public static final String ID = "usrgrp";
+
+ /**
+ * Constant for super administrators
+ */
+ public static final String SUPER_CERT_ADMINS = "Administrators";
+
+ /**
+ * Retrieves a user from LDAP
+ * @param userid the given user id
+ * @exception EUsrGrpException thrown when failed to find the user
+ */
+ public IUser getUser(String userid) throws EUsrGrpException;
+
+ /**
+ * Searches for users that matches the filter.
+ * @param filter search filter for efficiency
+ * @return list of users
+ * @exception EUsrGrpException thrown when any internal error occurs
+ */
+ public Enumeration listUsers(String filter) throws EUsrGrpException;
+
+ /**
+ * Adds the given user to the internal database
+ * @param identity the given user
+ * @exception EUsrGrpException thrown when failed to add user to the group
+ * @exception LDAPException thrown when the LDAP internal database is not available
+ */
+ public void addUser(IUser identity) throws EUsrGrpException, LDAPException;
+
+ /**
+ * Adds a user certificate to user
+ * @param identity user interface
+ * @exception EUsrGrpException thrown when failed to add the user certificate to the given user
+ * @exception LDAPException thrown when the LDAP internal database is not available
+ */
+ public void addUserCert(IUser identity) throws EUsrGrpException,
+ LDAPException;
+
+ /**
+ * Removes a user certificate for a user entry
+ * given a user certificate DN (actually, a combination of version,
+ * serialNumber, issuerDN, and SubjectDN), and it gets removed
+ * @param identity the given user whose user certificate is going to be
+ * be removed.
+ * @exception EUsrGrpException thrown when failed to remove user certificate
+ */
+ public void removeUserCert(IUser identity) throws EUsrGrpException;
+
+ /**
+ * Removes identity.
+ * @param userid the given user id
+ * @exception EUsrGrpException thrown when failed to remove user
+ */
+ public void removeUser(String userid) throws EUsrGrpException;
+
+ /**
+ * Modifies user attributes. Certs are handled separately
+ * @param identity the given identity which contains all the user
+ * attributes being modified
+ * @exception EUsrGrpException thrown when modification failed
+ */
+ public void modifyUser(IUser identity) throws EUsrGrpException;
+
+ /**
+ * Finds groups that match the filter.
+ * @param filter the search filter
+ * @return a list of groups that match the given search filter
+ */
+ public Enumeration findGroups(String filter);
+
+ /**
+ * Find a group for the given name
+ * @param name the given name
+ * @return a group that matched the given name
+ */
+ public IGroup findGroup(String name);
+
+ /**
+ * List groups. This method is more efficient than findGroups because
+ * this method retrieves group names and description only. Each
+ * retrieved group just contains group name and description.
+ * @param filter the search filter
+ * @return a list of groups, each group just contains group name and
+ * its description.
+ * @exception EUsrGrpException thrown when failed to list groups
+ */
+ public Enumeration listGroups(String filter) throws EUsrGrpException;
+
+ /**
+ * Retrieves a group from LDAP for the given group name
+ * @param name the given group name
+ * @return a group interface
+ */
+ public IGroup getGroupFromName(String name);
+
+ /**
+ * Retrieves a group from LDAP for the given DN.
+ * @param DN the given DN
+ * @return a group interface for the given DN.
+ */
+ public IGroup getGroup(String DN);
+
+ /**
+ * Checks if the given group exists.
+ * @param name the given group name
+ * @return true if the given group exists in the internal database; otherwise false.
+ */
+ public boolean isGroupPresent(String name);
+
+ /**
+ * Checks if the given context is a member of the given group
+ * @param uid the given user id
+ * @param name the given group name
+ * @return true if the user with the given user id is a member of the given
+ * group
+ */
+ public boolean isMemberOf(String uid, String name);
+ public boolean isMemberOf(IUser id, String name);
+
+ /**
+ * Adds a group of identities.
+ * @param group the given group
+ * @exception EUsrGrpException thrown when failed to add group.
+ */
+ public void addGroup(IGroup group) throws EUsrGrpException;
+
+ /**
+ * Removes a group. Can't remove SUPER_CERT_ADMINS
+ * @param name the given group name
+ * @exception EUsrGrpException thrown when the given group failed to remove
+ */
+ public void removeGroup(String name) throws EUsrGrpException;
+
+ /**
+ * Modifies a group.
+ * @param group the given group which contain all group attributes being
+ * modified.
+ * @exception EUsrGrpException thrown when failed to modify group.
+ */
+ public void modifyGroup(IGroup group) throws EUsrGrpException;
+
+ /**
+ * Removes the user with the given id from the given group
+ * @param grp the given group
+ * @param userid the given user id
+ * @exception EUsrGrpException thrown when failed to remove the user from
+ * the given group
+ */
+ public void removeUserFromGroup(IGroup grp, String userid)
+ throws EUsrGrpException;
+
+ /**
+ * Create user with the given id.
+ * @param id the user with the given id.
+ * @return a new user
+ */
+ public IUser createUser(String id);
+
+ /**
+ * Create group with the given id.
+ * @param id the group with the given id.
+ * @return a new group
+ */
+ public IGroup createGroup(String id);
+
+ /**
+ * Get string representation of the given certificate
+ * @param cert given certificate
+ * @return the string representation of the given certificate
+ */
+ public String getCertificateString(X509Certificate cert);
+
+ /**
+ * Searchs for identities that matches the certificate locater
+ * generated filter.
+ * @param filter search filter
+ * @return an user
+ * @exception EUsrGrpException thrown when failed to find user
+ * @exception LDAPException thrown when the internal database is not available
+ */
+ public IUser findUsersByCert(String filter) throws
+ EUsrGrpException, LDAPException;
+
+ /**
+ * Get user locator which does the mapping between the user and the certificate.
+ * @return CertUserLocator
+ */
+ public ICertUserLocator getCertUserLocator();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IUser.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUser.java
new file mode 100644
index 000000000..febcb9e84
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUser.java
@@ -0,0 +1,154 @@
+// --- 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.certsrv.usrgrp;
+
+
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This interface defines the basic interfaces for
+ * a user identity. (get/set methods for a user entry attributes)
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IUser extends IAttrSet, IUserConstants {
+
+ /**
+ * Retrieves name.
+ * @return user name
+ */
+ public String getName();
+
+ /**
+ * Retrieves user identifier.
+ * @return user id
+ */
+ public String getUserID();
+
+ /**
+ * Retrieves user full name.
+ * @return user fullname
+ */
+ public String getFullName();
+
+ /**
+ * Retrieves user phonenumber.
+ * @return user phonenumber
+ */
+ public String getPhone();
+
+ /**
+ * Retrieves user state
+ * @return user state
+ */
+ public String getState();
+
+ /**
+ * Sets user full name.
+ * @param name the given full name
+ */
+ public void setFullName(String name);
+
+ /**
+ * Sets user ldap DN.
+ * @param userdn the given user DN
+ */
+ public void setUserDN(String userdn);
+
+ /**
+ * Gets user ldap dn
+ * @return user DN
+ */
+ public String getUserDN();
+
+ /**
+ * Retrieves user password.
+ * @return user password
+ */
+ public String getPassword();
+
+ /**
+ * Sets user password.
+ * @param p the given password
+ */
+ public void setPassword(String p);
+
+ /**
+ * Sets user phonenumber
+ * @param p user phonenumber
+ */
+ public void setPhone(String p);
+
+ /**
+ * Sets user state
+ * @param p the given user state
+ */
+ public void setState(String p);
+
+ /**
+ * Sets user type
+ * @param userType the given user type
+ */
+ public void setUserType(String userType);
+
+ /**
+ * Gets user email address.
+ * @return email address
+ */
+ public String getEmail();
+
+ /**
+ * Sets user email address.
+ * @param email the given email address
+ */
+ public void setEmail(String email);
+
+ /**
+ * Gets list of certificates from this user
+ * @return list of certificates
+ */
+ public X509Certificate[] getX509Certificates();
+
+ /**
+ * Sets list of certificates in this user
+ * @param certs list of certificates
+ */
+ public void setX509Certificates(X509Certificate certs[]);
+
+ /**
+ * Get certificate DN
+ * @return certificate DN
+ */
+ public String getCertDN();
+
+ /**
+ * Set certificate DN
+ * @param userdn the given DN
+ */
+ public void setCertDN(String userdn);
+
+ /**
+ * Get user type
+ * @return user type.
+ */
+ public String getUserType();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java
new file mode 100644
index 000000000..01a392494
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java
@@ -0,0 +1,70 @@
+// --- 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.certsrv.usrgrp;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This interface defines the attribute names for a user entry
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IUserConstants {
+
+ /**
+ * Constant for userScope
+ */
+ public static final String ATTR_SCOPE = "userScope";
+
+ /**
+ * Constant for userName
+ */
+ public static final String ATTR_NAME = "userName";
+
+ /**
+ * Constant for userId
+ */
+ public static final String ATTR_ID = "userId";
+
+ /**
+ * Constant for userFullName
+ */
+ public static final String ATTR_FULLNAME = "userFullName";
+
+ /**
+ * Constant for userPassword
+ */
+ public static final String ATTR_PASSWORD = "userPassword";
+
+ /**
+ * Constant for userState
+ */
+ public static final String ATTR_STATE = "userstate";
+
+ /**
+ * Constant for userEmail
+ */
+ public static final String ATTR_EMAIL = "userEmail";
+
+ /**
+ * Constant for usertype
+ */
+ public static final String ATTR_USERTYPE = "usertype";
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java
new file mode 100644
index 000000000..98eb9e9b5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java
@@ -0,0 +1,110 @@
+// --- 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.certsrv.usrgrp;
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import netscape.ldap.*;
+
+/**
+ * This interface defines the basic capabilities of
+ * a usr/group manager. (get/add/modify/remove users or groups)
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IUsrGrp extends IIdEvaluator {
+
+ /**
+ * Retrieves usr/grp manager identifier.
+ * @return id
+ */
+ public String getId();
+
+ /**
+ * Retrieves the description
+ * @return description
+ */
+ public String getDescription();
+
+ /**
+ * Retrieves an identity
+ * @param userid the user id for the given user
+ * @return user interface
+ */
+ public IUser getUser(String userid) throws EUsrGrpException;
+
+ /**
+ * Adds a user identity to the LDAP server. For example,
+ * <code>
+ * User user = new User("joe");
+ * user.setFullName("joe doe");
+ * user.setPassword("secret");
+ * usrgrp.addUser(user);
+ * </code>
+ * @param user an user interface
+ * @exception EUsrGrpException thrown when some of the user attribute values
+ * are null
+ * @exception LDAPException thrown when the LDAP internal database is not
+ * available, or the add operation failed
+ */
+ public void addUser(IUser user) throws EUsrGrpException, LDAPException;
+
+ /**
+ * Removes a user.
+ * @param userid the user id for the given user
+ * @exception EUsrGrpException thrown when failed to remove user
+ */
+ public void removeUser(String userid) throws EUsrGrpException;
+
+ /**
+ * Modifies user.
+ * @param user the user interface which contains the modified information
+ * @exception EUsrGrpException thrown when failed to modify user
+ */
+ public void modifyUser(IUser user) throws EUsrGrpException;
+
+ /**
+ * Retrieves an identity group
+ * @param groupid the given group id.
+ * @return the group interface
+ */
+ public IGroup getGroup(String groupid);
+
+ /**
+ * Adds a group
+ * @param group the given group
+ * @exception EUsrGrpException thrown when failed to add the group.
+ */
+ public void addGroup(IGroup group) throws EUsrGrpException;
+
+ /**
+ * Modifies a group
+ * @param group the given group contains the new information for modification.
+ * @exception EUsrGrpException thrown when failed to modify the group.
+ */
+ public void modifyGroup(IGroup group) throws EUsrGrpException;
+
+ /**
+ * Removes a group
+ * @param name the group name
+ * @exception EUsrGrpException thrown when failed to remove the given
+ * group.
+ */
+ public void removeGroup(String name) throws EUsrGrpException;
+
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java b/pki/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java
new file mode 100644
index 000000000..ed4f28b83
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java
@@ -0,0 +1,45 @@
+// --- 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.certsrv.usrgrp;
+
+import java.util.ListResourceBundle;
+
+/**
+ * A class represents a resource bundle for the
+ * user/group manager
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class UsrGrpResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ * @return the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java b/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java
new file mode 100644
index 000000000..b64ac4622
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java
@@ -0,0 +1,296 @@
+// --- 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.certsrv.util;
+
+import netscape.ldap.*;
+import java.io.*;
+import java.net.*;
+import javax.servlet.http.*;
+import javax.servlet.*;
+import java.util.*;
+import java.math.*;
+import java.util.regex.*;
+
+public class HttpInput
+{
+ public static int getPortNumberInInt(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String val = request.getParameter(name);
+ int p = Integer.parseInt(val);
+ return p;
+ }
+
+ public static String getBoolean(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String val = request.getParameter(name);
+ if (val.equals("true") || val.equals("false")) {
+ return val;
+ }
+ throw new IOException("Invalid boolean value '" + val + "'");
+ }
+
+ public static String getCheckbox(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String val = request.getParameter(name);
+ if (val == null || val.equals("")) {
+ return "off";
+ } else if (val.equals("on") || val.equals("off")) {
+ return val;
+ }
+ throw new IOException("Invalid checkbox value '" + val + "'");
+ }
+
+ public static String getInteger(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String val = request.getParameter(name);
+ int p = 0;
+ try {
+ p = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ throw new IOException("Input '" + val + "' is not an integer");
+ }
+
+ if (!val.equals(Integer.toString(p))) {
+ throw new IOException("Input '" + val + "' is not an integer");
+ }
+ return val;
+ }
+
+ public static String getInteger(HttpServletRequest request, String name,
+ int min, int max) throws IOException
+ {
+ String val = getInteger(request, name);
+ int p = Integer.parseInt(val);
+ if (p < min || p > max) {
+ throw new IOException("Input '" + val + "' is out of range");
+ }
+ return val;
+ }
+
+ public static String getPortNumber(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getInteger(request, name);
+ return v;
+ }
+
+ public static String getString(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String val = request.getParameter(name);
+ return val;
+ }
+
+ public static String getString(HttpServletRequest request, String name,
+ int minlen, int maxlen) throws IOException
+ {
+ String val = request.getParameter(name);
+ if (val.length() < minlen || val.length() > maxlen) {
+ throw new IOException("String length of '" + val +
+ "' is out of range");
+ }
+ return val;
+ }
+
+ public static String getLdapDatabase(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getURL(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getString(request, name);
+ try {
+ URL u = new URL(v);
+ } catch (Exception e) {
+ throw new IOException("Invalid URL " + v);
+ }
+ return v;
+ }
+
+ public static String getUID(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getPassword(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getKeyType(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getString(request, name);
+ if (v.equals("rsa")) {
+ return v;
+ }
+ if (v.equals("ecc")) {
+ return v;
+ }
+ throw new IOException("Invalid key type '" + v + "' not supported.");
+ }
+
+ public static String getKeySize(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String i = getInteger(request, name);
+ if (i.equals("256") || i.equals("512") || i.equals("1024") ||
+ i.equals("2048") || i.equals("4096")) {
+ return i;
+ }
+ throw new IOException("Invalid key length '" + i + "'. Currently supported key lengths are 256, 512, 1024, 2048, 4096.");
+ }
+
+ public static String getKeySize(HttpServletRequest request, String name, String keyType)
+ throws IOException
+ {
+ String i = getInteger(request, name);
+ if (keyType.equals("rsa")) {
+ if (i.equals("256") || i.equals("512") || i.equals("1024") ||
+ i.equals("2048") || i.equals("4096")) {
+ return i;
+ } else {
+ throw new IOException("Invalid key length '" + i + "'. Currently supported RSA key lengths are 256, 512, 1024, 2048, 4096.");
+ }
+ }
+ if (keyType.equals("ecc")) {
+ int p = 0;
+ try {
+ p = Integer.parseInt(i);
+ } catch (NumberFormatException e) {
+ throw new IOException("Input '" + i + "' is not an integer");
+ }
+ if ((p >= 112) && (p <= 571))
+ return i;
+ else {
+ throw new IOException("Invalid key length '" + i + "'. Please consult your security officer for a proper length, or take the default value. Here are examples of some commonly used key lengths: 256, 384, 521.");
+ }
+/*
+
+ if (i.equals("256") || i.equals("384") || i.equals("521")) {
+ return i;
+ } else {
+ throw new IOException("Invalid key length '" + i + "'. Currently supported ECC key lengths are 256, 384, 521.");
+ }
+*/
+ }
+ throw new IOException("Invalid key type '" + keyType + "'");
+ }
+
+ public static String getDN(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getString(request, name);
+ String dn[] = LDAPDN.explodeDN(v, true);
+ if (dn == null || dn.length <= 0) {
+ throw new IOException("Invalid DN " + v + " in " + name);
+ }
+ return v;
+ }
+
+ public static String getID(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getName(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getCertRequest(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getCertChain(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getCert(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getNickname(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getHostname(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getTokenName(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getReplicationAgreementName(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getEmail(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getString(request, name);
+ if (v.indexOf('@') == -1) {
+ throw new IOException("Invalid email " + v);
+ }
+ return v;
+ }
+
+ public static String getDomainName(HttpServletRequest request, String name)
+ throws IOException
+ {
+ return getString(request, name);
+ }
+
+ public static String getSecurityDomainName(HttpServletRequest request, String name)
+ throws IOException
+ {
+ String v = getName(request, name);
+ Pattern p = Pattern.compile("[A-Za-z0-9]+[A-Za-z0-9 -]*");
+ Matcher m = p.matcher(v);
+ if (!m.matches()) {
+ throw new IOException("Invalid characters found in Security Domain Name " + v + ". Valid characters are A-Z, a-z, 0-9, dash and space");
+ }
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java b/pki/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java
new file mode 100644
index 000000000..05a92f8d4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java
@@ -0,0 +1,63 @@
+// --- 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.certsrv.util;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a internal subsystem. This subsystem
+ * can be loaded into cert server kernel to perform
+ * statistics collection.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public interface IStatsSubsystem extends ISubsystem
+{
+ /**
+ * Retrieves the start time since startup or
+ * clearing of statistics.
+ */
+ public Date getStartTime();
+
+ /**
+ * Starts timing of a operation.
+ */
+ public void startTiming(String id);
+
+ public void startTiming(String id, boolean main);
+
+ /**
+ * Stops timing of a operation.
+ */
+ public void endTiming(String id);
+
+ /**
+ * Resets counters.
+ */
+ public void resetCounters();
+
+ /**
+ * Resets all internal counters.
+ */
+ public StatsEvent getMainStatsEvent();
+}
diff --git a/pki/base/common/src/com/netscape/certsrv/util/StatsEvent.java b/pki/base/common/src/com/netscape/certsrv/util/StatsEvent.java
new file mode 100644
index 000000000..2849f5ecc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/certsrv/util/StatsEvent.java
@@ -0,0 +1,194 @@
+// --- 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.certsrv.util;
+
+
+import java.util.*;
+import java.math.*;
+
+/**
+ * A statistics transaction.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StatsEvent
+{
+ private String mName = null;
+ private long mMin = -1;
+ private long mMax = -1;
+ private long mTimeTaken = 0;
+ private long mTimeTakenSqSum = 0;
+ private long mNoOfOperations = 0;
+ private Vector mSubEvents = new Vector();
+ private StatsEvent mParent = null;
+
+ public StatsEvent(StatsEvent parent)
+ {
+ mParent = parent;
+ }
+
+ public void setName(String name)
+ {
+ mName = name;
+ }
+
+ /**
+ * Retrieves Transaction name.
+ */
+ public String getName()
+ {
+ return mName;
+ }
+
+ public void addSubEvent(StatsEvent st)
+ {
+ mSubEvents.addElement(st);
+ }
+
+ /**
+ * Retrieves a list of sub transaction names.
+ */
+ public Enumeration getSubEventNames()
+ {
+ Vector names = new Vector();
+ Enumeration e = mSubEvents.elements();
+ while (e.hasMoreElements()) {
+ StatsEvent st = (StatsEvent)e.nextElement();
+ names.addElement(st.getName());
+ }
+ return names.elements();
+ }
+
+ /**
+ * Retrieves a sub transaction.
+ */
+ public StatsEvent getSubEvent(String name)
+ {
+ Enumeration e = mSubEvents.elements();
+ while (e.hasMoreElements()) {
+ StatsEvent st = (StatsEvent)e.nextElement();
+ if (st.getName().equals(name)) {
+ return st;
+ }
+ }
+ return null;
+ }
+
+ public void resetCounters()
+ {
+ mMin = -1;
+ mMax = -1;
+ mNoOfOperations = 0;
+ mTimeTaken = 0;
+ mTimeTakenSqSum = 0;
+ Enumeration e = getSubEventNames();
+ while (e.hasMoreElements()) {
+ String n = (String)e.nextElement();
+ StatsEvent c = getSubEvent(n);
+ c.resetCounters();
+ }
+ }
+
+ public long getMax()
+ {
+ return mMax;
+ }
+
+ public long getMin()
+ {
+ return mMin;
+ }
+
+ public void incNoOfOperations(long c)
+ {
+ mNoOfOperations += c;
+ }
+
+ public long getTimeTakenSqSum()
+ {
+ return mTimeTakenSqSum;
+ }
+
+ public long getPercentage()
+ {
+ if (mParent == null || mParent.getTimeTaken() == 0) {
+ return 100;
+ } else {
+ return (mTimeTaken * 100 / mParent.getTimeTaken());
+ }
+ }
+
+ public long getStdDev()
+ {
+ if (getNoOfOperations() == 0) {
+ return 0;
+ } else {
+ long a = getTimeTakenSqSum();
+ long b = (-2 * getAvg() *getTimeTaken());
+ long c = getAvg() * getAvg() * getNoOfOperations();
+ return (long)Math.sqrt((a + b + c)/getNoOfOperations());
+ }
+ }
+
+ public long getAvg()
+ {
+ if (mNoOfOperations == 0) {
+ return -1;
+ } else {
+ return mTimeTaken/mNoOfOperations;
+ }
+ }
+
+ /**
+ * Retrieves number of operations performed.
+ */
+ public long getNoOfOperations()
+ {
+ return mNoOfOperations;
+ }
+
+ public void incTimeTaken(long c)
+ {
+ if (mMin == -1) {
+ mMin = c;
+ } else {
+ if (c < mMin) {
+ mMin = c;
+ }
+ }
+ if (mMax == -1) {
+ mMax = c;
+ } else {
+ if (c > mMax) {
+ mMax = c;
+ }
+ }
+ mTimeTaken += c;
+ mTimeTakenSqSum += (c * c);
+ }
+
+ /**
+ * Retrieves total time token in msec.
+ */
+ public long getTimeTaken()
+ {
+ return mTimeTaken;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/AVAPattern.java b/pki/base/common/src/com/netscape/cms/authentication/AVAPattern.java
new file mode 100644
index 000000000..e4f700054
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/AVAPattern.java
@@ -0,0 +1,542 @@
+// --- 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.authentication;
+
+
+import java.util.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import java.io.*;
+import java.security.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a certificate
+ * subject name from ldap attributes and dn.<p>
+ *
+ * dnpattern is a string representing a subject name pattern to formulate from
+ * the directory attributes and entry dn. If empty or not set, the
+ * ldap entry DN will be used as the certificate subject name. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$attr" "." attrName [ "." attrNumber ] |
+ * name "=" "$dn" "." attrName [ "." attrNumber ] |
+ * "$dn" "." "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US </i>
+ * Ldap entry: dn: UID=jjames, OU=IS, OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example2: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * <pre>
+ * Example3: <i>CN=$attr.cn, $rdn.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=IS+OU=people, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * followed by the second RDN in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example4: <i>CN=$attr.cn, OU=$dn.ou.2+OU=$dn.ou.1, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=people+OU=IS, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN followed by the
+ * first 'ou' value in the user's entry. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * If an attribute or subject DN component does not exist the attribute
+ * is skipped.
+ *
+ * @version $Revision$, $Date$
+ */
+class AVAPattern {
+
+ /* the value type of the dn component */
+ public static final String TYPE_ATTR = "$attr";
+ public static final String TYPE_DN = "$dn";
+ public static final String TYPE_RDN = "$rdn";
+ public static final String TYPE_CONSTANT = "constant";
+
+ private static final char[] endChars = new char[] { '+', ',' };
+
+ private static final LdapV3DNStrConverter mLdapDNStrConverter =
+ new LdapV3DNStrConverter();
+
+ /* ldap attributes needed by this AVA (to retrieve from ldap) */
+ protected String[] mLdapAttrs = null;
+
+ /* value type */
+ protected String mType = null;
+
+ /* the attribute in the AVA pair */
+ protected String mAttr = null;
+
+ /* value - could be name of an ldap attribute or entry dn attribute. */
+ protected String mValue = null;
+
+ /* nth value of the ldap or dn attribute */
+ protected int mElement = 0;
+
+ protected String mTestDN = null;
+
+ public AVAPattern(String component)
+ throws EAuthException {
+ if (component == null || component.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", component));
+ parse(new PushbackReader(new StringReader(component)));
+ }
+
+ public AVAPattern(PushbackReader in)
+ throws EAuthException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws EAuthException {
+ int c;
+
+ // mark ava beginning.
+
+ // skip spaces
+ //System.out.println("============ AVAPattern Begin ===========");
+ //System.out.println("skip spaces");
+
+ try {
+ while ((c = in.read()) == ' ' || c == '\t') {//System.out.println("spaces read "+(char)c);
+ ;
+ }
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+
+ // $rdn "." number syntax.
+
+ if (c == '$') {
+ //System.out.println("$rdn syntax");
+ mType = TYPE_RDN;
+ try {
+ if (in.read() != 'r' ||
+ in.read() != 'd' ||
+ in.read() != 'n' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $ syntax, expecting $rdn"));
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $ syntax, expecting $rdn"));
+ }
+
+ StringBuffer rdnNumberBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '+') {
+ //System.out.println("rdnNumber read "+(char)c);
+ rdnNumberBuf.append((char) c);
+ }
+ if (c != -1) // either ',' or '+'
+ in.unread(c);
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+
+ String rdnNumber = rdnNumberBuf.toString().trim();
+
+ if (rdnNumber.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "$rdn number not set in ava pattern"));
+ try {
+ mElement = Integer.parseInt(rdnNumber) - 1;
+ } catch (NumberFormatException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $rdn number in ava pattern"));
+ }
+ return;
+ }
+
+ // name "=" ... syntax.
+
+ // read name
+ //System.out.println("reading name");
+
+ StringBuffer attrBuf = new StringBuffer();
+
+ try {
+ while (c != '=' && c != -1 && c != ',' && c != '+') {
+ attrBuf.append((char) c);
+ c = in.read();
+ //System.out.println("name read "+(char)c);
+ }
+ if (c == ',' || c == '+')
+ in.unread(c);
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ if (c != '=')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Missing \"=\" in ava pattern"));
+
+ // read value
+ //System.out.println("reading value");
+
+ // skip spaces
+ //System.out.println("skip spaces for value");
+ try {
+ while ((c = in.read()) == ' ' || c == '\t') {//System.out.println("spaces2 read "+(char)c);
+ ;
+ }
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "no value after = in ava pattern"));
+
+ if (c == '$') {
+ // check for $dn or $attr
+ try {
+ c = in.read();
+ //System.out.println("check $dn or $attr read "+(char)c);
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $dn or $attr in ava pattern"));
+ if (c == 'a') {
+ try {
+ if (in.read() != 't' ||
+ in.read() != 't' ||
+ in.read() != 'r' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $attr in ava pattern"));
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ mType = TYPE_ATTR;
+ //System.out.println("---- mtype $attr");
+ } else if (c == 'd') {
+ try {
+ if (in.read() != 'n' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $dn in ava pattern"));
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ mType = TYPE_DN;
+ //System.out.println("----- mtype $dn");
+ } else {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "unknown keyword. expecting $dn or $attr."));
+ }
+
+ // get attr name of dn pattern from above.
+ String attrName = attrBuf.toString().trim();
+
+ //System.out.println("----- attrName "+attrName);
+ if (attrName.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "attribute name expected"));
+ try {
+ ObjectIdentifier attrOid =
+ mLdapDNStrConverter.parseAVAKeyword(attrName);
+
+ mAttr = mLdapDNStrConverter.encodeOID(attrOid);
+ //System.out.println("----- mAttr "+mAttr);
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", e.getMessage()));
+ }
+
+ // get dn or attribute from ldap search.
+ StringBuffer valueBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1 && c != '.' && c != '+') {
+ //System.out.println("mValue read "+(char)c);
+ valueBuf.append((char) c);
+ }
+ if (c == '+' || c == ',') // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+
+ mValue = valueBuf.toString().trim();
+ if (mValue.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "$dn or $attr attribute name expected"));
+ //System.out.println("----- mValue "+mValue);
+
+ // get nth dn or attribute from ldap search.
+ if (c == '.') {
+ StringBuffer attrNumberBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '+') {
+ //System.out.println("mElement read "+(char)c);
+ attrNumberBuf.append((char) c);
+ }
+ if (c != -1) // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ String attrNumber = attrNumberBuf.toString().trim();
+
+ if (attrNumber.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "nth element $dn or $attr expected"));
+ try {
+ mElement = Integer.parseInt(attrNumber) - 1;
+ } catch (NumberFormatException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "Invalid format in nth element $dn or $attr"));
+ }
+ }
+ //System.out.println("----- mElement "+mElement);
+ } else {
+ // value is constant. treat as regular ava.
+ mType = TYPE_CONSTANT;
+ //System.out.println("----- mType constant");
+ // parse ava value.
+ StringBuffer valueBuf = new StringBuffer();
+
+ valueBuf.append((char) c);
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1) {
+ valueBuf.append((char) c);
+ }
+ if (c == '+' || c == ',') { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", e.getMessage()));
+ }
+ try {
+ AVA ava = mLdapDNStrConverter.parseAVA(attrBuf + "=" + valueBuf);
+
+ mValue = ava.toLdapDNString();
+ //System.out.println("----- mValue "+mValue);
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", e.getMessage()));
+ }
+ }
+ }
+
+ public String formAVA(LDAPEntry entry)
+ throws EAuthException {
+ if (mType == TYPE_CONSTANT)
+ return mValue;
+
+ if (mType == TYPE_RDN) {
+ String dn = entry.getDN();
+
+ if (mTestDN != null)
+ dn = mTestDN;
+ //System.out.println("AVAPattern Using dn "+mTestDN);
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+
+ if (mElement >= rdns.length)
+ return null;
+ return rdns[mElement];
+ }
+
+ if (mType == TYPE_DN) {
+ String dn = entry.getDN();
+
+ if (mTestDN != null)
+ dn = mTestDN;
+ //System.out.println("AVAPattern Using dn "+mTestDN);
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+ String value = null;
+ int nFound = -1;
+
+ for (int i = 0; i < rdns.length; i++) {
+ String[] avas = explodeRDN(rdns[i]);
+
+ for (int j = 0; j < avas.length; j++) {
+ String[] exploded = explodeAVA(avas[j]);
+
+ if (exploded[0].equalsIgnoreCase(mValue) &&
+ ++nFound == mElement) {
+ value = exploded[1];
+ break;
+ }
+ }
+ }
+ if (value == null)
+ return null;
+ return mAttr + "=" + value;
+ }
+
+ if (mType == TYPE_ATTR) {
+ LDAPAttribute ldapAttr = entry.getAttribute(mValue);
+
+ if (ldapAttr == null)
+ return null;
+ String value = null;
+ Enumeration ldapValues = ldapAttr.getStringValues();
+
+ for (int i = 0; ldapValues.hasMoreElements(); i++) {
+ String val = (String) ldapValues.nextElement();
+
+ if (i == mElement) {
+ value = val;
+ break;
+ }
+ }
+ if (value == null)
+ return null;
+ String v = escapeLdapString(value);
+
+ return mAttr + "=" + v;
+ }
+
+ return null;
+ }
+
+ private String escapeLdapString(String value) {
+ int len = value.length();
+ char[] c = new char[len];
+ char[] newc = new char[len * 2];
+
+ value.getChars(0, len, c, 0);
+ int j = 0;
+
+ for (int i = 0; i < c.length; i++) {
+ // escape special characters that directory does not.
+ if ((c[i] == ',' || c[i] == '=' || c[i] == '+' || c[i] == '<' ||
+ c[i] == '>' || c[i] == '#' || c[i] == ';')) {
+ if (i == 0 || c[i - 1] != '\\') {
+ newc[j++] = '\\';
+ newc[j++] = c[i];
+ }
+ } // escape "\"
+ else if (c[i] == '\\') {
+ int k = i + 1;
+
+ if (i == len - 1 ||
+ (c[k] == ',' || c[k] == '=' || c[k] == '+' || c[k] == '<' ||
+ c[k] == '>' || c[k] == '#' || c[k] == ';')) {
+ newc[j++] = '\\';
+ newc[j++] = c[i];
+ }
+ } // escape QUOTATION
+ else if (c[i] == '"') {
+ if ((i == 0 && c[len - 1] != '"') ||
+ (i == len - 1 && c[0] != '"') ||
+ (i > 0 && i < len - 1)) {
+ newc[j++] = '\\';
+ newc[j++] = c[i];
+ }
+ } else
+ newc[j++] = c[i];
+ }
+ return new String(newc, 0, j);
+ }
+
+ public String getLdapAttr() {
+ if (mType == TYPE_ATTR)
+ return mValue;
+ else
+ return null;
+ }
+
+ /**
+ * Explode RDN into AVAs.
+ * Does not handle escaped '+'
+ * Java ldap library does not yet support multiple avas per rdn.
+ * If RDN is malformed returns empty array.
+ */
+ public static String[] explodeRDN(String rdn) {
+ int plus = rdn.indexOf('+');
+
+ if (plus == -1)
+ return new String[] { rdn };
+ Vector avas = new Vector();
+ StringTokenizer token = new StringTokenizer(rdn, "+");
+
+ while (token.hasMoreTokens())
+ avas.addElement(token.nextToken());
+ String[] theAvas = new String[avas.size()];
+
+ avas.copyInto(theAvas);
+ return theAvas;
+ }
+
+ /**
+ * Explode AVA into name and value.
+ * Does not handle escaped '='
+ * If AVA is malformed empty array is returned.
+ */
+ public static String[] explodeAVA(String ava) {
+ int equals = ava.indexOf('=');
+
+ if (equals == -1)
+ return null;
+ return new String[] {
+ ava.substring(0, equals).trim(), ava.substring(equals + 1).trim()};
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java
new file mode 100644
index 000000000..bef5e8c2a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java
@@ -0,0 +1,325 @@
+// --- 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.authentication;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.lang.Class;
+import java.security.cert.*;
+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 agent authentication.
+ * Maps a SSL client authenticate certificate to a user (agent) entry in the
+ * internal database.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AgentCertAuthentication 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";
+ public static final String TOKEN_GROUP = "group";
+
+ /* 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 IUGSubsystem mUGSub = null;
+ private ICertUserLocator mCULocator = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ private IConfigStore mRevocationChecking = null;
+ private String mRequestor = null;
+
+ public AgentCertAuthentication() {
+ }
+
+ /**
+ * initializes the CertUserDBAuthentication 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;
+
+ mUGSub = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ mCULocator = mUGSub.getCertUserLocator();
+ }
+
+ /**
+ * 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(agent) by certificate
+ * <p>
+ * called by other subsystems or their servlets to authenticate
+ * users (agents)
+ * @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("AgentCertAuthentication: 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("AgentCertAuthentication: No SSL Client Cert Provider Found");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ CMS.debug("AgentCertAuthenticator: got provider");
+ CMS.debug("AgentCertAuthenticator: retrieving client certificate");
+ X509Certificate[] allCerts = provider.getClientCertificateChain();
+
+ if (allCerts == null) {
+ CMS.debug("AgentCertAuthentication: No SSL Client Certs Found");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ CMS.debug("AgentCertAuthenticator: 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];
+
+ try {
+ for (int i = 0; i < x509Certs.length; i++) {
+ ci[i] = new X509CertImpl(x509Certs[i].getEncoded());
+ }
+ } catch (CertificateException e) {
+ CMS.debug(e.toString());
+ }
+
+ // 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("AgentCertAuthentication: certificate revoked");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ }
+
+ // map cert to user
+ IUser user = null;
+ Certificates certs = new Certificates(ci);
+
+ try {
+ user = (IUser) mCULocator.locateUser(certs);
+ } catch (EUsrGrpException e) {
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ } catch (netscape.ldap.LDAPException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ e.toString()));
+ }
+
+ // any unexpected error occurs like internal db down,
+ // UGSubsystem only returns null for user.
+ if (user == null) {
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // get group name from configuration file
+ IConfigStore sconfig = CMS.getConfigStore();
+ String groupname = "";
+ try {
+ groupname = sconfig.getString("auths.instance."+ getName() +".agentGroup",
+ "");
+ } catch (EBaseException ee) {
+ }
+
+ if (!groupname.equals("")) {
+ CMS.debug("check if "+user.getUserID()+" is in group "+groupname);
+ IUGSubsystem uggroup = (IUGSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ if (!uggroup.isMemberOf(user, groupname)) {
+ CMS.debug(user.getUserID()+" is not in this group "+groupname);
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHORIZATION_ERROR"));
+ }
+ }
+ authToken.set(TOKEN_USERDN, user.getUserDN());
+ 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("AgentCertAuthentication: authenticated " + user.getUserDN());
+
+ return authToken;
+ }
+
+ /**
+ * 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_AGENT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_AGENT_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 {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/CMCAuth.java b/pki/base/common/src/com/netscape/cms/authentication/CMCAuth.java
new file mode 100644
index 000000000..eb09e5b47
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/CMCAuth.java
@@ -0,0 +1,1048 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.authentication;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+/* cert server imports */
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.cmsutil.util.*;
+import netscape.security.x509.*;
+
+/* java sdk imports */
+import java.io.*;
+import java.util.*;
+import java.util.Properties;
+import java.util.Vector;
+import com.netscape.certsrv.apps.*;
+import java.util.Hashtable;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.certsrv.usrgrp.*;
+
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import java.math.BigInteger;
+import org.mozilla.jss.CryptoManager;
+
+//import com.netscape.cmscore.util.*;
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * UID/CMC authentication plug-in
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
+ IProfileAuthenticator {
+
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ /////////////////////////////
+ // IAuthManager parameters //
+ /////////////////////////////
+
+ /* authentication plug-in configuration store */
+ private IConfigStore mConfig;
+ private static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ public static final String REASON_CODE = "reasonCode";
+ /* authentication plug-in name */
+ private String mImplName = null;
+
+ /* authentication plug-in instance name */
+ private String mName = null;
+
+ /* authentication plug-in fields */
+
+
+
+ /* Holds authentication plug-in fields accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {};
+
+ /* authentication plug-in values */
+
+ /* authentication plug-in properties */
+
+
+ /* required credentials to authenticate. UID and CMC are strings. */
+ public static final String CRED_CMC = "cmcRequest";
+
+ protected static String[] mRequiredCreds = {};
+
+ ////////////////////////////////////
+ // IExtendedPluginInfo parameters //
+ ////////////////////////////////////
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+ //public static final String AGENT_AUTHMGR_ID = "agentAuthMgr";
+ //public static final String AGENT_PLUGIN_ID = "agentAuthPlugin";
+
+
+ /* actual help messages */
+ static {
+ mExtendedPluginInfo = new Vector();
+
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TEXT +
+ ";Authenticate the CMC request. The signer must be an agent. The \"Authentication Instance ID\" must be named \"CMCAuth\"");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authentication");
+ }
+
+ ///////////////////////
+ // Logger parameters //
+ ///////////////////////
+
+ /* the system's logger */
+ private ILogger mLogger = CMS.getLogger();
+
+ /* signed audit parameters */
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE =
+ "enrollment";
+ private final static String SIGNED_AUDIT_REVOCATION_REQUEST_TYPE =
+ "revocation";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY =
+ "LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY_5";
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public CMCAuth() {
+ }
+
+ //////////////////////////
+ // IAuthManager methods //
+ //////////////////////////
+
+ /**
+ * Initializes the CMCAuth authentication plug-in.
+ * <p>
+ * @param name The name for this authentication plug-in instance.
+ * @param implName The name of the authentication plug-in.
+ * @param config - The configuration store for this instance.
+ * @exception EBaseException If an error occurs during initialization.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ log(ILogger.LL_INFO, "Initialization complete!");
+ }
+
+ /**
+ * Authenticates user by their CMC;
+ * resulting AuthToken sets a TOKEN_SUBJECT for the subject name.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY
+ * used when CMC (agent-pre-signed) cert requests or revocation requests
+ * are submitted and signature is verified
+ * </ul>
+ * @param authCred Authentication credentials, CRED_UID and CRED_CMC.
+ * @return an AuthToken
+ * @exception com.netscape.certsrv.authentication.EMissingCredential
+ * If a required authentication credential is missing.
+ * @exception com.netscape.certsrv.authentication.EInvalidCredentials
+ * If credentials failed authentication.
+ * @exception com.netscape.certsrv.base.EBaseException
+ * If an internal error occurred.
+ * @see com.netscape.certsrv.authentication.AuthToken
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred) throws EMissingCredential, EInvalidCredentials, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditReqType = ILogger.UNIDENTIFIED;
+ String auditCertSubject = ILogger.UNIDENTIFIED;
+ String auditSignerInfo = ILogger.UNIDENTIFIED;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // get the CMC.
+
+ Object argblock = (Object)(authCred.getArgBlock());
+ Object returnVal = null;
+ if (argblock == null) {
+ returnVal = authCred.get("cert_request");
+ if (returnVal == null)
+ returnVal = authCred.get(CRED_CMC);
+ } else {
+ returnVal = authCred.get("cert_request");
+ if (returnVal == null)
+ returnVal = authCred.getArgBlock().get(CRED_CMC);
+ }
+ String cmc = (String) returnVal;
+ if (cmc == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ throw new EMissingCredential(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_NULL_CREDENTIAL",CRED_CMC));
+ }
+
+ if (cmc.equals("")) {
+ log(ILogger.LL_FAILURE,
+ "cmc : attempted login with empty CMC.");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ throw new EInvalidCredentials(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // authenticate by checking CMC.
+
+ // everything OK.
+ // now formulate the certificate info.
+ // set the subject name at a minimum.
+ // set anything else like version, extensions, etc.
+ // if nothing except subject name is set the rest of
+ // cert info will be filled in by policies and CA defaults.
+
+ AuthToken authToken = new AuthToken(this);
+
+ try {
+ String asciiBASE64Blob;
+
+ int startIndex = cmc.indexOf(HEADER);
+ int endIndex = cmc.indexOf(TRAILER);
+ if (startIndex!= -1 && endIndex!=-1) {
+ startIndex = startIndex + HEADER.length();
+ asciiBASE64Blob=cmc.substring(startIndex, endIndex);
+ }else
+ asciiBASE64Blob = cmc;
+
+
+ byte[] cmcBlob = CMS.AtoB(asciiBASE64Blob);
+ ByteArrayInputStream cmcBlobIn= new
+ ByteArrayInputStream(cmcBlob);
+
+ org.mozilla.jss.pkix.cms.ContentInfo cmcReq =
+ (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(
+ cmcBlobIn);
+
+ if(!cmcReq.getContentType().equals(
+ org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) ||
+ !cmcReq.hasContent()) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ // throw new ECMSGWException(CMSGWResources.NO_CMC_CONTENT);
+
+ throw new EBaseException("NO_CMC_CONTENT");
+ }
+
+ SignedData cmcFullReq = (SignedData)
+ cmcReq.getInterpretedContent();
+
+ IConfigStore cmc_config = CMS.getConfigStore();
+ boolean checkSignerInfo =
+ cmc_config.getBoolean("cmc.signerInfo.verify", true);
+ String userid = "defUser";
+ String uid = "defUser";
+ if (checkSignerInfo) {
+ IAuthToken agentToken = verifySignerInfo(authToken,cmcFullReq);
+ userid = agentToken.getInString("userid");
+ uid = agentToken.getInString("cn");
+ } else {
+ CMS.debug("CMCAuth: authenticate() signerInfo verification bypassed");
+ }
+ // reset value of auditSignerInfo
+ if( uid != null ) {
+ auditSignerInfo = uid.trim();
+ }
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+
+ OBJECT_IDENTIFIER id = ci.getContentType();
+
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
+ !ci.hasContent()) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ // throw new ECMSGWException(
+ // CMSGWResources.NO_PKIDATA);
+
+ throw new EBaseException("NO_PKIDATA");
+ }
+
+ OCTET_STRING content = ci.getContent();
+
+ ByteArrayInputStream s = new
+ ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SEQUENCE reqSequence = pkiData.getReqSequence();
+
+ int numReqs = reqSequence.size();
+
+ if (numReqs == 0) {
+ // revocation request
+
+ // reset value of auditReqType
+ auditReqType = SIGNED_AUDIT_REVOCATION_REQUEST_TYPE;
+
+ SEQUENCE controlSequence = pkiData.getControlSequence();
+ int controlSize = controlSequence.size();
+
+ if (controlSize > 0) {
+ for (int i = 0; i < controlSize; i++) {
+ TaggedAttribute taggedAttribute =
+ (TaggedAttribute) controlSequence.elementAt(i);
+ OBJECT_IDENTIFIER type = taggedAttribute.getType();
+
+ if( type.equals(
+ OBJECT_IDENTIFIER.id_cmc_revokeRequest)) {
+ // if( i ==1 ) {
+ // taggedAttribute.getType() ==
+ // OBJECT_IDENTIFIER.id_cmc_revokeRequest
+ // }
+
+ SET values = taggedAttribute.getValues();
+ int numVals = values.size();
+ BigInteger[] bigIntArray = null;
+
+ bigIntArray = new BigInteger[numVals];
+ for (int j = 0; j < numVals; j++) {
+ // serialNumber INTEGER
+
+ // SEQUENCE RevRequest = (SEQUENCE)
+ // values.elementAt(j);
+ byte[] encoded = ASN1Util.encode(
+ values.elementAt(j));
+ org.mozilla.jss.asn1.ASN1Template
+ template = new
+ org.mozilla.jss.pkix.cmmf.RevRequest.Template();
+ org.mozilla.jss.pkix.cmmf.RevRequest
+ revRequest =
+ (org.mozilla.jss.pkix.cmmf.RevRequest)
+ ASN1Util.decode(template, encoded);
+
+ // SEQUENCE RevRequest = (SEQUENCE)
+ // ASN1Util.decode(
+ // SEQUENCE.getTemplate(),
+ // ASN1Util.encode(
+ // values.elementAt(j)));
+
+ // SEQUENCE RevRequest =
+ // values.elementAt(j);
+ // int revReqSize = RevRequest.size();
+ // if( revReqSize > 3 ) {
+ // INTEGER serialNumber =
+ // new INTEGER((long)0);
+ // }
+
+ INTEGER temp = revRequest.getSerialNumber();
+ int temp2 = temp.intValue();
+
+ bigIntArray[j] = temp;
+ authToken.set(TOKEN_CERT_SERIAL,bigIntArray);
+
+ long reasonCode = revRequest.getReason().getValue();
+ Integer IntObject = Integer.valueOf((int)reasonCode);
+ authToken.set(REASON_CODE,IntObject);
+
+ authToken.set("uid",uid);
+ authToken.set("userid",userid);
+ }
+ }
+ }
+
+ }
+ } else {
+ // enrollment request
+
+ // reset value of auditReqType
+ auditReqType = SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE;
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[numReqs];
+ String[] reqIdArray = new String[numReqs];
+
+ for (int i = 0; i < numReqs; i++) {
+ // decode message.
+ TaggedRequest taggedRequest =
+ (TaggedRequest) reqSequence.elementAt(i);
+
+ TaggedRequest.Type type = taggedRequest.getType();
+
+ if (type.equals(TaggedRequest.PKCS10)) {
+ CMS.debug("CMCAuth: in PKCS10");
+ TaggedCertificationRequest tcr =
+ taggedRequest.getTcr();
+ int p10Id = tcr.getBodyPartID().intValue();
+
+ reqIdArray[i] = String.valueOf(p10Id);
+
+ CertificationRequest p10 =
+ tcr.getCertificationRequest();
+
+ // transfer to sun class
+ ByteArrayOutputStream ostream =
+ new ByteArrayOutputStream();
+
+ p10.encode(ostream);
+ try {
+ PKCS10 pkcs10 =
+ new PKCS10(ostream.toByteArray());
+
+ // xxx do we need to do anything else?
+ X509CertInfo certInfo =
+ CMS.getDefaultX509CertInfo();
+
+ // fillPKCS10(certInfo,pkcs10,authToken,null);
+
+ // authToken.set(
+ // pkcs10.getSubjectPublicKeyInfo());
+
+ X500Name tempName = pkcs10.getSubjectName();
+
+ // reset value of auditCertSubject
+ if( tempName != null ) {
+ auditCertSubject =
+ tempName.toString().trim();
+ if( auditCertSubject.equals( "" ) ) {
+ auditCertSubject =
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
+ tempName.toString());
+ }
+
+ authToken.set("uid", uid);
+ authToken.set("userid", userid);
+
+ certInfoArray[i] = certInfo;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ //throw new ECMSGWException(
+ //CMSGWResources.ERROR_PKCS101, e.toString());
+
+ e.printStackTrace();
+ throw new EBaseException(e.toString());
+ }
+ } else if (type.equals(TaggedRequest.CRMF)) {
+
+ CMS.debug("CMCAuth: in CRMF");
+ try {
+ CertReqMsg crm =
+ taggedRequest.getCrm();
+ CertRequest certReq = crm.getCertReq();
+ INTEGER reqID = certReq.getCertReqId();
+ reqIdArray[i] = reqID.toString();
+ CertTemplate template = certReq.getCertTemplate();
+ Name name = template.getSubject();
+
+ // xxx do we need to do anything else?
+ X509CertInfo certInfo =
+ CMS.getDefaultX509CertInfo();
+
+ // reset value of auditCertSubject
+ if( name != null ) {
+ String ss = name.getRFC1485();
+
+ auditCertSubject = ss;
+ if( auditCertSubject.equals( "" ) ) {
+ auditCertSubject =
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT, ss);
+ authToken.set("uid", uid);
+ authToken.set("userid", userid);
+ }
+ certInfoArray[i] = certInfo;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ //throw new ECMSGWException(
+ //CMSGWResources.ERROR_PKCS101, e.toString());
+
+ e.printStackTrace();
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ // authToken.set(AgentAuthentication.CRED_CERT, new
+ // com.netscape.certsrv.usrgrp.Certificates(
+ // x509Certs));
+ }
+ }
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ //Debug.printStackTrace(e);
+ throw new EInvalidCredentials(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ return authToken;
+ } catch( EMissingCredential eAudit1 ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch( EInvalidCredentials eAudit2 ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ } catch( EBaseException eAudit3 ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo );
+
+ audit( auditMessage );
+
+ // rethrow the specific exception to be handled later
+ throw eAudit3;
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ * <p>
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * gets the configuration substore used by this authentication
+ * plug-in
+ * <p>
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the plug-in name of this authentication plug-in.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * gets the name of this authentication plug-in instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * get the list of required credentials.
+ * <p>
+ * @return list of required credentials as strings.
+ */
+ public String[] getRequiredCreds() {
+ return (mRequiredCreds);
+ }
+
+ /**
+ * prepares for shutdown.
+ */
+ public void shutdown() {
+ }
+
+ /////////////////////////////////
+ // IExtendedPluginInfo methods //
+ /////////////////////////////////
+
+ /**
+ * Activate the help system.
+ * <p>
+ * @return help messages
+ */
+ public String[] getExtendedPluginInfo() {
+ CMS.debug("CMCAuth: getExtendedPluginInfo()");
+ String[] s = Utils.getStringArrayFromVector(mExtendedPluginInfo);
+
+ CMS.debug("CMCAuth: s.length = " + s.length);
+ for (int i = 0; i < s.length; i++) {
+ CMS.debug("" + i + " " + s[i]);
+ }
+ return s;
+ }
+
+ ////////////////////
+ // Logger methods //
+ ////////////////////
+
+ /**
+ * Logs a message for this class in the system log file.
+ * <p>
+ * @param level The log level.
+ * @param msg The message to log.
+ * @see com.netscape.certsrv.logging.ILogger
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, "CMC Authentication: " + msg);
+ }
+
+ protected IAuthToken verifySignerInfo(AuthToken authToken,SignedData cmcFullReq) throws EInvalidCredentials {
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+ OBJECT_IDENTIFIER id = ci.getContentType();
+ OCTET_STRING content = ci.getContent();
+
+ try {
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SET dais = cmcFullReq.getDigestAlgorithmIdentifiers();
+ int numDig = dais.size();
+ Hashtable digs = new Hashtable();
+
+ //if request key is used for signing, there MUST be only one signerInfo
+ //object in the signedData object.
+ for (int i = 0; i < numDig; i++) {
+ AlgorithmIdentifier dai =
+ (AlgorithmIdentifier) dais.elementAt(i);
+ String name =
+ DigestAlgorithm.fromOID(dai.getOID()).toString();
+
+ MessageDigest md =
+ MessageDigest.getInstance(name);
+
+ byte[] digest = md.digest(content.toByteArray());
+
+ digs.put(name, digest);
+ }
+
+ SET sis = cmcFullReq.getSignerInfos();
+ int numSis = sis.size();
+
+ for (int i = 0; i < numSis; i++) {
+ org.mozilla.jss.pkix.cms.SignerInfo si = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
+
+ String name = si.getDigestAlgorithm().toString();
+ byte[] digest = (byte[]) digs.get(name);
+
+ if (digest == null) {
+ MessageDigest md = MessageDigest.getInstance(name);
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkiData.encode((OutputStream) ostream);
+ digest = md.digest(ostream.toByteArray());
+
+ }
+ // signed by previously certified signature key
+ SignerIdentifier sid = si.getSignerIdentifier();
+
+ if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
+ IssuerAndSerialNumber issuerAndSerialNumber = sid.getIssuerAndSerialNumber();
+ // find from the certs in the signedData
+ java.security.cert.X509Certificate cert = null;
+
+ if (cmcFullReq.hasCertificates()) {
+ SET certs = cmcFullReq.getCertificates();
+ int numCerts = certs.size();
+ java.security.cert.X509Certificate[] x509Certs = new java.security.cert.X509Certificate[1];
+ byte[] certByteArray = new byte[0];
+ for (int j = 0; j < numCerts; j++) {
+ Certificate certJss = (Certificate) certs.elementAt(j);
+ CertificateInfo certI = certJss.getInfo();
+ Name issuer = certI.getIssuer();
+
+ byte[] issuerB = ASN1Util.encode(issuer);
+ INTEGER sn = certI.getSerialNumber();
+ // if this cert is the signer cert, not a cert in the chain
+ if (new String(issuerB).equals(new String(ASN1Util.encode(issuerAndSerialNumber.getIssuer())))
+ && sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString()) )
+ {
+ ByteArrayOutputStream os = new
+ ByteArrayOutputStream();
+
+ certJss.encode(os);
+ certByteArray = os.toByteArray();
+
+ X509CertImpl tempcert = new X509CertImpl(os.toByteArray());
+
+ cert = tempcert;
+ x509Certs[0] = cert;
+ // xxx validate the cert length
+
+ }
+ }
+ CMS.debug("CMCAuth: start checking signature");
+ if (cert == null) {
+ // find from certDB
+ CMS.debug("CMCAuth: verifying signature");
+ si.verify(digest, id);
+ } else {
+ PublicKey signKey = cert.getPublicKey();
+ PrivateKey.Type keyType = null;
+ String alg = signKey.getAlgorithm();
+
+ if (alg.equals("RSA")) {
+ keyType = PrivateKey.RSA;
+ } else if (alg.equals("DSA")) {
+ keyType = PrivateKey.DSA;
+ }
+ PK11PubKey pubK = PK11PubKey.fromRaw(keyType, ((X509Key) signKey).getKey());
+
+ CMS.debug("CMCAuth: verifying signature with public key");
+ si.verify(digest, id, pubK);
+ }
+ CMS.debug("CMCAuth: finished checking signature");
+ // verify signer's certificate using the revocator
+ CryptoManager cm = CryptoManager.getInstance();
+ if( ! cm.isCertValid( certByteArray, true,CryptoManager.CertUsage.SSLClient) )
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ // authenticate signer's certificate using the userdb
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+
+ IAuthManager agentAuth = authSS.getAuthManager(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID);//AGENT_AUTHMGR_ID);
+ IAuthCredentials agentCred = new com.netscape.certsrv.authentication.AuthCredentials();
+
+ agentCred.set(IAuthManager.CRED_SSL_CLIENT_CERT, x509Certs);
+
+ IAuthToken tempToken = agentAuth.authenticate(agentCred);
+ netscape.security.x509.X500Name tempPrincipal = (X500Name) x509Certs[0].getSubjectDN();
+ String CN = (String) tempPrincipal.getCommonName();//tempToken.get("userid");
+
+ BigInteger agentCertSerial = x509Certs[0].getSerialNumber();
+ authToken.set(IAuthManager.CRED_SSL_CLIENT_CERT,agentCertSerial.toString());
+ tempToken.set("cn",CN);
+ return tempToken;
+
+ }
+ // find from internaldb if it's ca. (ra does not have that.)
+ // find from internaldb usrgrp info
+
+ if (cert == null) {
+ // find from certDB
+ si.verify(digest, id);
+ } else {
+ PublicKey signKey = cert.getPublicKey();
+ PrivateKey.Type keyType = null;
+ String alg = signKey.getAlgorithm();
+
+ if (alg.equals("RSA")) {
+ keyType = PrivateKey.RSA;
+ } else if (alg.equals("DSA")) {
+ keyType = PrivateKey.DSA;
+ } else {
+ }
+ PK11PubKey pubK = PK11PubKey.fromRaw(keyType, ((X509Key) signKey).getKey());
+
+ si.verify(digest, id, pubK);
+ }
+
+ } //
+ }
+ }catch (InvalidBERException e) {
+ CMS.debug("CMCAuth: " + e.toString());
+ } catch (IOException e) {
+ CMS.debug("CMCAuth: " + e.toString());
+ } catch (Exception e) {
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ return (IAuthToken) null;
+
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return null;
+ }
+
+ // 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_CMS_SIGN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale)
+ {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_CMS_SIGN_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+ v.addElement("cert_request");
+ return v.elements();
+ }
+
+ public boolean isValueWriteable(String name) {
+ return false;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(CRED_CMC)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null, null,
+ "CMC request");
+ }
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString(AuthToken.TOKEN_CERT_SUBJECT));
+ }
+
+ public boolean isSSLClientRequired() {
+ return false;
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ private void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ private String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/Crypt.java b/pki/base/common/src/com/netscape/cms/authentication/Crypt.java
new file mode 100644
index 000000000..950120399
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/Crypt.java
@@ -0,0 +1,437 @@
+// --- 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.authentication;
+
+
+public class Crypt {
+ // Static data:
+ static byte[]
+ IP = // Initial permutation
+ {
+ 58, 50, 42, 34, 26, 18, 10, 2,
+ 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6,
+ 64, 56, 48, 40, 32, 24, 16, 8,
+ 57, 49, 41, 33, 25, 17, 9, 1,
+ 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5,
+ 63, 55, 47, 39, 31, 23, 15, 7
+ },
+ FP = // Final permutation, FP = IP^(-1)
+ {
+ 40, 8, 48, 16, 56, 24, 64, 32,
+ 39, 7, 47, 15, 55, 23, 63, 31,
+ 38, 6, 46, 14, 54, 22, 62, 30,
+ 37, 5, 45, 13, 53, 21, 61, 29,
+ 36, 4, 44, 12, 52, 20, 60, 28,
+ 35, 3, 43, 11, 51, 19, 59, 27,
+ 34, 2, 42, 10, 50, 18, 58, 26,
+ 33, 1, 41, 9, 49, 17, 57, 25
+ },
+ // Permuted-choice 1 from the key bits to yield C and D.
+ // Note that bits 8,16... are left out:
+ // They are intended for a parity check.
+ PC1_C =
+ {
+ 57, 49, 41, 33, 25, 17, 9,
+ 1, 58, 50, 42, 34, 26, 18,
+ 10, 2, 59, 51, 43, 35, 27,
+ 19, 11, 3, 60, 52, 44, 36
+ },
+ PC1_D =
+ {
+ 63, 55, 47, 39, 31, 23, 15,
+ 7, 62, 54, 46, 38, 30, 22,
+ 14, 6, 61, 53, 45, 37, 29,
+ 21, 13, 5, 28, 20, 12, 4
+ },
+ shifts = // Sequence of shifts used for the key schedule.
+ {
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+ },
+ // Permuted-choice 2, to pick out the bits from
+ // the CD array that generate the key schedule.
+ PC2_C =
+ {
+ 14, 17, 11, 24, 1, 5,
+ 3, 28, 15, 6, 21, 10,
+ 23, 19, 12, 4, 26, 8,
+ 16, 7, 27, 20, 13, 2
+ },
+ PC2_D =
+ {
+ 41, 52, 31, 37, 47, 55,
+ 30, 40, 51, 45, 33, 48,
+ 44, 49, 39, 56, 34, 53,
+ 46, 42, 50, 36, 29, 32
+ },
+ e2 = // The E-bit selection table. (see E below)
+ {
+ 32, 1, 2, 3, 4, 5,
+ 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13,
+ 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21,
+ 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29,
+ 28, 29, 30, 31, 32, 1
+ },
+ // P is a permutation on the selected combination of
+ // the current L and key.
+ P =
+ {
+ 16, 7, 20, 21,
+ 29, 12, 28, 17,
+ 1, 15, 23, 26,
+ 5, 18, 31, 10,
+ 2, 8, 24, 14,
+ 32, 27, 3, 9,
+ 19, 13, 30, 6,
+ 22, 11, 4, 25
+ };
+ // The 8 selection functions. For some reason, they gave a 0-origin
+ // index, unlike everything else.
+ static byte[][] S =
+ {
+ {
+ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
+ }, {
+ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
+ }, {
+ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
+ }, {
+ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
+ }, {
+ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
+ }, {
+ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
+ }, {
+ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
+ }, {
+ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
+ }
+ };
+
+ // Dynamic data:
+ byte[] C = new byte[28], // The C and D arrays used to
+ D = new byte[28], // calculate the key schedule.
+ E = new byte[48], // The E bit-selection table.
+ L = new byte[32], // The current block,
+ R = new byte[32], // divided into two halves.
+ tempL = new byte[32],
+ f = new byte[32],
+ preS = new byte[48]; // The combination of the key and
+ // the input, before selection.
+ // The key schedule. Generated from the key.
+ byte[][] KS = new byte[16][48];
+
+ // Object fields:
+ String Passwd, Salt, Encrypt;
+
+ // Public methods:
+ /**
+ * Create Crypt object with no passwd or salt set. Must use setPasswd()
+ * and setSalt() before getEncryptedPasswd().
+ */
+ public Crypt() {
+ Passwd = Salt = Encrypt = "";
+ }
+
+ /**
+ * Create a Crypt object with specified salt. Use setPasswd() before
+ * getEncryptedPasswd().
+ *
+ * @param salt the salt string for encryption
+ */
+ public Crypt(String salt) {
+ Passwd = "";
+ Salt = salt;
+ Encrypt = crypt();
+ }
+
+ /**
+ * Create a Crypt object with specified passwd and salt (often the
+ * already encypted passwd). Get the encrypted result with
+ * getEncryptedPasswd().
+ *
+ * @param passwd the passwd to encrypt
+ * @param salt the salt string for encryption
+ */
+ public Crypt(String passwd, String salt) {
+ Passwd = passwd;
+ Salt = salt;
+ Encrypt = crypt();
+ }
+
+ /**
+ * Retrieve the passwd string currently being encrypted.
+ *
+ * @return the current passwd string
+ */
+ public String getPasswd() {
+ return Passwd;
+ }
+
+ /**
+ * Retrieve the salt string currently being used for encryption.
+ *
+ * @return the current salt string
+ */
+ public String getSalt() {
+ return Salt;
+ }
+
+ /**
+ * Retrieve the resulting encrypted string from the current passwd and
+ * salt settings.
+ *
+ * @return the encrypted passwd
+ */
+ public String getEncryptedPasswd() {
+ return Encrypt;
+ }
+
+ /**
+ * Set a new passwd string for encryption. Use getEncryptedPasswd() to
+ * retrieve the new result.
+ *
+ * @param passwd the new passwd string
+ */
+ public void setPasswd(String passwd) {
+ Passwd = passwd;
+ Encrypt = crypt();
+ }
+
+ /**
+ * Set a new salt string for encryption. Use getEncryptedPasswd() to
+ * retrieve the new result.
+ *
+ * @param salt the new salt string
+ */
+ public void setSalt(String salt) {
+ Salt = salt;
+ Encrypt = crypt();
+ }
+
+ // Internal crypt methods:
+ String crypt() {
+ if (Salt.length() == 0) return "";
+ int i, j, pwi;
+ byte c, temp;
+ byte[] block = new byte[66],
+ iobuf = new byte[16],
+ salt = new byte[2],
+ pw = Passwd.getBytes(), //jdk1.1
+ saltbytes = Salt.getBytes(); //jdk1.1
+
+ // pw = new byte[Passwd.length()], //jdk1.0.2
+ // saltbytes = new byte[Salt.length()]; //jdk1.0.2
+ //Passwd.getBytes(0,Passwd.length(),pw,0); //jdk1.0.2
+ //Salt.getBytes(0,Salt.length(),saltbytes,0); //jdk1.0.2
+
+ salt[0] = saltbytes[0];
+ salt[1] = (saltbytes.length > 1) ? saltbytes[1] : 0;
+
+ for (i = 0; i < 66; i++)
+ block[i] = 0;
+
+ for (i = 0, pwi = 0; (pwi < pw.length) && (i < 64); pwi++, i++) {
+ for (j = 0; j < 7; j++, i++) {
+ block[i] = (byte) ((pw[pwi] >> (6 - j)) & 1);
+ }
+ }
+
+ setkey(block);
+
+ for (i = 0; i < 66; i++)
+ block[i] = 0;
+
+ for (i = 0; i < 2; i++) {
+ c = salt[i];
+ iobuf[i] = c;
+ if (c > 'Z') c -= 6;
+ if (c > '9') c -= 7;
+ c -= '.';
+ for (j = 0; j < 6; j++) {
+ if (((c >> j) & 1) != 0) {
+ temp = E[6 * i + j];
+ E[6 * i + j] = E[6 * i + j + 24];
+ E[6 * i + j + 24] = temp;
+ }
+ }
+ }
+
+ for (i = 0; i < 25; i++) {
+ encrypt(block, 0);
+ }
+
+ for (i = 0; i < 11; i++) {
+ c = 0;
+ for (j = 0; j < 6; j++) {
+ c <<= 1;
+ c |= block[6 * i + j];
+ }
+ c += '.';
+ if (c > '9') c += 7;
+ if (c > 'Z') c += 6;
+ iobuf[i + 2] = c;
+ }
+
+ iobuf[i + 2] = 0;
+ if (iobuf[1] == 0)
+ iobuf[1] = iobuf[0];
+
+ return new String(iobuf); //jdk1.1
+ //return new String(iobuf,0); //jdk1.0.2
+ }
+
+ void setkey(byte[] key) // Set up the key schedule from the key.
+ {
+ int i, j, k;
+ byte t;
+
+ // First, generate C and D by permuting the key. The low order bit
+ // of each 8-bit char is not used, so C and D are only 28 bits apiece.
+ for (i = 0; i < 28; i++) {
+ C[i] = key[PC1_C[i] - 1];
+ D[i] = key[PC1_D[i] - 1];
+ }
+
+ // To generate Ki, rotate C and D according to schedule
+ // and pick up a permutation using PC2.
+ for (i = 0; i < 16; i++) {
+ // rotate.
+ for (k = 0; k < shifts[i]; k++) {
+ t = C[0];
+ for (j = 0; j < 27; j++)
+ C[j] = C[j + 1];
+ C[27] = t;
+ t = D[0];
+ for (j = 0; j < 27; j++)
+ D[j] = D[j + 1];
+ D[27] = t;
+ }
+
+ // get Ki. Note C and D are concatenated.
+ for (j = 0; j < 24; j++) {
+ KS[i][j] = C[PC2_C[j] - 1];
+ KS[i][j + 24] = D[PC2_D[j] - 29];
+ }
+ }
+
+ for (i = 0; i < 48; i++) {
+ E[i] = e2[i];
+ }
+ }
+
+ // The payoff: encrypt a block.
+ void encrypt(byte[] block, int edflag) {
+ int i, j, ii, t;
+ byte k;
+
+ // First, permute the bits in the input
+ //for (j = 0; j < 64; j++)
+ //{
+ // L[j] = block[IP[j]-1];
+ //}
+ for (j = 0; j < 32; j++)
+ L[j] = block[IP[j] - 1];
+ for (j = 32; j < 64; j++)
+ R[j - 32] = block[IP[j] - 1];
+
+ // Perform an encryption operation 16 times.
+ for (ii = 0; ii < 16; ii++) {
+ i = ii;
+ // Save the R array, which will be the new L.
+ for (j = 0; j < 32; j++)
+ tempL[j] = R[j];
+ // Expand R to 48 bits using the E selector;
+ // exclusive-or with the current key bits.
+ for (j = 0; j < 48; j++)
+ preS[j] = (byte) (R[E[j] - 1] ^ KS[i][j]);
+
+ // The pre-select bits are now considered in 8 groups of
+ // 6 bits each. The 8 selection functions map these 6-bit
+ // quantities into 4-bit quantities and the results permuted
+ // to make an f(R, K). The indexing into the selection functions
+ // is peculiar; it could be simplified by rewriting the tables.
+ for (j = 0; j < 8; j++) {
+ t = 6 * j;
+ k = S[j][ (preS[t ] << 5) +
+ (preS[t + 1] << 3) +
+ (preS[t + 2] << 2) +
+ (preS[t + 3] << 1) +
+ (preS[t + 4]) +
+ (preS[t + 5] << 4) ];
+ t = 4 * j;
+ f[t ] = (byte) ((k >> 3) & 1);
+ f[t + 1] = (byte) ((k >> 2) & 1);
+ f[t + 2] = (byte) ((k >> 1) & 1);
+ f[t + 3] = (byte) ((k) & 1);
+ }
+
+ // The new R is L ^ f(R, K).
+ // The f here has to be permuted first, though.
+ for (j = 0; j < 32; j++) {
+ R[j] = (byte) (L[j] ^ f[P[j] - 1]);
+ }
+
+ // Finally, the new L (the original R) is copied back.
+ for (j = 0; j < 32; j++) {
+ L[j] = tempL[j];
+ }
+ }
+
+ // The output L and R are reversed.
+ for (j = 0; j < 32; j++) {
+ k = L[j];
+ L[j] = R[j];
+ R[j] = k;
+ }
+
+ // The final output gets the inverse permutation of the very original.
+ for (j = 0; j < 64; j++) {
+ //block[j] = L[FP[j]-1];
+ block[j] = (FP[j] > 32) ? R[FP[j] - 33] : L[FP[j] - 1];
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/DNPattern.java b/pki/base/common/src/com/netscape/cms/authentication/DNPattern.java
new file mode 100644
index 000000000..80d51c4f5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/DNPattern.java
@@ -0,0 +1,211 @@
+// --- 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.authentication;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.publish.*;
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a certificate
+ * subject name from ldap attributes and dn.<p>
+ *
+ * dnpattern is a string representing a subject name pattern to formulate from
+ * the directory attributes and entry dn. If empty or not set, the
+ * ldap entry DN will be used as the certificate subject name. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$attr" "." attrName [ "." attrNumber ] |
+ * name "=" "$dn" "." attrName [ "." attrNumber ] |
+ * "$dn" "." "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US </i>
+ * Ldap entry: dn: UID=jjames, OU=IS, OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example2: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * <pre>
+ * Example3: <i>CN=$attr.cn, $rdn.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=IS+OU=people, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * followed by the second RDN in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example4: <i>CN=$attr.cn, OU=$dn.ou.2+OU=$dn.ou.1, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=people+OU=IS, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN followed by the
+ * first 'ou' value in the user's entry. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * If an attribute or subject DN component does not exist the attribute
+ * is skipped.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DNPattern {
+
+ /* ldap attributes to retrieve */
+ private String[] mLdapAttrs = null;
+
+ /* rdn patterns */
+ protected RDNPattern[] mRDNPatterns = null;
+
+ /* original pattern string */
+ protected String mPatternString = null;
+
+ protected String mTestDN = null;
+
+ /**
+ * Construct a DN pattern by parsing a pattern string.
+ * @param pattern the DN pattern
+ * @exception EBaseException If parsing error occurs.
+ */
+ public DNPattern(String pattern)
+ throws EAuthException {
+ if (pattern == null || pattern.equals("")) {
+ // create an attribute list that is the dn.
+ mLdapAttrs = new String[] { "dn" };
+ } else {
+ mPatternString = pattern;
+ PushbackReader in = new PushbackReader(new StringReader(pattern));
+
+ parse(in);
+ }
+ }
+
+ public DNPattern(PushbackReader in)
+ throws EAuthException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws EAuthException {
+ Vector rdnPatterns = new Vector();
+ RDNPattern rdnPattern = null;
+ int lastChar = -1;
+
+ do {
+ rdnPattern = new RDNPattern(in);
+ rdnPatterns.addElement(rdnPattern);
+ try {
+ lastChar = in.read();
+ } catch (IOException e) {
+ throw new EAuthException("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString());
+ }
+ }
+ while (lastChar == ',');
+
+ mRDNPatterns = new RDNPattern[rdnPatterns.size()];
+ rdnPatterns.copyInto(mRDNPatterns);
+
+ Vector ldapAttrs = new Vector();
+
+ for (int i = 0; i < mRDNPatterns.length; i++) {
+ String[] rdnAttrs = mRDNPatterns[i].getLdapAttrs();
+
+ if (rdnAttrs != null && rdnAttrs.length > 0)
+ for (int j = 0; j < rdnAttrs.length; j++)
+ ldapAttrs.addElement(rdnAttrs[j]);
+ }
+ mLdapAttrs = new String[ldapAttrs.size()];
+ ldapAttrs.copyInto(mLdapAttrs);
+ }
+
+ /**
+ * Form a Ldap v3 DN string from results of a ldap search.
+ * @param entry LDAPentry from a ldap search
+ * @return Ldap v3 DN string to use for a subject name.
+ */
+ public String formDN(LDAPEntry entry)
+ throws EAuthException {
+ StringBuffer formedDN = new StringBuffer();
+
+ for (int i = 0; i < mRDNPatterns.length; i++) {
+ if (mTestDN != null)
+ mRDNPatterns[i].mTestDN = mTestDN;
+ String rdn = mRDNPatterns[i].formRDN(entry);
+
+ if (rdn != null) {
+ if (rdn != null && rdn.length() != 0) {
+ if (formedDN.length() != 0)
+ formedDN.append(",");
+ formedDN.append(rdn);
+ }
+ }
+ }
+ //System.out.println("formed DN "+formedDN.toString());
+ return formedDN.toString();
+ }
+
+ public String[] getLdapAttrs() {
+ return (String[]) mLdapAttrs.clone();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java
new file mode 100644
index 000000000..1b1394175
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java
@@ -0,0 +1,657 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cmsutil.util.*;
+
+// cert server x509 imports
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateExtensions;
+import java.security.cert.CertificateException;
+
+// java sdk imports.
+import java.util.Locale;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Date;
+import java.io.IOException;
+
+
+/**
+ * Abstract class for directory based authentication managers
+ * Uses a pattern for formulating subject names.
+ * The pattern is read from configuration file.
+ * Syntax of the pattern is described in the init() method.
+ *
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public abstract class DirBasedAuthentication
+ implements IAuthManager, IExtendedPluginInfo {
+
+ protected static final String USER_DN = "userDN";
+
+ /* configuration parameter keys */
+ protected static final String PROP_LDAP = "ldap";
+ protected static final String PROP_BASEDN = "basedn";
+ protected static final String PROP_DNPATTERN = "dnpattern";
+ protected static final String PROP_LDAPSTRINGATTRS = "ldapStringAttributes";
+ protected static final String PROP_LDAPBYTEATTRS = "ldapByteAttributes";
+
+ // members
+
+ /* name of this authentication manager instance */
+ protected String mName = null;
+
+ /* name of the authentication manager plugin */
+ protected String mImplName = null;
+
+ /* configuration store */
+ protected IConfigStore mConfig;
+
+ /* ldap configuration sub-store */
+ protected IConfigStore mLdapConfig;
+
+ /* ldap base dn */
+ protected String mBaseDN = null;
+
+ /* factory of anonymous ldap connections */
+ protected ILdapConnFactory mConnFactory = null;
+
+ /* the system logger */
+ protected ILogger mLogger = CMS.getLogger();
+
+ /* the subject DN pattern */
+ protected DNPattern mPattern = null;
+
+ /* the list of LDAP attributes with string values to retrieve to
+ * save in the auth token including ones from the dn pattern. */
+ protected String[] mLdapStringAttrs = null;
+
+ /* the list of LDAP attributes with byte[] values to retrive to save
+ * in authtoken. */
+ protected String[] mLdapByteAttrs = null;
+
+ /* the combined list of LDAP attriubutes to retrieve*/
+ protected String[] mLdapAttrs = null;
+
+ /* default dn pattern if left blank or not set in the config */
+ protected static String DEFAULT_DNPATTERN =
+ "E=$attr.mail, CN=$attr.cn, O=$dn.o, C=$dn.c";
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+
+ static {
+ mExtendedPluginInfo = new Vector();
+ mExtendedPluginInfo.add(PROP_DNPATTERN + ";string;Template for cert" +
+ " Subject Name. ($dn.xxx - get value from user's LDAP " +
+ "DN. $attr.yyy - get value from LDAP attributes in " +
+ "user's entry.) Default: " + DEFAULT_DNPATTERN);
+ mExtendedPluginInfo.add(PROP_LDAPSTRINGATTRS + ";string;" +
+ "Comma-separated list of LDAP attributes to copy from " +
+ "the user's LDAP entry into the AuthToken. e.g use " +
+ "'mail' to copy user's email address for subjectAltName");
+ mExtendedPluginInfo.add(PROP_LDAPBYTEATTRS + ";string;" +
+ "Comma-separated list of binary LDAP attributes to copy" +
+ " from the user's LDAP entry into the AuthToken");
+ mExtendedPluginInfo.add("ldap.ldapconn.host;string,required;" +
+ "LDAP host to connect to");
+ mExtendedPluginInfo.add("ldap.ldapconn.port;number,required;" +
+ "LDAP port number (use 389, or 636 if SSL)");
+ mExtendedPluginInfo.add("ldap.ldapconn.secureConn;boolean;" +
+ "Use SSL to connect to directory?");
+ mExtendedPluginInfo.add("ldap.ldapconn.version;choice(3,2);" +
+ "LDAP protocol version");
+ mExtendedPluginInfo.add("ldap.basedn;string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here");
+ mExtendedPluginInfo.add("ldap.minConns;number;number of connections " +
+ "to keep open to directory server. Default 5.");
+ mExtendedPluginInfo.add("ldap.maxConns;number;when needed, connection " +
+ "pool can grow to this many (multiplexed) connections. Default 1000.");
+ }
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public DirBasedAuthentication() {
+ }
+
+ /**
+ * Initializes the UidPwdDirBasedAuthentication auth manager.
+ *
+ * Takes the following configuration parameters: <br>
+ * <pre>
+ * ldap.basedn - the ldap base dn.
+ * ldap.ldapconn.host - the ldap host.
+ * ldap.ldapconn.port - the ldap port
+ * ldap.ldapconn.secureConn - whether port should be secure
+ * ldap.minConns - minimum connections
+ * ldap.maxConns - max connections
+ * dnpattern - dn pattern.
+ * </pre>
+ * <p>
+ * <i><b>dnpattern</b></i> is a string representing a subject name pattern
+ * to formulate from the directory attributes and entry dn. If empty or
+ * not set, the ldap entry DN will be used as the certificate subject name.
+ * <p>
+ * The syntax is
+ * <pre>
+ * dnpattern = SubjectNameComp *[ "," SubjectNameComp ]
+ *
+ * SubjectNameComponent = DnComp | EntryComp | ConstantComp
+ * DnComp = CertAttr "=" "$dn" "." DnAttr "." Num
+ * EntryComp = CertAttr "=" "$attr" "." EntryAttr "." Num
+ * ConstantComp = CertAttr "=" Constant
+ * DnAttr = an attribute in the Ldap entry dn
+ * EntryAttr = an attribute in the Ldap entry
+ * CertAttr = a Component in the Certificate Subject Name
+ * (multiple AVA in one RDN not supported)
+ * Num = the nth value of tha attribute in the dn or entry.
+ * Constant = Constant String, with any accepted ldap string value.
+ *
+ * </pre>
+ * <p>
+ * <b>Example:</b>
+ * <pre>
+ * dnpattern:
+ * E=$attr.mail.1, CN=$attr.cn, OU=$attr.ou.2, O=$dn.o, C=US
+ * <br>
+ * Ldap entry dn:
+ * UID=joesmith, OU=people, O=Acme.com
+ * <br>
+ * Ldap attributes:
+ * cn: Joe Smith
+ * sn: Smith
+ * mail: joesmith@acme.com
+ * mail: joesmith@redhat.com
+ * ou: people
+ * ou: IS
+ * <i>etc.</i>
+ * </pre>
+ * <p>
+ * The subject name formulated in the cert will be : <br>
+ * <pre>
+ * E=joesmith@acme.com, CN=Joe Smith, OU=Human Resources, O=Acme.com, C=US
+ *
+ * E = the first 'mail' ldap attribute value in user's entry - joesmithe@acme.com
+ * CN = the (first) 'cn' ldap attribute value in the user's entry - Joe Smith
+ * OU = the second 'ou' value in the ldap entry - IS
+ * O = the (first) 'o' value in the user's entry DN - "Acme.com"
+ * C = the constant string "US"
+ * </pre>
+ *
+ * @param name The name for this authentication manager instance.
+ * @param implName The name of the authentication manager plugin.
+ * @param config - The configuration store for this instance.
+ * @exception EBaseException If an error occurs during initialization.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ init(name, implName, config, true);
+ }
+
+ public void init(String name, String implName, IConfigStore config, boolean needBaseDN)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ /* initialize ldap server configuration */
+ mLdapConfig = mConfig.getSubStore(PROP_LDAP);
+ if (needBaseDN) mBaseDN = mLdapConfig.getString(PROP_BASEDN);
+ if (needBaseDN && ((mBaseDN == null) || (mBaseDN.length() == 0) || (mBaseDN.trim().equals(""))))
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn"));
+ mConnFactory = CMS.getLdapAnonConnFactory();
+ mConnFactory.init(mLdapConfig);
+
+ /* initialize dn pattern */
+ String pattern = mConfig.getString(PROP_DNPATTERN, null);
+
+ if (pattern == null || pattern.length() == 0)
+ pattern = DEFAULT_DNPATTERN;
+ mPattern = new DNPattern(pattern);
+ String[] patternLdapAttrs = mPattern.getLdapAttrs();
+
+ /* initialize ldap string attribute list */
+ String ldapStringAttrs = mConfig.getString(PROP_LDAPSTRINGATTRS, null);
+
+ if (ldapStringAttrs == null) {
+ mLdapStringAttrs = patternLdapAttrs;
+ } else {
+ StringTokenizer pAttrs =
+ new StringTokenizer(ldapStringAttrs, ",", false);
+ int begin = 0;
+
+ if (patternLdapAttrs != null && patternLdapAttrs.length > 0) {
+ mLdapStringAttrs = new String[
+ patternLdapAttrs.length + pAttrs.countTokens()];
+ System.arraycopy(patternLdapAttrs, 0,
+ mLdapStringAttrs, 0, patternLdapAttrs.length);
+ begin = patternLdapAttrs.length;
+ } else {
+ mLdapStringAttrs = new String[pAttrs.countTokens()];
+ }
+ for (int i = begin; i < mLdapStringAttrs.length; i++) {
+ mLdapStringAttrs[i] = ((String) pAttrs.nextElement()).trim();
+ }
+ }
+
+ /* initialize ldap byte[] attribute list */
+ String ldapByteAttrs = mConfig.getString(PROP_LDAPBYTEATTRS, null);
+
+ if (ldapByteAttrs == null) {
+ mLdapByteAttrs = new String[0];
+ } else {
+ StringTokenizer byteAttrs =
+ new StringTokenizer(ldapByteAttrs, ",", false);
+
+ mLdapByteAttrs = new String[byteAttrs.countTokens()];
+ for (int j = 0; j < mLdapByteAttrs.length; j++) {
+ mLdapByteAttrs[j] = ((String) byteAttrs.nextElement()).trim();
+ }
+ }
+
+ /* make the combined list */
+ mLdapAttrs =
+ new String[mLdapStringAttrs.length + mLdapByteAttrs.length];
+ System.arraycopy(mLdapStringAttrs, 0, mLdapAttrs,
+ 0, mLdapStringAttrs.length);
+ System.arraycopy(mLdapByteAttrs, 0, mLdapAttrs,
+ mLdapStringAttrs.length, mLdapByteAttrs.length);
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_INIT_DONE"));
+ }
+
+ /**
+ * gets the name of this authentication manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the plugin name of this authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * Authenticates user through LDAP by a set of credentials.
+ * Resulting AuthToken a TOKEN_CERTINFO field of a X509CertInfo
+ * <p>
+ * @param authCred Authentication credentials, CRED_UID and CRED_PWD.
+ * @return A AuthToken with a TOKEN_SUBJECT of X500name type.
+ * @exception com.netscape.certsrv.authentication.EMissingCredential
+ * If a required authentication credential is missing.
+ * @exception com.netscape.certsrv.authentication.EInvalidCredentials
+ * If credentials failed authentication.
+ * @exception com.netscape.certsrv.base.EBaseException
+ * If an internal error occurred.
+ * @see com.netscape.certsrv.authentication.AuthToken
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ String userdn = null;
+ LDAPConnection conn = null;
+ AuthToken authToken = new AuthToken(this);
+
+ try {
+ if (mConnFactory == null) {
+ conn = null;
+ } else {
+ conn = mConnFactory.getConn();
+ }
+
+ // authenticate the user and get a user entry.
+ userdn = authenticate(conn, authCred, authToken);
+ authToken.set(USER_DN, userdn);
+
+ // formulate the cert info.
+ // set each seperatly since otherwise they won't serialize
+ // in the request queue.
+ X509CertInfo certInfo = new X509CertInfo();
+
+ formCertInfo(conn, userdn, certInfo, authToken);
+
+ // set subject name.
+ try {
+ CertificateSubjectName subjectname = (CertificateSubjectName)
+ certInfo.get(X509CertInfo.SUBJECT);
+
+ if (subjectname != null)
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
+ subjectname.toString());
+ } // error means it's not set.
+ catch (CertificateException e) {
+ } catch (IOException e) {
+ }
+
+ // set validity if any
+ try {
+ CertificateValidity validity = (CertificateValidity)
+ certInfo.get(X509CertInfo.VALIDITY);
+
+ if (validity != null) {
+ // the gets throws IOException but only if attribute
+ // not recognized. In these cases they are always.
+ authToken.set(AuthToken.TOKEN_CERT_NOTBEFORE,
+ (Date)validity.get(CertificateValidity.NOT_BEFORE));
+ authToken.set(AuthToken.TOKEN_CERT_NOTAFTER,
+ (Date)validity.get(CertificateValidity.NOT_AFTER));
+ }
+ } // error means it's not set.
+ catch (CertificateException e) {
+ } catch (IOException e) {
+ }
+
+ // set extensions if any.
+ try {
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null)
+ authToken.set(AuthToken.TOKEN_CERT_EXTENSIONS, extensions);
+ } // error means it's not set.
+ catch (CertificateException e) {
+ } catch (IOException e) {
+ }
+
+ } finally {
+ if (conn != null)
+ mConnFactory.returnConn(conn);
+ }
+
+ return authToken;
+ }
+
+ /**
+ * get the list of required credentials.
+ * @return list of required credentials as strings.
+ */
+ public abstract String[] getRequiredCreds();
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public abstract String[] getConfigParams();
+
+ /**
+ * disconnects the ldap connections
+ */
+ public void shutdown() {
+ try {
+ if (mConnFactory != null) {
+ mConnFactory.reset();
+ mConnFactory = null;
+ }
+ } catch (ELdapException e) {
+ // ignore
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_SHUTDOWN_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Gets the configuration substore used by this authentication manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Authenticates a user through directory based a set of credentials.
+ *
+ * @param authCreds The authentication credentials.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the uid and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected abstract String authenticate(
+ LDAPConnection conn, IAuthCredentials authCreds, AuthToken token)
+ throws EBaseException;
+
+ /**
+ * Formulate the cert info.
+ *
+ * @param conn A LDAP Connection authenticated to user to use.
+ * @param userdn The user's dn.
+ * @param certinfo A certinfo object to fill.
+ * @param token A authentication token to fill.
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected void formCertInfo(LDAPConnection conn,
+ String userdn,
+ X509CertInfo certinfo,
+ AuthToken token)
+ throws EBaseException {
+ String dn = null;
+ // get ldap attributes to retrieve.
+ String[] attrs = getLdapAttrs();
+
+ // retrieve the attributes.
+ try {
+ if (conn != null) {
+ LDAPEntry entry = null;
+ LDAPSearchResults results =
+ conn.search(userdn, LDAPv2.SCOPE_BASE, "objectclass=*",
+ attrs, false);
+
+ if (!results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_ATTR_ERROR"));
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_LDAPATTRIBUTES_NOT_FOUND"));
+ }
+ entry = results.next();
+
+ // formulate the subject dn
+ try {
+ dn = formSubjectName(entry);
+ } catch (EBaseException e) {
+ //e.printStackTrace();
+ throw e;
+ }
+ // Put selected values from the entry into the token
+ setAuthTokenValues(entry, token);
+ } else {
+ dn = userdn;
+ }
+
+ // add anything else in cert info such as validity, extensions
+ // (nothing now)
+
+ // pack the dn into X500name and set subject name.
+ if (dn.length() == 0) {
+ EBaseException ex =
+ new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_EMPTY_DN_FORMED", mName));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_DN_ERROR", ex.toString()));
+ throw ex;
+ }
+ X500Name subjectdn = new X500Name(dn);
+
+ certinfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subjectdn));
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.SERVER_DOWN:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_AUTH_ATTR_ERROR"));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_USER_ENTRY_ERROR", userdn));
+
+ // fall to below.
+ default:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.toString()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_OTHER_LDAP_EXCEPTION",
+ e.errorCodeToString()));
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_CREATE_SUBJECT_ERROR", userdn, e.getMessage()));
+ throw new EFormSubjectDN(CMS.getUserMessage("CMS_AUTHENTICATION_FORM_SUBJECTDN_ERROR"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_CREATE_CERTINFO_ERROR", userdn, e.getMessage()));
+ throw new EFormSubjectDN(CMS.getUserMessage("CMS_AUTHENTICATION_FORM_SUBJECTDN_ERROR"));
+ }
+ }
+
+ /**
+ * Copy values from the LDAPEntry into the AuthToken. The
+ * list of values that should be store this way is given in
+ * a the ldapAttributes configuration parameter.
+ */
+ protected void setAuthTokenValues(LDAPEntry e, AuthToken tok) {
+ for (int i = 0; i < mLdapStringAttrs.length; i++)
+ setAuthTokenStringValue(mLdapStringAttrs[i], e, tok);
+ for (int j = 0; j < mLdapByteAttrs.length; j++)
+ setAuthTokenByteValue(mLdapByteAttrs[j], e, tok);
+ }
+
+ protected void setAuthTokenStringValue(
+ String name, LDAPEntry entry, AuthToken tok) {
+ LDAPAttribute values = entry.getAttribute(name);
+
+ if (values == null) return;
+
+ Vector v = new Vector();
+ Enumeration e = values.getStringValues();
+
+ while (e.hasMoreElements()) {
+ v.addElement(e.nextElement());
+ }
+
+ String a[] = new String[v.size()];
+
+ v.copyInto(a);
+
+ tok.set(name, a);
+ }
+
+ protected void setAuthTokenByteValue(
+ String name, LDAPEntry entry, AuthToken tok) {
+ LDAPAttribute values = entry.getAttribute(name);
+
+ if (values == null) return;
+
+ Vector v = new Vector();
+ Enumeration e = values.getByteValues();
+
+ while (e.hasMoreElements()) {
+ v.addElement(e.nextElement());
+ }
+
+ byte[][] a = new byte[v.size()][];
+
+ v.copyInto(a);
+
+ tok.set(name, a);
+ }
+
+ /**
+ * Return a list of LDAP attributes with String values to retrieve.
+ * Subclasses can override to return any set of attributes.
+ * @return Array of LDAP attributes to retrieve from the directory.
+ */
+ protected String[] getLdapAttrs() {
+ return mLdapAttrs;
+ }
+
+ /**
+ * Return a list of LDAP attributes with byte[] values to retrieve.
+ * Subclasses can override to return any set of attributes.
+ * @return Array of LDAP attributes to retrieve from the directory.
+ */
+ protected String[] getLdapByteAttrs() {
+ return mLdapByteAttrs;
+ }
+
+ /**
+ * Formulate the subject name
+ * @param entry The LDAP entry
+ * @return The subject name string.
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected String formSubjectName(LDAPEntry entry)
+ throws EAuthException {
+ if (mPattern.mPatternString == null)
+ return entry.getDN();
+
+ /*
+ if (mTestDNString != null) {
+ mPattern.mTestDN = mTestDNString;
+ //System.out.println("Set DNPattern.mTestDN to "+mPattern.mTestDN);
+ }
+ */
+
+ String dn = mPattern.formDN(entry);
+
+ CMS.debug("DirBasedAuthentication: formed DN '" + dn + "'");
+ return dn;
+ }
+
+ /**
+ * Logs a message for this class in the system log file.
+ * @param level The log level.
+ * @param msg The message to log.
+ * @see com.netscape.certsrv.logging.ILogger
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] s = Utils.getStringArrayFromVector(mExtendedPluginInfo);
+
+ return s;
+
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java b/pki/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java
new file mode 100644
index 000000000..a03b298e6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java
@@ -0,0 +1,678 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.logging.ILogger;
+
+
+/**
+ * This represents the authentication manager that authenticates
+ * user against a file where id, and password are stored.
+ *
+ * @version $Revision$, $Date$
+ */
+public class FlatFileAuth
+ implements IProfileAuthenticator, IExtendedPluginInfo {
+
+ /* configuration parameter keys */
+ protected static final String PROP_FILENAME = "fileName";
+ protected static final String PROP_KEYATTRIBUTES = "keyAttributes";
+ protected static final String PROP_AUTHATTRS = "authAttributes";
+ protected static final String PROP_DEFERONFAILURE = "deferOnFailure";
+
+ protected String mFilename = "config/pwfile";
+ protected long mFileLastRead = 0;
+ protected String mKeyAttributes = "UID";
+ protected String mAuthAttrs = "PWD";
+ protected boolean mDeferOnFailure = true;
+ private static final String DATE_PATTERN = "yyyy-MM-dd-HH-mm-ss";
+ private static SimpleDateFormat mDateFormat = new SimpleDateFormat(DATE_PATTERN);
+
+ protected static String[] mConfigParams =
+ new String[] {
+ PROP_FILENAME,
+ PROP_KEYATTRIBUTES,
+ PROP_AUTHATTRS,
+ PROP_DEFERONFAILURE
+ };
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ PROP_FILENAME + ";string;Pathname of password file",
+ PROP_KEYATTRIBUTES + ";string;Comma-separated list of attributes" +
+ " which together form a unique identifier for the user",
+ PROP_AUTHATTRS + ";string;Comma-separated list of attributes" +
+ " which are used for further authentication",
+ PROP_DEFERONFAILURE + ";boolean;if user is not found, defer the " +
+ "request to the queue for manual-authentication (true), or " +
+ "simply rejected the request (false)"
+ };
+
+ return s;
+ }
+
+ /** name of this authentication manager instance */
+ protected String mName = null;
+
+ protected String FFAUTH = "FlatFileAuth";
+
+ /** name of the authentication manager plugin */
+ protected String mImplName = null;
+
+ /** configuration store */
+ protected IConfigStore mConfig = null;
+
+ /** system logger */
+ protected ILogger mLogger = CMS.getLogger();
+
+ /** This array is created as to include all the requested attributes
+ *
+ */
+ String[] reqCreds = null;
+
+ String[] authAttrs = null;
+ String[] keyAttrs = null;
+
+ /** Hashtable of entries from Auth File. Hash index is the
+ * concatenation of the attributes from matchAttributes property
+ */
+ protected Hashtable entries = null;
+
+ /**
+ * Get the named property
+ * If the property is not set, use s as the default, and create
+ * a new value for the property in the config file.
+ *
+ * @param propertyName Property name
+ * @param s The default value of the property
+ */
+ protected String getPropertyS(String propertyName, String s)
+ throws EBaseException {
+ String p;
+
+ try {
+ p = mConfig.getString(propertyName);
+ } catch (EPropertyNotFound e) {
+ mConfig.put(propertyName, s);
+ p = s;
+ }
+ return p;
+ }
+
+ public boolean isSSLClientRequired() {
+ return false;
+ }
+
+ /**
+ * Get the named property,
+ * If the property is not set, use b as the default, and create
+ * a new value for the property in the config file.
+ *
+ * @param propertyName Property name
+ * @param b The default value of the property
+ */
+ protected boolean getPropertyB(String propertyName, boolean b)
+ throws EBaseException {
+ boolean p;
+
+ try {
+ p = mConfig.getBoolean(propertyName);
+ } catch (EPropertyNotFound e) {
+ mConfig.put(propertyName, b ? "true" : "false");
+ p = b;
+ }
+ return p;
+ }
+
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ try {
+ mFilename = getPropertyS(PROP_FILENAME, mFilename);
+ mKeyAttributes = getPropertyS(PROP_KEYATTRIBUTES, mKeyAttributes);
+ mAuthAttrs = getPropertyS(PROP_AUTHATTRS, mAuthAttrs);
+ mDeferOnFailure = getPropertyB(PROP_DEFERONFAILURE, mDeferOnFailure);
+ } catch (EBaseException e) {
+ return;
+ }
+
+ keyAttrs = splitOnComma(mKeyAttributes);
+ authAttrs = splitOnComma(mAuthAttrs);
+
+ String[][] stringArrays = new String[2][];
+
+ stringArrays[0] = keyAttrs;
+ stringArrays[1] = authAttrs;
+ reqCreds = unionOfStrings(stringArrays);
+
+ print("mFilename = " + mFilename);
+ print("mKeyAttributes = " + mKeyAttributes);
+ print("mAuthAttrs = " + mAuthAttrs);
+ for (int i = 0; i < stringArrays.length; i++) {
+ for (int j = 0; j < stringArrays[i].length; j++) {
+ print("stringArrays[" + i + "][" + j + "] = " + stringArrays[i][j]);
+ }
+ }
+
+ try {
+ File file = new File(mFilename);
+
+ mFileLastRead = file.lastModified();
+ entries = readFile(file, keyAttrs);
+ CMS.debug("FlatFileAuth: " + CMS.getLogMessage("CMS_AUTH_READ_ENTRIES", mFilename));
+ // printAllEntries();
+ } catch (IOException e) {
+ throw new EBaseException(mName + " authentication: Could not open file " + mFilename + " (" + e.getMessage() + ")");
+ } catch (java.lang.StringIndexOutOfBoundsException ee) {
+ CMS.debug("FlatFileAuth: " + CMS.getLogMessage("OPERATION_ERROR", ee.toString()));
+ }
+
+ }
+
+ /**
+ * Log a message.
+ * @param level The logging level.
+ * @param msg The message to log.
+ */
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+ void print(String s) {
+ CMS.debug("FlatFileAuth: " + s);
+ }
+
+ /**
+ * Return a string array which is the union of all the string arrays
+ * passed in. The strings are treated as case sensitive
+ */
+
+ public String[] unionOfStrings(String[][] stringArrays) {
+ Hashtable ht = new Hashtable();
+
+ for (int i = 0; i < stringArrays.length; i++) {
+ String[] sa = stringArrays[i];
+
+ for (int j = 0; j < sa.length; j++) {
+ print("unionOfStrings: " + i + "," + j + " = " + sa[j]);
+ ht.put(sa[j], "");
+ }
+ }
+
+ String[] s = new String[ht.size()];
+ Enumeration e = ht.keys();
+
+ for (int i = 0; e.hasMoreElements(); i++) {
+ s[i] = (String) e.nextElement();
+ }
+ return s;
+
+ }
+
+ /**
+ * Split a comma-delimited String into an array of individual
+ * Strings.
+ */
+ private String[] splitOnComma(String s) {
+ print("Splitting String: " + s + " on commas");
+ StringTokenizer st = new StringTokenizer(s, ",", false);
+ String[] sa = new String[st.countTokens()];
+
+ print(" countTokens:" + st.countTokens());
+
+ for (int i = 0; i < sa.length; i++) {
+ String p = st.nextToken().trim();
+
+ print(" token " + i + " = " + p);
+ sa[i] = p;
+ }
+
+ return sa;
+ }
+
+ /**
+ * Join an array of Strings into one string, with
+ * the specified string between each string
+ */
+
+ private String joinStringArray(String[] s, String sep) {
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < s.length; i++) {
+ sb.append(s[i]);
+ if (i < (s.length - 1)) {
+ sb.append(sep);
+ }
+ }
+ return sb.toString();
+ }
+
+ private synchronized void updateFile (String key) {
+ try {
+ String name = writeFile (key);
+ if (name != null) {
+ File orgFile = new File(mFilename);
+ long lastModified = orgFile.lastModified();
+ File newFile = new File(name);
+ if (lastModified > mFileLastRead) {
+ mFileLastRead = lastModified;
+ } else {
+ mFileLastRead = newFile.lastModified();
+ }
+ if (orgFile.renameTo(new File(name.substring(0, name.length()-1)))) {
+ if (!newFile.renameTo(new File(mFilename))) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("RENAME_FILE_ERROR", name, mFilename));
+ File file = new File(name.substring(0, name.length()-1));
+ file.renameTo(new File(mFilename));
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("RENAME_FILE_ERROR", mFilename,
+ name.substring(0, name.length()-1)));
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("FILE_ERROR", e.getMessage()));
+ }
+ }
+
+ private String writeFile (String key) {
+ BufferedReader reader = null;
+ BufferedWriter writer = null;
+ String name = null;
+ boolean commentOutNextLine = false;
+ boolean done = false;
+ String line = null;
+ try {
+ reader = new BufferedReader (new FileReader (mFilename));
+ name = mFilename+"."+mDateFormat.format(new Date())+"~";
+ writer = new BufferedWriter (new FileWriter(name));
+ if (reader != null && writer != null) {
+ while ((line = reader.readLine()) != null) {
+ if (commentOutNextLine) {
+ writer.write("#");
+ commentOutNextLine = false;
+ }
+ if (line.indexOf(key) > -1) {
+ writer.write("#");
+ commentOutNextLine = true;
+ }
+ writer.write(line);
+ writer.newLine();
+ }
+ done = true;
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("FILE_ERROR", e.getMessage()));
+ }
+
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ if (writer != null) {
+ writer.flush();
+ writer.close();
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("FILE_ERROR", e.getMessage()));
+ }
+
+ try {
+ if (!done) {
+ long s1 = 0;
+ long s2 = 0;
+ File f1 = new File(mFilename);
+ File f2 = new File(name);
+ if (f1.exists()) s1 = f1.length();
+ if (f2.exists()) s2 = f2.length();
+ if (s1 > 0 && s2 > 0 && s2 > s1) {
+ done = true;
+ } else {
+ if (f2.exists()) f2.delete();
+ name = null;
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("FILE_ERROR", e.getMessage()));
+ }
+
+ return name;
+ }
+
+
+ /**
+ * Read a file with the following format: <p><pre>
+ * param1: valuea
+ * param2: valueb
+ * -blank-line-
+ * param1: valuec
+ * param2: valued
+ * </pre>
+ *
+ * @param f The file to read
+ * @param keys The parameters to concat together to form the hash
+ * key
+ * @return a hashtable of hashtables.
+ */
+ protected Hashtable readFile(File f, String[] keys)
+ throws IOException {
+ log(ILogger.LL_INFO, "Reading file: " + f.getName());
+ BufferedReader file = new BufferedReader(
+ new FileReader(f)
+ );
+
+ String line;
+ Hashtable allusers = new Hashtable();
+ Hashtable entry = null;
+ int linenum = 0;
+
+ while ((line = file.readLine()) != null) {
+ linenum++;
+ line = line.trim();
+ if (line.length() > 0 && line.charAt(0) == '#') {
+ continue;
+ }
+ int colon = line.indexOf(':');
+
+ if (entry == null) {
+ entry = new Hashtable();
+ }
+
+ if (colon == -1) { // no colon -> empty line signifies end of record
+ if (!line.trim().equals("")) {
+ if (file != null) {
+ file.close();
+ }
+ throw new IOException(FFAUTH + ": Parsing error, " +
+ "colon missing from line " + linenum + " of " + f.getName());
+ }
+ if (entry.size() > 0) {
+ putEntry(allusers, entry, keys);
+ entry = null;
+ }
+ continue;
+ }
+
+ String attr = line.substring(0, colon).trim();
+ String val = line.substring(colon + 1).trim();
+
+ entry.put(attr, val);
+ }
+
+ putEntry(allusers, entry, keys);
+ if (file != null) {
+ file.close();
+ }
+ return allusers;
+ }
+
+ private void putEntry(Hashtable allUsers,
+ Hashtable entry,
+ String[] keys) {
+ if (entry == null) {
+ return;
+ }
+ String key = "";
+
+ print("keys.length = " + keys.length);
+ for (int i = 0; i < keys.length; i++) {
+ String s = (String) entry.get(keys[i]);
+
+ print(" concatenating: " + s);
+ if (s != null) {
+ key = key.concat(s);
+ }
+ }
+ print("putting: key " + key);
+ allUsers.put(key, entry);
+ }
+
+ void printAllEntries() {
+ Enumeration e = entries.keys();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ print("* " + key + " *");
+ Hashtable ht = (Hashtable) entries.get(key);
+ Enumeration f = ht.keys();
+
+ while (f.hasMoreElements()) {
+ String fkey = (String) f.nextElement();
+
+ print(" " + fkey + " -> " + ht.get(fkey));
+ }
+ }
+ }
+
+ /**
+ * Compare attributes provided by the user with those in
+ * in flat file.
+ *
+ */
+
+ private IAuthToken doAuthentication(Hashtable user, IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ AuthToken authToken = new AuthToken(this);
+
+ for (int i = 0; i < authAttrs.length; i++) {
+ String ffvalue = (String) user.get(authAttrs[i]);
+ String uservalue = (String) authCred.get(authAttrs[i]);
+
+ // print("checking authentication token (" + authAttrs[i] + ": " + uservalue + " against ff value: " + ffvalue);
+ if (!ffvalue.equals(uservalue)) {
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ }
+ return authToken;
+ }
+
+ private void reReadPwFile() {
+
+ try {
+ File file = new File(mFilename);
+ long pwfilelastmodified = file.lastModified();
+
+ if (pwfilelastmodified > mFileLastRead) {
+ mFileLastRead = pwfilelastmodified;
+ entries = readFile(file, keyAttrs);
+ // printAllEntries();
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("READ_FILE_ERROR", mFilename, e.getMessage()));
+ }
+ }
+
+ /**
+ * Authenticate the request
+ *
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ IAuthToken authToken = null;
+ String keyForUser = "";
+
+ /* First check if hashtable has been modified since we last read it in */
+
+ reReadPwFile();
+
+ /* Find the user in our hashtable */
+
+ for (int i = 0; i < keyAttrs.length; i++) {
+ print("concatenating string i=" + i + " keyAttrs[" + i + "] = " + keyAttrs[i]);
+ String credential = (String) authCred.get(keyAttrs[i]);
+
+ if (credential == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", keyAttrs[i]));
+ }
+ keyForUser = keyForUser.concat((String) authCred.get(keyAttrs[i]));
+ }
+ print("authenticating user: finding user from key: " + keyForUser);
+
+ Hashtable user = (Hashtable) entries.get(keyForUser);
+
+ try {
+ if (user != null) {
+ authToken = doAuthentication(user, authCred);
+ } else {
+ CMS.debug("FlatFileAuth: " + CMS.getLogMessage("CMS_AUTH_USER_NOT_FOUND"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ } catch (EInvalidCredentials e) {
+ // If defer on failure is false, then we re-throw the exception
+ // which causes the request to be rejected
+ if (!mDeferOnFailure) {
+ throw e;
+ } else {
+ CMS.debug("FlatFileAuth: Since defering on failure - ignore invalid creds");
+ }
+ }
+
+ // if a dn was specified in the password file for this user,
+ // replace the requested dn with the one in the pwfile
+ if (user != null) {
+ String dn = (String) user.get("dn");
+
+ if (dn != null && authToken != null) {
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT, dn);
+ }
+ }
+
+ // If defer on failure is true, and the auth failed, authToken will
+ // be null here, which causes the request to be deferred.
+
+ if (user != null && authToken != null) {
+ entries.remove(keyForUser);
+ updateFile(keyForUser);
+ // printAllEntries();
+ }
+ return authToken;
+ }
+
+ /**
+ * Return a list of HTTP parameters which will be taken from the
+ * request posting and placed into the AuthCredentials block
+ *
+ * Note that this method will not be called until after the
+ * init() method is called
+ */
+ public String[] getRequiredCreds() {
+ print("getRequiredCreds returning: " + joinStringArray(reqCreds, ","));
+ return reqCreds;
+
+ }
+
+ /**
+ * Returns a list of configuration parameters, so the console
+ * can prompt the user when configuring.
+ */
+ public String[] getConfigParams() {
+ return mConfigParams;
+ }
+
+ /**
+ * Returns the configuration store used by this authentication manager
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void shutdown() {
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getImplName() {
+ return mImplName;
+ }
+
+ 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_AGENT_NAME");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ return null;
+ }
+
+ public boolean isValueWriteable(String name) {
+ return false;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_AGENT_TEXT");
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/HashAuthData.java b/pki/base/common/src/com/netscape/cms/authentication/HashAuthData.java
new file mode 100644
index 000000000..fe05dec9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/HashAuthData.java
@@ -0,0 +1,117 @@
+// --- 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.authentication;
+
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.io.IOException;
+
+
+/**
+ * The structure stores the information of which machine is enabled for
+ * the agent-initiated user enrollment, and whom agents enable this feature,
+ * and the value of the timeout.
+ * <P>
+ * @version $Revision$, $Date$
+ */
+public class HashAuthData extends Hashtable {
+
+ public static final long TIMEOUT = 600000;
+ public static final long LASTLOGIN = 0;
+
+ public HashAuthData() {
+ }
+
+ public String getAgentName(String hostname) {
+ Vector val = (Vector) get(hostname);
+
+ if (val != null)
+ return (String) val.elementAt(0);
+ return null;
+ }
+
+ public void setAgentName(String hostname, String agentName) {
+ Vector val = (Vector) get(hostname);
+
+ if (val == null) {
+ val = new Vector();
+ put(hostname, val);
+ }
+ val.setElementAt(agentName, 0);
+ }
+
+ public long getTimeout(String hostname) {
+ Vector val = (Vector) get(hostname);
+
+ if (val != null) {
+ return ((Long) val.elementAt(1)).longValue();
+ }
+ return TIMEOUT;
+ }
+
+ public void setTimeout(String hostname, long timeout) {
+ Vector val = (Vector) get(hostname);
+
+ if (val == null) {
+ val = new Vector();
+ put(hostname, val);
+ }
+ val.setElementAt(Long.valueOf(timeout), 1);
+ }
+
+ public String getSecret(String hostname) {
+ Vector val = (Vector) get(hostname);
+
+ if (val != null) {
+ return (String) val.elementAt(2);
+ }
+ return null;
+ }
+
+ public void setSecret(String hostname, String secret) {
+ Vector val = (Vector) get(hostname);
+
+ if (val == null) {
+ val = new Vector();
+ put(hostname, val);
+ }
+ val.setElementAt(secret, 2);
+ }
+
+ public long getLastLogin(String hostname) {
+ Vector val = (Vector) get(hostname);
+
+ if (val != null) {
+ return ((Long) val.elementAt(3)).longValue();
+ }
+ return LASTLOGIN;
+ }
+
+ public void setLastLogin(String hostname, long lastLogin) {
+ Vector val = (Vector) get(hostname);
+
+ if (val == null) {
+ val = new Vector();
+ put(hostname, val);
+ }
+ val.setElementAt(Long.valueOf(lastLogin), 3);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/HashAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/HashAuthentication.java
new file mode 100644
index 000000000..12ea8f041
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/HashAuthentication.java
@@ -0,0 +1,290 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cmsutil.util.*;
+
+// cert server x509 imports
+import netscape.security.x509.*;
+import java.security.cert.*;
+import java.security.*;
+
+// java sdk imports.
+import java.util.*;
+import java.io.IOException;
+
+
+/**
+ * Hash uid/pwd directory based authentication manager
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class HashAuthentication implements IAuthManager, IExtendedPluginInfo {
+
+ public static final String SALT = "lala123";
+ public static final String CRED_UID = "uid";
+ public static final String CRED_FINGERPRINT = "fingerprint";
+ public static final String CRED_PAGEID = "pageID";
+ public static final String CRED_HOST = "hostname";
+ protected static String[] mRequiredCreds = { CRED_UID,
+ CRED_PAGEID, CRED_FINGERPRINT, CRED_HOST };
+ public static final long DEFAULT_TIMEOUT = 600000;
+ private boolean mEnable = false;
+ private long mTimeout = DEFAULT_TIMEOUT; // in milliseconds
+ private String mSecret;
+ private int mPageID;
+ private String mHost;
+ private long mLastLogin = 0;
+ private MessageDigest mSHADigest = null;
+ private Hashtable mData = null;
+ private IConfigStore mConfig;
+ private String mName = null;
+ private String mImplName = null;
+ private ILogger mLogger = CMS.getLogger();
+ private static Vector mExtendedPluginInfo = null;
+ private HashAuthData mHosts = null;
+
+ static String[] mConfigParams =
+ new String[] {};
+
+ static {
+ mExtendedPluginInfo = new Vector();
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TEXT +
+ ";Authenticate the username and password provided " +
+ "by the user against an LDAP directory. Works with the " +
+ "Dir Based Enrollment HTML form");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authrules-uidpwddirauth");
+ };
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public HashAuthentication() {
+ }
+
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+ mData = new Hashtable();
+ mHosts = new HashAuthData();
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.getMessage()));
+ }
+
+ }
+
+ public IAuthToken getAuthToken(String key) {
+ return (IAuthToken) mData.remove(key);
+ }
+
+ public void addAuthToken(String pageID, IAuthToken token) {
+ mData.put(pageID, token);
+ }
+
+ public void deleteToken(String pageID) {
+ IAuthToken token = (IAuthToken) mData.remove(pageID);
+ }
+
+ public HashAuthData getData() {
+ return mHosts;
+ }
+
+ public void createEntry(String host, String dn, long timeout,
+ String secret, long lastLogin) {
+ Vector v = new Vector();
+
+ v.addElement(dn);
+ v.addElement(Long.valueOf(timeout));
+ v.addElement(secret);
+ v.addElement(Long.valueOf(lastLogin));
+ mHosts.put(host, v);
+ }
+
+ public void disable(String hostname) {
+ mHosts.remove(hostname);
+ }
+
+ public String getAgentName(String hostname) {
+ return mHosts.getAgentName(hostname);
+ }
+
+ public void setAgentName(String hostname, String agentName) {
+ mHosts.setAgentName(hostname, agentName);
+ }
+
+ public boolean isEnable(String hostname) {
+ return mHosts.containsKey(hostname);
+ }
+
+ public long getTimeout(String hostname) {
+ return mHosts.getTimeout(hostname);
+ }
+
+ public void setTimeout(String hostname, long timeout) {
+ mHosts.setTimeout(hostname, timeout);
+ }
+
+ public String getSecret(String hostname) {
+ return mHosts.getSecret(hostname);
+ }
+
+ public void setSecret(String hostname, String secret) {
+ mHosts.setSecret(hostname, secret);
+ }
+
+ public long getLastLogin(String hostname) {
+ return mHosts.getLastLogin(hostname);
+ }
+
+ public void setLastLogin(String hostname, long lastlogin) {
+ mHosts.setLastLogin(hostname, lastlogin);
+ }
+
+ public long getPageID() {
+ Date date = new Date();
+
+ return date.getTime();
+ }
+
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+ public boolean validFingerprint(String host, String pageID, String uid, String fingerprint) {
+ String val = hashFingerprint(host, pageID, uid);
+
+ if (val.equals(fingerprint))
+ return true;
+ return false;
+ }
+
+ public Enumeration getHosts() {
+ return mHosts.keys();
+ }
+
+ public String hashFingerprint(String host, String pageID, String uid) {
+ byte[] hash =
+ mSHADigest.digest((SALT + pageID + getSecret(host) + uid).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(hash);
+
+ return "{SHA}" + b64E;
+ }
+
+ public void shutdown() {
+ }
+
+ /**
+ * Authenticates a user based on uid, pwd in the directory.
+ *
+ * @param authCreds The authentication credentials.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the uid and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ public IAuthToken authenticate(IAuthCredentials authCreds)
+ throws EBaseException {
+ AuthToken token = new AuthToken(this);
+ String fingerprint = (String) authCreds.get(CRED_FINGERPRINT);
+ String pageID = (String) authCreds.get(CRED_PAGEID);
+ String uid = (String) authCreds.get(CRED_UID);
+ String host = (String) authCreds.get(CRED_HOST);
+
+ if (fingerprint.equals("") ||
+ !validFingerprint(host, pageID, uid, fingerprint)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_INVALID_FINGER_PRINT"));
+ throw new EAuthException("Invalid Fingerprint");
+ }
+
+ // set uid in the token.
+ token.set(CRED_UID, uid);
+
+ return token;
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+ /**
+ * Gets the configuration substore used by this authentication manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the name of this authentication manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the plugin name of this authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] s = Utils.getStringArrayFromVector(mExtendedPluginInfo);
+
+ return s;
+
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/PortalEnroll.java b/pki/base/common/src/com/netscape/cms/authentication/PortalEnroll.java
new file mode 100644
index 000000000..9f49c2fd1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/PortalEnroll.java
@@ -0,0 +1,458 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.BaseResources;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+
+// java sdk imports.
+import java.util.Locale;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.StringTokenizer;
+import java.io.IOException;
+
+
+/**
+ * uid/pwd directory based authentication manager
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PortalEnroll extends DirBasedAuthentication {
+
+ /* configuration parameter keys */
+ protected static final String PROP_LDAPAUTH = "ldapauth";
+ protected static final String PROP_AUTHTYPE = "authtype";
+ protected static final String PROP_BINDDN = "bindDN";
+ protected static final String PROP_BINDPW = "bindPW";
+ protected static final String PROP_LDAPCONN = "ldapconn";
+ protected static final String PROP_HOST = "host";
+ protected static final String PROP_PORT = "port";
+ protected static final String PROP_SECURECONN = "secureConn";
+ protected static final String PROP_VERSION = "version";
+ protected static final String PROP_OBJECTCLASS = "objectclass";
+
+ /* required credentials to authenticate. uid and pwd are strings. */
+ public static final String CRED_UID = "uid";
+ public static final String CRED_PWD = "userPassword";
+ protected static String[] mRequiredCreds = { CRED_UID, CRED_PWD };
+
+ /* ldap configuration sub-store */
+ private IArgBlock argblk = null;
+ private String mObjectClass = null;
+ private String mBindDN = null;
+ private String mBaseDN = null;
+ private ILdapConnFactory mLdapFactory = null;
+ private LDAPConnection mLdapConn = null;
+
+ // contains all nested superiors' required attrs in the form of a
+ // vector of "required" attributes in Enumeration
+ Vector mRequiredAttrs = null;
+
+ // contains all nested superiors' optional attrs in the form of a
+ // vector of "optional" attributes in Enumeration
+ Vector mOptionalAttrs = null;
+
+ // contains all the objclasses, including superiors and itself
+ Vector mObjClasses = null;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {
+ PROP_DNPATTERN,
+ "ldap.ldapconn.host",
+ "ldap.ldapconn.port",
+ "ldap.ldapconn.secureConn",
+ "ldap.ldapconn.version",
+ "ldap.ldapauth.bindDN",
+ "ldap.ldapauth.bindPWPrompt",
+ "ldap.ldapauth.clientCertNickname",
+ "ldap.ldapauth.authtype",
+ "ldap.basedn",
+ "ldap.objectclass",
+ "ldap.minConns",
+ "ldap.maxConns",
+ };
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public PortalEnroll()
+ throws EBaseException {
+ super();
+ }
+
+ /**
+ * Initializes the PortalEnrollment auth manager.
+ * <p>
+ * @param name - The name for this authentication manager instance.
+ * @param implName - The name of the authentication manager plugin.
+ * @param config - The configuration store for this instance.
+ * @exception EBaseException If an error occurs during initialization.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ super.init(name, implName, config);
+
+ /* Get Bind DN for directory server */
+ mConfig = mLdapConfig.getSubStore(PROP_LDAPAUTH);
+ mBindDN = mConfig.getString(PROP_BINDDN);
+ if ( (mBindDN == null) || (mBindDN.length() == 0) || (mBindDN == ""))
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "binddn"));
+
+ /* Get Bind DN for directory server */
+ mBaseDN = mLdapConfig.getString(PROP_BASEDN);
+ if ((mBaseDN == null) || (mBaseDN.length() == 0) || (mBaseDN == ""))
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn"));
+
+ /* Get Object clase name for enrollment */
+ mObjectClass = mLdapConfig.getString(PROP_OBJECTCLASS);
+ if (mObjectClass == null || mObjectClass.length() == 0)
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "objectclass"));
+
+ /* Get connect parameter */
+ mLdapFactory = CMS.getLdapBoundConnFactory();
+ mLdapFactory.init(mLdapConfig);
+ mLdapConn = mLdapFactory.getConn();
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_PORTAL_INIT"));
+ }
+
+ /**
+ * Authenticates a user based on uid, pwd in the directory.
+ *
+ * @param authCreds The authentication credentials.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the uid and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected String authenticate(LDAPConnection conn,
+ IAuthCredentials authCreds,
+ AuthToken token)
+ throws EBaseException {
+ String uid = null;
+ String pwd = null;
+ String dn = null;
+
+ argblk = authCreds.getArgBlock();
+
+ // authenticate by binding to ldap server with password.
+ try {
+ // get the uid.
+ uid = (String) authCreds.get(CRED_UID);
+ if (uid == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID));
+ }
+
+ // get the password.
+ pwd = (String) authCreds.get(CRED_PWD);
+ if (pwd == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD));
+ }
+ if (pwd.equals("")) {
+ // anonymous binding not allowed
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // get user dn.
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", "UID already exists."));
+ } else {
+ dn = regist(token, uid);
+ if (dn == null)
+ throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE","Could not add user " + uid + "."));
+ }
+
+ // bind as user dn and pwd - authenticates user with pwd.
+ conn.authenticate(dn, pwd);
+
+ // set uid in the token.
+ token.set(CRED_UID, uid);
+
+ log(ILogger.LL_INFO, "portal authentication is done");
+
+ return dn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.toString()));
+ throw e;
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_ADD_USER_ERROR", conn.getHost(), Integer.toString(conn.getPort())));
+ throw new
+ EAuthInternalError(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", "Check Configuration detail."));
+
+ case LDAPException.INVALID_CREDENTIALS:
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMS_AUTH_BAD_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.SERVER_DOWN:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_SERVER_DOWN"));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+
+ default:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.getMessage()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_OTHER_LDAP_EXCEPTION",
+ e.errorCodeToString()));
+ }
+ } catch (EBaseException e) {
+ if (e.getMessage().equalsIgnoreCase(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND")) == true)
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_MAKE_DN_ERROR", e.toString()));
+ throw e;
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] s = {
+ PROP_DNPATTERN + ";string;Template for cert" +
+ " Subject Name. ($dn.xxx - get value from user's LDAP " +
+ "DN. $attr.yyy - get value from LDAP attributes in " +
+ "user's entry.) Default: " + DEFAULT_DNPATTERN,
+ "ldap.ldapconn.host;string,required;" + "LDAP host to connect to",
+ "ldap.ldapconn.port;number,required;" + "LDAP port number (default 389, or 636 if SSL)",
+ "ldap.objectclass;string,required;SEE DOCUMENTATION for Object Class. "
+ + "Default is inetOrgPerson.",
+ "ldap.ldapconn.secureConn;boolean;" + "Use SSL to connect to directory?",
+ "ldap.ldapconn.version;choice(3,2);" + "LDAP protocol version",
+ "ldap.ldapauth.bindDN;string,required;DN to bind as for Directory Manager. "
+ + "For example 'CN=Directory Manager'",
+ "ldap.ldapauth.bindPWPrompt;password;Enter password used to bind as " +
+ "the above user",
+ "ldap.ldapauth.authtype;choice(BasicAuth,SslClientAuth);"
+ + "How to bind to the directory (for pin removal only)",
+ "ldap.ldapauth.clientCertNickname;string;If you want to use "
+ + "SSL client auth to the directory, set the client "
+ + "cert nickname here",
+ "ldap.basedn;string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here",
+ "ldap.minConns;number;number of connections " +
+ "to keep open to directory server",
+ "ldap.maxConns;number;when needed, connection " +
+ "pool can grow to this many connections",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This authentication plugin checks to see if a user " +
+ "exists in the directory. If not, then the user is created " +
+ "with the requested password.",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-authrules-portalauth"
+ };
+
+ return s;
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+ /**
+ * adds a user to the directory.
+ * @return dn upon success and null upon failure.
+ * @param token authentication token
+ * @param uid the user's id.
+ */
+ public String regist(AuthToken token, String uid) {
+ String dn = "uid=" + uid + "," + mBaseDN;
+
+ /* Specify the attributes of the entry */
+ Vector objectclass_values = null;
+
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ LDAPAttribute attr = new LDAPAttribute("objectclass");
+
+ // initialized to new
+ mRequiredAttrs = new Vector();
+ mOptionalAttrs = new Vector();
+ mObjClasses = new Vector();
+
+ LDAPSchema dirSchema = null;
+
+ try {
+
+ /* Construct a new LDAPSchema object to hold
+ the schema that you want to retrieve. */
+ dirSchema = new LDAPSchema();
+
+ /* Get the schema from the Directory. Anonymous access okay. */
+ dirSchema.fetchSchema(mLdapConn);
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.getMessage()));
+ }
+ // complete mRequiredAttrs, mOptionalAttrs, and mObjClasses
+ initLdapAttrs(dirSchema, mObjectClass);
+
+ objectclass_values = mObjClasses;
+ for (int i = objectclass_values.size() - 1; i >= 0; i--)
+ attr.addValue((String) objectclass_values.elementAt(i));
+ attrs.add(attr);
+
+ Enumeration objClasses = mRequiredAttrs.elements();
+ Enumeration attrnames = null;
+
+ while (objClasses.hasMoreElements()) {
+ attrnames = (Enumeration) objClasses.nextElement();
+ CMS.debug("PortalEnroll: Required attrs:");
+ while (attrnames.hasMoreElements()) {
+ String attrname = (String) attrnames.nextElement();
+ String attrval = null;
+
+ CMS.debug("PortalEnroll: attrname is: " + attrname);
+ if (attrname.equalsIgnoreCase("objectclass") == true)
+ continue;
+ try {
+ attrval = (String) argblk.getValueAsString(attrname);
+ } catch (EBaseException e) {
+ if (e.getMessage().equalsIgnoreCase(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND")) == true)
+ continue;
+ }
+
+ CMS.debug("PortalEnroll: " + attrname + " = " + attrval);
+ attrs.add(new LDAPAttribute(attrname, attrval));
+ }
+
+ }
+
+ objClasses = mOptionalAttrs.elements();
+ attrnames = null;
+
+ while (objClasses.hasMoreElements()) {
+ attrnames = (Enumeration) objClasses.nextElement();
+ CMS.debug("PortalEnroll: Optional attrs:");
+ while (attrnames.hasMoreElements()) {
+ String attrname = (String) attrnames.nextElement();
+ String attrval = null;
+
+ CMS.debug("PortalEnroll: attrname is: " + attrname);
+ try {
+ attrval = (String) argblk.getValueAsString(attrname);
+ } catch (EBaseException e) {
+ if (e.getMessage().equalsIgnoreCase(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND")) == true)
+ continue;
+ }
+ CMS.debug("PortalEnroll: " + attrname + " = " + attrval);
+ if (attrval != null) {
+ attrs.add(new LDAPAttribute(attrname, attrval));
+ }
+ }
+ }
+
+ /* Create an entry with this DN and these attributes */
+ LDAPEntry entry = new LDAPEntry(dn, attrs);
+
+ try {
+
+ /* Now add the entry to the directory */
+ mLdapConn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.getMessage()));
+ } else
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.getMessage()));
+ return null;
+ }
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_REGISTRATION_DONE"));
+
+ return dn;
+ }
+
+ /*
+ * get the superiors of "inetOrgPerson" so the "required
+ * attributes", "optional qttributes", and "object classes" are complete;
+ * should build up
+ * mRequiredAttrs, mOptionalAttrs, and mObjClasses when returned
+ */
+ public void initLdapAttrs(LDAPSchema dirSchema, String oclass) {
+ CMS.debug("PortalEnroll: in initLdapAttrsAttrs");
+ mObjClasses.addElement(oclass);
+ if (oclass.equalsIgnoreCase("top"))
+ return;
+
+ try {
+
+ /* Get and print the def. of the object class. */
+ LDAPObjectClassSchema objClass = dirSchema.getObjectClass(oclass);
+
+ if (objClass != null) {
+ mRequiredAttrs.add(objClass.getRequiredAttributes());
+ mOptionalAttrs.add(objClass.getOptionalAttributes());
+ } else {
+ return;
+ }
+
+ CMS.debug("PortalEnroll: getting superiors for: " + oclass);
+ String superiors[] = objClass.getSuperiors();
+
+ CMS.debug("PortalEnroll: got superiors, superiors.length=" + superiors.length);
+ if (superiors.length == 0)
+ return;
+ for (int i = 0; i < superiors.length; i++) {
+ CMS.debug("Portalenroll: superior" + i + "=" + superiors[i]);
+ objClass = dirSchema.getObjectClass(superiors[i]);
+ initLdapAttrs(dirSchema, superiors[i]);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR", e.getMessage()));
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/RDNPattern.java b/pki/base/common/src/com/netscape/cms/authentication/RDNPattern.java
new file mode 100644
index 000000000..ee011b0e2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/RDNPattern.java
@@ -0,0 +1,227 @@
+// --- 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.authentication;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.publish.*;
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a certificate
+ * subject name from ldap attributes and dn.<p>
+ *
+ * dnpattern is a string representing a subject name pattern to formulate from
+ * the directory attributes and entry dn. If empty or not set, the
+ * ldap entry DN will be used as the certificate subject name. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$attr" "." attrName [ "." attrNumber ] |
+ * name "=" "$dn" "." attrName [ "." attrNumber ] |
+ * "$dn" "." "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US </i>
+ * Ldap entry: dn: UID=jjames, OU=IS, OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example2: <i>E=$attr.mail.1, CN=$attr.cn, OU=$dn.ou.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * E=jjames@acme.org, CN=Jesse James, OU=people, O=acme.org, C=US
+ * <p>
+ * E = the first 'mail' ldap attribute value in user's entry. <br>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * <pre>
+ * Example3: <i>CN=$attr.cn, $rdn.2, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=IS+OU=people, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * followed by the second RDN in the user's entry DN. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * Example4: <i>CN=$attr.cn, OU=$dn.ou.2+OU=$dn.ou.1, O=$dn.o, C=US</i>
+ * Ldap entry: dn: UID=jjames, OU=IS+OU=people, O=acme.org
+ * Ldap attributes: cn: Jesse James
+ * Ldap attributes: mail: jjames@acme.org
+ * <p>
+ * The subject name formulated will be : <br>
+ * CN=Jesse James, OU=people+OU=IS, O=acme.org, C=US
+ * <p>
+ * CN = the (first) 'cn' ldap attribute value in the user's entry. <br>
+ * OU = the second 'ou' value in the user's entry DN followed by the
+ * first 'ou' value in the user's entry. note multiple AVAs
+ * in a RDN in this example. <br>
+ * O = the (first) 'o' value in the user's entry DN. <br>
+ * C = the string "US"
+ * <p>
+ * </pre>
+ * If an attribute or subject DN component does not exist the attribute
+ * is skipped.
+ *
+ * @version $Revision$, $Date$
+ */
+class RDNPattern {
+
+ /* ldap attributes needed by this RDN (to retrieve from ldap) */
+ private String[] mLdapAttrs = null;
+
+ /* AVA patterns */
+ protected AVAPattern[] mAVAPatterns = null;
+
+ /* original pattern string */
+ protected String mPatternString = null;
+
+ protected String mTestDN = null;
+
+ /**
+ * Construct a DN pattern by parsing a pattern string.
+ * @param pattenr the DN pattern
+ * @exception EBaseException If parsing error occurs.
+ */
+ public RDNPattern(String pattern)
+ throws EAuthException {
+ if (pattern == null || pattern.equals("")) {
+ // create an attribute list that is the dn.
+ mLdapAttrs = new String[] { "dn" };
+ } else {
+ mPatternString = pattern;
+ PushbackReader in = new PushbackReader(new StringReader(pattern));
+
+ parse(in);
+ }
+ }
+
+ /**
+ * Construct a DN pattern from a input stream of pattern
+ */
+ public RDNPattern(PushbackReader in)
+ throws EAuthException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws EAuthException {
+ //System.out.println("_________ begin rdn _________");
+ Vector avaPatterns = new Vector();
+ AVAPattern avaPattern = null;
+ int lastChar;
+
+ do {
+ avaPattern = new AVAPattern(in);
+ avaPatterns.addElement(avaPattern);
+ //System.out.println("added AVAPattern"+
+ //" mType "+avaPattern.mType+
+ //" mAttr "+avaPattern.mAttr+
+ //" mValue "+avaPattern.mValue+
+ //" mElement "+avaPattern.mElement);
+ try {
+ lastChar = in.read();
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ }
+ while (lastChar == '+');
+
+ if (lastChar != -1) {
+ try {
+ in.unread(lastChar); // pushback last ,
+ } catch (IOException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ mAVAPatterns = new AVAPattern[avaPatterns.size()];
+ avaPatterns.copyInto(mAVAPatterns);
+
+ Vector ldapAttrs = new Vector();
+
+ for (int i = 0; i < mAVAPatterns.length; i++) {
+ String avaAttr = mAVAPatterns[i].getLdapAttr();
+
+ if (avaAttr == null || avaAttr.length() == 0)
+ continue;
+ ldapAttrs.addElement(avaAttr);
+ }
+ mLdapAttrs = new String[ldapAttrs.size()];
+ ldapAttrs.copyInto(mLdapAttrs);
+ }
+
+ /**
+ * Form a Ldap v3 DN string from results of a ldap search.
+ * @param entry LDAPentry from a ldap search
+ * @return Ldap v3 DN string to use for a subject name.
+ */
+ public String formRDN(LDAPEntry entry)
+ throws EAuthException {
+ StringBuffer formedRDN = new StringBuffer();
+
+ for (int i = 0; i < mAVAPatterns.length; i++) {
+ if (mTestDN != null)
+ mAVAPatterns[i].mTestDN = mTestDN;
+ String ava = mAVAPatterns[i].formAVA(entry);
+
+ if (ava != null && ava.length() > 0) {
+ if (formedRDN.length() != 0)
+ formedRDN.append("+");
+ formedRDN.append(ava);
+ }
+ }
+ //System.out.println("formed RDN "+formedRDN.toString());
+ return formedRDN.toString();
+ }
+
+ public String[] getLdapAttrs() {
+ return (String[]) mLdapAttrs.clone();
+ }
+}
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/authentication/SharedSecret.java b/pki/base/common/src/com/netscape/cms/authentication/SharedSecret.java
new file mode 100644
index 000000000..98bf72f47
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/SharedSecret.java
@@ -0,0 +1,36 @@
+// --- 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.authentication;
+
+import java.math.BigInteger;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import com.netscape.certsrv.authentication.ISharedToken;
+
+public class SharedSecret implements ISharedToken {
+
+ public SharedSecret() {
+ }
+
+ public String getSharedToken(PKIData cmcdata) {
+ return "testing";
+ }
+
+ public String getSharedToken(BigInteger serial) {
+ return "testing";
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java
new file mode 100644
index 000000000..937531933
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java
@@ -0,0 +1,298 @@
+// --- 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.authentication;
+
+import java.io.*;
+import java.util.*;
+import java.lang.Class;
+import java.security.cert.*;
+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.cmsutil.http.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.kra.*;
+import javax.servlet.http.HttpServletRequest;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+/**
+ * Token authentication.
+ * Checked if the given token is valid.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class TokenAuthentication implements IAuthManager,
+ IProfileAuthenticator {
+
+ /* result auth token attributes */
+ public static final String TOKEN_UID = "uid";
+ public static final String TOKEN_GID = "gid";
+
+ /* required credentials */
+ public static final String CRED_SESSION_ID = IAuthManager.CRED_SESSION_ID;
+ protected String[] mRequiredCreds = { CRED_SESSION_ID };
+
+ /* 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 IUGSubsystem mUGSub = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ public TokenAuthentication() {
+ }
+
+ /**
+ * initializes the TokenAuthentication 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;
+
+ mUGSub = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ }
+
+ /**
+ * 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 false;
+ }
+
+ /**
+ * authenticates user(agent) by certificate
+ * <p>
+ * called by other subsystems or their servlets to authenticate
+ * users (agents)
+ * @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("TokenAuthentication: start");
+
+ // force SSL handshake
+ SessionContext context = SessionContext.getExistingContext();
+
+ // retreive certificate from socket
+ AuthToken authToken = new AuthToken(this);
+
+ // get group name from configuration file
+ IConfigStore sconfig = CMS.getConfigStore();
+
+ String sessionId = (String)authCred.get(CRED_SESSION_ID);
+ String givenHost = (String)authCred.get("clientHost");
+ String auth_host = sconfig.getString("securitydomain.host");
+ int auth_port = sconfig.getInteger("securitydomain.httpseeport");
+
+ HttpClient httpclient = new HttpClient();
+ String c = null;
+ try {
+ JssSSLSocketFactory factory = new JssSSLSocketFactory();
+ httpclient = new HttpClient(factory);
+ String content = CRED_SESSION_ID+"="+sessionId+"&hostname="+givenHost;
+ CMS.debug("TokenAuthentication: content=" + content);
+ httpclient.connect(auth_host, auth_port);
+ HttpRequest httprequest = new HttpRequest();
+ httprequest.setMethod(HttpRequest.POST);
+ httprequest.setURI("/ca/ee/ca/tokenAuthenticate");
+ httprequest.setHeader("user-agent", "HTTPTool/1.0");
+ httprequest.setHeader("content-length", "" + content.length());
+ httprequest.setHeader("content-type",
+ "application/x-www-form-urlencoded");
+ httprequest.setContent(content);
+ HttpResponse httpresponse = httpclient.send(httprequest);
+
+ c = httpresponse.getContent();
+ } catch (Exception e) {
+ CMS.debug("TokenAuthentication authenticate Exception="+e.toString());
+ }
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "TokenAuthentication::authenticate() - "
+ + "Exception="+e.toString() );
+ throw new EBaseException( e.toString() );
+ }
+ String status = parser.getValue("Status");
+
+ CMS.debug("TokenAuthentication: status=" + status);
+ if (!status.equals("0")) {
+ String error = parser.getValue("Error");
+ throw new EBaseException(error);
+ }
+
+ String uid = parser.getValue("uid");
+ String gid = parser.getValue("gid");
+
+ authToken.set(TOKEN_UID, uid);
+ authToken.set(TOKEN_GID, gid);
+
+ if(context != null) {
+ CMS.debug("SessionContext.USER_ID " + uid + " SessionContext.GROUP_ID " + gid);
+ context.put(SessionContext.USER_ID, uid );
+ context.put(SessionContext.GROUP_ID, gid );
+ }
+
+ CMS.debug("TokenAuthentication: authenticated uid="+uid+", gid="+gid);
+ } catch (EBaseException e) {
+ throw e;
+ } catch (Exception e) {
+ }
+ }
+
+ return authToken;
+ }
+
+ /**
+ * 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_AGENT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_AGENT_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+
+ v.addElement(CRED_SESSION_ID);
+ return v.elements();
+ }
+
+ 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 {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java
new file mode 100644
index 000000000..07f072914
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java
@@ -0,0 +1,199 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+// cert server x509 imports
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.CertificateSubjectName;
+import java.security.cert.CertificateException;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.io.IOException;
+
+
+/**
+ * udn/pwd directory based authentication manager
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class UdnPwdDirAuthentication extends DirBasedAuthentication {
+
+ /* required credentials to authenticate. udn and pwd are strings. */
+ public static final String CRED_UDN = "udn";
+ public static final String CRED_PWD = "pwd";
+ protected static String[] mRequiredCreds = { CRED_UDN, CRED_PWD };
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] { PROP_DNPATTERN,
+ PROP_LDAPSTRINGATTRS,
+ PROP_LDAPBYTEATTRS,
+ "ldap.ldapconn.host",
+ "ldap.ldapconn.port",
+ "ldap.ldapconn.secureConn",
+ "ldap.ldapconn.version",
+ "ldap.minConns",
+ "ldap.maxConns",
+ };
+
+ static {
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TEXT +
+ ";Authenticate the user distinguished name and password provided " +
+ "by the user against an LDAP directory. Works with the " +
+ "Dir Based Enrollment HTML form");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authentication");
+ };
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public UdnPwdDirAuthentication() {
+ super();
+ }
+
+ /**
+ * Initializes the UdnPwdDirAuthentication auth manager.
+ * <p>
+ * @param name - The name for this authentication manager instance.
+ * @param implName - The name of the authentication manager plugin.
+ * @param config - The configuration store for this instance.
+ * @exception EBaseException If an error occurs during initialization.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ super.init(name, implName, config, false);
+ }
+
+ /**
+ * Authenticates a user based on udn, pwd in the directory.
+ *
+ * @param authCreds The authentication credentials.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the udn and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected String authenticate(LDAPConnection conn,
+ IAuthCredentials authCreds,
+ AuthToken token)
+ throws EBaseException {
+ String userdn = null;
+
+ // authenticate by binding to ldap server with password.
+ try {
+ // get the udn.
+ userdn = (String) authCreds.get(CRED_UDN);
+ if (userdn == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UDN));
+ }
+
+ // get the password.
+ String pwd = (String) authCreds.get(CRED_PWD);
+
+ if (pwd == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD));
+ }
+ if (pwd.equals("")) {
+ // anonymous binding not allowed
+ log(ILogger.LL_FAILURE,
+ "user " + userdn + " attempted login with empty password.");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // bind as user dn and pwd - authenticates user with pwd.
+ conn.authenticate(userdn, pwd);
+ // set userdn in the token.
+ token.set(CRED_UDN, userdn);
+
+ return userdn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE,
+ "Couldn't get ldap connection. Error: " + e.toString());
+ throw e;
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ log(ILogger.LL_SECURITY,
+ "user " + userdn + " does not exist in ldap server host " +
+ conn.getHost() + ", port " + conn.getPort() + ".");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.INVALID_CREDENTIALS:
+ log(ILogger.LL_SECURITY,
+ "authenticate user " + userdn + " with bad password.");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.SERVER_DOWN:
+ log(ILogger.LL_FAILURE, "Ldap server is down.");
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+
+ default:
+ log(ILogger.LL_FAILURE,
+ "Ldap error encountered. " + e.getMessage());
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_OTHER_LDAP_EXCEPTION",
+ e.errorCodeToString()));
+ }
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
new file mode 100644
index 000000000..41f178163
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
@@ -0,0 +1,270 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+
+// cert server x509 imports
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.CertificateSubjectName;
+import java.security.cert.CertificateException;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Locale;
+import java.util.Enumeration;
+import java.io.IOException;
+
+
+/**
+ * uid/pwd directory based authentication manager
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class UidPwdDirAuthentication extends DirBasedAuthentication
+ implements IProfileAuthenticator {
+
+ /* required credentials to authenticate. uid and pwd are strings. */
+ public static final String CRED_UID = "uid";
+ public static final String CRED_PWD = "pwd";
+ protected static String[] mRequiredCreds = { CRED_UID, CRED_PWD };
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] { PROP_DNPATTERN,
+ PROP_LDAPSTRINGATTRS,
+ PROP_LDAPBYTEATTRS,
+ "ldap.ldapconn.host",
+ "ldap.ldapconn.port",
+ "ldap.ldapconn.secureConn",
+ "ldap.ldapconn.version",
+ "ldap.basedn",
+ "ldap.minConns",
+ "ldap.maxConns",
+ };
+
+ static {
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TEXT +
+ ";Authenticate the username and password provided " +
+ "by the user against an LDAP directory. Works with the " +
+ "Dir Based Enrollment HTML form");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authrules-uidpwddirauth");
+ };
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public UidPwdDirAuthentication() {
+ super();
+ }
+
+ /**
+ * Authenticates a user based on uid, pwd in the directory.
+ *
+ * @param authCreds The authentication credentials.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the uid and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected String authenticate(LDAPConnection conn,
+ IAuthCredentials authCreds,
+ AuthToken token)
+ throws EBaseException {
+ String userdn = null;
+ String uid = null;
+
+ // authenticate by binding to ldap server with password.
+ try {
+ // get the uid.
+ uid = (String) authCreds.get(CRED_UID);
+ CMS.debug("Authenticating UID=" + uid);
+ if (uid == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID));
+ }
+
+ // get the password.
+ String pwd = (String) authCreds.get(CRED_PWD);
+
+ if (pwd == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL",CRED_PWD));
+ }
+ if (pwd.equals("")) {
+ // anonymous binding not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_EMPTY_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // get user dn.
+ CMS.debug("Authenticating: Searching for UID=" + uid +
+ " base DN=" + mBaseDN);
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ //LDAPEntry entry = (LDAPEntry)res.nextElement();
+ LDAPEntry entry = res.next();
+
+ userdn = entry.getDN();
+ CMS.debug("Authenticating: Found User DN=" + userdn);
+ } else {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_USER_NOT_EXIST", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // bind as user dn and pwd - authenticates user with pwd.
+ conn.authenticate(userdn, pwd);
+ // set uid in the token.
+ token.set(CRED_UID, uid);
+
+ return userdn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CANNOT_CONNECT_LDAP", e.toString()));
+ throw e;
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("USER_NOT_EXIST", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.INVALID_CREDENTIALS:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_BAD_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.SERVER_DOWN:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_SERVER_DOWN"));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+
+ default:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.getMessage()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_OTHER_LDAP_EXCEPTION",
+ e.errorCodeToString()));
+ }
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+ // 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_LDAP_UID_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_UID_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+
+ v.addElement(CRED_UID);
+ v.addElement(CRED_PWD);
+ return v.elements();
+ }
+
+ public boolean isValueWriteable(String name) {
+ if (name.equals(CRED_UID)) {
+ return true;
+ } else if (name.equals(CRED_PWD)) {
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(CRED_UID)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_UID"));
+ } else if (name.equals(CRED_PWD)) {
+ return new Descriptor(IDescriptor.PASSWORD, null, null,
+ CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_PWD"));
+
+ }
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString(USER_DN));
+ }
+
+ public boolean isSSLClientRequired() {
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java
new file mode 100644
index 000000000..7b6e41da0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java
@@ -0,0 +1,464 @@
+// --- 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.authentication;
+
+
+// ldap java sdk
+import netscape.ldap.*;
+import java.util.*;
+
+// cert server imports.
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.LdapResources;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+
+// cert server x509 imports
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.CertificateSubjectName;
+import java.security.cert.CertificateException;
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.IOException;
+import java.io.*;
+
+
+/**
+ * uid/pwd/pin directory based authentication manager
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class UidPwdPinDirAuthentication extends DirBasedAuthentication
+ implements IExtendedPluginInfo, IProfileAuthenticator {
+
+ /* required credentials to authenticate. uid and pwd are strings. */
+ public static final String CRED_UID = "uid";
+ public static final String CRED_PWD = "pwd";
+ public static final String CRED_PIN = "pin";
+ protected static String[] mRequiredCreds = { CRED_UID, CRED_PWD, CRED_PIN };
+
+ public static final String PROP_REMOVE_PIN = "removePin";
+ public static final String PROP_PIN_ATTR = "pinAttr";
+
+ public static final boolean DEF_REMOVE_PIN = false;
+ public static final String DEF_PIN_ATTR = "pin";
+
+ protected static final byte SENTINEL_SHA = 0;
+ protected static final byte SENTINEL_MD5 = 1;
+ protected static final byte SENTINEL_NONE = 0x2d;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] { PROP_REMOVE_PIN,
+ PROP_PIN_ATTR,
+ PROP_DNPATTERN,
+ PROP_LDAPSTRINGATTRS,
+ PROP_LDAPBYTEATTRS,
+ "ldap.ldapconn.host",
+ "ldap.ldapconn.port",
+ "ldap.ldapconn.secureConn",
+ "ldap.ldapconn.version",
+ "ldap.ldapauth.bindDN",
+ "ldap.ldapauth.bindPWPrompt",
+ "ldap.ldapauth.clientCertNickname",
+ "ldap.ldapauth.authtype",
+ "ldap.basedn",
+ "ldap.minConns",
+ "ldap.maxConns",
+ };
+
+ static {
+ mExtendedPluginInfo.add(
+ PROP_REMOVE_PIN + ";boolean;SEE DOCUMENTATION for pin removal");
+ mExtendedPluginInfo.add(
+ PROP_PIN_ATTR + ";string;directory attribute to use for pin (default 'pin')");
+ mExtendedPluginInfo.add(
+ "ldap.ldapauth.bindDN;string;DN to bind as for pin removal. "
+ + "For example 'CN=PinRemoval User'");
+ mExtendedPluginInfo.add(
+ "ldap.ldapauth.bindPWPrompt;password;Enter password used to bind as " +
+ "the above user");
+ mExtendedPluginInfo.add(
+ "ldap.ldapauth.clientCertNickname;string;If you want to use "
+ + "SSL client auth to the directory, set the client "
+ + "cert nickname here");
+ mExtendedPluginInfo.add(
+ "ldap.ldapauth.authtype;choice(BasicAuth,SslClientAuth),required;"
+ + "How to bind to the directory (for pin removal only)");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TEXT
+ + ";Authenticate the username, password and pin provided "
+ + "by the user against an LDAP directory. Works with the "
+ + "Dir/Pin Based Enrollment HTML form");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authrules-uidpwdpindirauth");
+
+ }
+
+ protected boolean mRemovePin = DEF_REMOVE_PIN;
+ protected String mPinAttr = DEF_PIN_ATTR;
+ protected MessageDigest mSHADigest = null;
+ protected MessageDigest mMD5Digest = null;
+
+ private String mBindDN = null;
+ private String mBindPassword = null;
+
+ private ILdapConnFactory removePinLdapFactory = null;
+ private LDAPConnection removePinLdapConnection = null;
+ private IConfigStore removePinLdapConfigStore = null;
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public UidPwdPinDirAuthentication() {
+ super();
+ }
+
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ super.init(name, implName, config);
+ mRemovePin =
+ config.getBoolean(PROP_REMOVE_PIN, DEF_REMOVE_PIN);
+ mPinAttr =
+ config.getString(PROP_PIN_ATTR, DEF_PIN_ATTR);
+ if (mPinAttr.equals("")) {
+ mPinAttr = DEF_PIN_ATTR;
+ }
+
+ if (mRemovePin) {
+ removePinLdapConfigStore = config.getSubStore("ldap");
+ removePinLdapFactory = CMS.getLdapBoundConnFactory();
+ removePinLdapFactory.init(removePinLdapConfigStore);
+ removePinLdapConnection = removePinLdapFactory.getConn();
+ }
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ mMD5Digest = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.getMessage()));
+ }
+
+ }
+
+ protected void verifyPassword(String Password) {
+ }
+
+ /**
+ * Authenticates a user based on its uid, pwd, pin in the directory.
+ *
+ * @param authCreds The authentication credentials with uid, pwd, pin.
+ * @return The user's ldap entry dn.
+ * @exception EInvalidCredentials If the uid and password are not valid
+ * @exception EBaseException If an internal error occurs.
+ */
+ protected String authenticate(LDAPConnection conn,
+ IAuthCredentials authCreds,
+ AuthToken token)
+ throws EBaseException {
+ String userdn = null;
+ String uid = null;
+ String pwd = null;
+ String pin = null;
+
+ try {
+ // get the uid.
+ uid = (String) authCreds.get(CRED_UID);
+ if (uid == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID));
+ }
+
+ // get the password.
+ pwd = (String) authCreds.get(CRED_PWD);
+ if (pwd == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD));
+ }
+ if (pwd.equals("")) {
+ // anonymous binding not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_EMPTY_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // get the pin.
+ pin = (String) authCreds.get(CRED_PIN);
+ if (pin == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PIN));
+ }
+ if (pin.equals("")) {
+ // empty pin not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_EMPTY_PIN", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // get user dn.
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ userdn = entry.getDN();
+ } else {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_USER_NOT_EXIST", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // bind as user dn and pwd - authenticates user with pwd.
+ conn.authenticate(userdn, pwd);
+
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", uid));
+ // log(ILogger.LL_SECURITY, "found user : " + userdn);
+
+ // check pin.
+ checkpin(conn, userdn, uid, pin);
+
+ // set uid in the token.
+ token.set(CRED_UID, uid);
+
+ return userdn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CANNOT_CONNECT_LDAP", e.toString()));
+ throw e;
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_USER_NOT_EXIST", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.INVALID_CREDENTIALS:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_BAD_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ case LDAPException.SERVER_DOWN:
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("LDAP_SERVER_DOWN"));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+
+ default:
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.getMessage()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_OTHER_LDAP_EXCEPTION",
+ e.errorCodeToString()));
+ }
+ }
+ }
+
+ protected void checkpin(LDAPConnection conn, String userdn,
+ String uid, String pin)
+ throws EBaseException, LDAPException {
+ LDAPSearchResults res = null;
+ LDAPEntry entry = null;
+
+ // get pin.
+
+ res = conn.search(userdn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mPinAttr }, false);
+ if (res.hasMoreElements()) {
+ entry = (LDAPEntry) res.nextElement();
+ } else {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_NO_ENTRY_RETURNED", uid, userdn));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ LDAPAttribute pinAttr = entry.getAttribute(mPinAttr);
+
+ if (pinAttr == null) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ Enumeration pinValues = pinAttr.getByteValues();
+
+ if (!pinValues.hasMoreElements()) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ byte[] entrypin = (byte[]) pinValues.nextElement();
+
+ // compare value digest.
+
+ if (entrypin == null || entrypin.length < 2) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ byte hashtype = entrypin[0];
+
+ byte[] pinDigest = null;
+ String toBeDigested = userdn + pin;
+
+ if (hashtype == SENTINEL_SHA) {
+
+ pinDigest = mSHADigest.digest(toBeDigested.getBytes());
+ } else if (hashtype == SENTINEL_MD5) {
+ pinDigest = mMD5Digest.digest(toBeDigested.getBytes());
+ } else if (hashtype == SENTINEL_NONE) {
+ pinDigest = toBeDigested.getBytes();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_UKNOWN_ENCODING_TYPE", mPinAttr, "*", userdn));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ if (pinDigest.length != (entrypin.length - 1)) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_LENGTH_NOT_MATCHED", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ int i;
+
+ for (i = 0; i < (entrypin.length - 1); i++) {
+ if (pinDigest[i] != entrypin[i + 1])
+ break;
+ }
+ if (i != (entrypin.length - 1)) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_BAD_PASSWORD", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // pin ok. remove pin if so configured
+ // Note that this means that a policy may reject this request later,
+ // but the user will not be able to enroll again as his pin is gone.
+
+ // We remove the pin using a different connection which is bound as
+ // a more privileged user.
+
+ if (mRemovePin) {
+
+ try {
+ removePinLdapConnection.modify(userdn,
+ new LDAPModification(
+ LDAPModification.DELETE,
+ new LDAPAttribute(mPinAttr, entrypin)));
+
+ } catch (LDAPException e) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMS_AUTH_CANT_REMOVE_PIN", userdn));
+ }
+
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+ // 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_LDAP_UID_PIN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_UID_PIN_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+
+ v.addElement(CRED_UID);
+ v.addElement(CRED_PWD);
+ v.addElement(CRED_PIN);
+ return v.elements();
+ }
+
+ public boolean isValueWriteable(String name) {
+ if (name.equals(CRED_UID)) {
+ return true;
+ } else if (name.equals(CRED_PWD)) {
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(CRED_UID)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_UID"));
+ } else if (name.equals(CRED_PWD)) {
+ return new Descriptor(IDescriptor.PASSWORD, null, null,
+ CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_PWD"));
+ } else if (name.equals(CRED_PIN)) {
+ return new Descriptor(IDescriptor.PASSWORD, null, null,
+ CMS.getUserMessage(locale, "CMS_AUTHENTICATION_LDAP_PIN"));
+
+ }
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString(USER_DN));
+ }
+
+ public boolean isSSLClientRequired() {
+ return false;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/authorization/AAclAuthz.java b/pki/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
new file mode 100644
index 000000000..4416a52fd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
@@ -0,0 +1,885 @@
+// --- 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.authorization;
+
+
+import java.util.*;
+import java.lang.Class;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.evaluators.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * An abstract class represents an authorization manager that governs the
+ * access of internal resources such as servlets.
+ * It parses in the ACLs associated with each protected
+ * resources, and provides protected method <CODE>checkPermission</CODE>
+ * for code that needs to verify access before performing
+ * actions.
+ * <P>
+ * Here is a sample resourceACLS for a resource
+ * <PRE>
+ * certServer.UsrGrpAdminServlet:
+ * execute:
+ * deny (execute) user="tempAdmin";
+ * allow (execute) group="Administrators";
+ * </PRE>
+ * To perform permission checking, code call authz mgr authorize()
+ * method to verify access. See AuthzMgr for calling example.
+ * <P>
+ * default "evaluators" are used to evaluate the "group=.." or "user=.."
+ * rules. See evaluator for more info
+ *
+ * @version $Revision$, $Date$
+ * @see <A HREF="http://developer.netscape.com/library/documentation/enterprise/admnunix/aclfiles.htm">ACL Files</A>
+ */
+public abstract class AAclAuthz {
+
+ protected static final String PROP_CLASS = "class";
+ protected static final String PROP_IMPL = "impl";
+ protected static final String PROP_EVAL = "accessEvaluator";
+
+ protected static final String ACLS_ATTR = "aclResources";
+
+ private IConfigStore mConfig = null;
+
+ private Hashtable mACLs = new Hashtable();
+ private Hashtable mEvaluators = new Hashtable();
+ private ILogger mLogger = null;
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+
+ protected static String[] mConfigParams = null;
+
+ static {
+ mExtendedPluginInfo = new Vector();
+ }
+
+ /**
+ * Constructor
+ */
+ public AAclAuthz() {
+ }
+
+ /**
+ * Initializes
+ */
+ protected void init(IConfigStore config)
+ throws EBaseException {
+
+ mLogger = CMS.getLogger();
+ CMS.debug("AAclAuthz: init begins");
+
+ mConfig = config;
+
+ // load access evaluators specified in the config file
+ IConfigStore mainConfig = CMS.getConfigStore();
+ IConfigStore evalConfig = mainConfig.getSubStore(PROP_EVAL);
+ IConfigStore i = evalConfig.getSubStore(PROP_IMPL);
+
+ IAccessEvaluator evaluator = null;
+ Enumeration mImpls = i.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String type = (String) mImpls.nextElement();
+ String evalClassPath = null;
+
+ try {
+ evalClassPath = i.getString(type + "." + PROP_CLASS);
+ } catch (Exception e) {
+ log(ILogger.LL_MISCONF, "failed to get config class info");
+
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ type + "." + PROP_CLASS));
+ }
+
+ // instantiate evaluator
+ try {
+ evaluator =
+ (IAccessEvaluator) Class.forName(evalClassPath).newInstance();
+ } catch (Exception e) {
+ String errMsg = "init(): failed to load class: " +
+ evalClassPath + ":" + e.toString();
+
+ throw new
+ EACLsException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL",
+ evalClassPath));
+ }
+
+ if (evaluator != null) {
+ evaluator.init();
+ // store evaluator
+ registerEvaluator(type, evaluator);
+ } else {
+ String errMsg = "access evaluator " + type + " is null";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_NULL", type));
+ }
+ }
+
+ log(ILogger.LL_INFO, "initialization done");
+ }
+
+ /**
+ * Parse ACL resource attributes, then update the ACLs memory store
+ * This is intended to be used if storing ACLs on ldap is not desired,
+ * and the caller is expected to call this method to add resource
+ * and acl info into acls memory store. The resACLs format should conform
+ * to the following:
+ * <resource ID>:right-1[,right-n]:[allow,deny](right(s))<evaluatorType>=<value>:<comment for this resource acl
+ * <P>
+ * Example:
+ * resTurnKnob:left,right:allow(left) group="lefties":door knobs for lefties
+ * @param resACLs same format as the resourceACLs attribute
+ * @throws EBaseException parsing error from <code>parseACL</code>
+ */
+ public void addACLs(String resACLs) throws EBaseException {
+ ACL acl = (ACL) CMS.parseACL(resACLs);
+
+ if (acl != null) {
+ mACLs.put(acl.getName(), acl);
+ } else {
+ log(ILogger.LL_FAILURE, "parseACL failed");
+ }
+ }
+
+ public void accessInit(String accessInfo) throws EBaseException {
+ addACLs(accessInfo);
+ }
+
+ public IACL getACL(String target) {
+ return (ACL) mACLs.get(target);
+ }
+
+ protected Enumeration getTargetNames() {
+ return mACLs.keys();
+ }
+
+ public Enumeration getACLs() {
+ return mACLs.elements();
+ }
+
+ /**
+ * Returns the configuration store used by this Authz mgr
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] s = Utils.getStringArrayFromVector(mExtendedPluginInfo);
+
+ return s;
+
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return mConfigParams;
+ }
+
+ /**
+ * graceful shutdown
+ */
+ public abstract void shutdown();
+
+ /**
+ * Registers new handler for the given attribute type
+ * in the expressions.
+ */
+ public void registerEvaluator(String type, IAccessEvaluator evaluator) {
+ mEvaluators.put(type, evaluator);
+ log(ILogger.LL_INFO, type + " evaluator registered");
+ }
+
+ /*******************************************************
+ * with session context
+ *******************************************************/
+
+ /**
+ * Checks if the permission is granted or denied in
+ * the current execution context. If the code is
+ * marked as privileged, this methods will simply
+ * return.
+ * <P>
+ * note that if a resource does not exist in the aclResources
+ * entry, but a higher level node exist, it will still be
+ * evaluated. The highest level node's acl determines the
+ * permission. If the higher level node doesn't contain any acl
+ * information, then it's passed down to the lower node. If
+ * a node has no aci in its resourceACLs, then it's considered
+ * passed.
+ * <p>
+ * example: certServer.common.users, if failed permission check for
+ * "certServer", then it's considered failed, and there is no need to
+ * continue the check. If passed permission check for "certServer",
+ * then it's considered passed, and no need to continue the
+ * check. If certServer contains no aci then "certServer.common" will be
+ * checked for permission instead. If down to the leaf level,
+ * the node still contains no aci, then it's considered passed.
+ * If at the leaf level, no such resource exist, or no acis, it's
+ * considered passed.
+ * <p>
+ * If there are multiple aci's for a resource, ALL aci's will be
+ * checked, and only if all passed permission checks, will the
+ * eventual access be granted.
+ * @param name resource name
+ * @param perm permission requested
+ * @exception EACLsException access permission denied
+ */
+ protected synchronized void checkPermission(String name, String perm)
+ throws EACLsException {
+ String resource = "";
+ StringTokenizer st = new StringTokenizer(name, ".");
+
+ while (st.hasMoreTokens()) {
+ String node = st.nextToken();
+
+ if (! "".equals(resource)) {
+ resource = resource + "." + node;
+ } else {
+ resource = node;
+ }
+
+ boolean passed = false;
+
+ try {
+ passed = checkACLs(resource, perm);
+ } catch (EACLsException e) {
+ Object[] params = new Object[2];
+
+ params[0] = name;
+ params[1] = perm;
+
+ String errMsg = "checkPermission(): permission denied for the resource " +
+ name + " on operation " + perm;
+
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("AUTHZ_EVALUATOR_ACCESS_DENIED", name, perm));
+
+ throw new
+ EACLsException(CMS.getUserMessage("CMS_ACL_NO_PERMISSION",
+ (String[]) params));
+ }
+
+ if (passed) {
+ String infoMsg = "checkPermission(): permission granted for the resource " +
+ name + " on operation " + perm;
+
+ log(ILogger.LL_INFO, infoMsg);
+
+ return;
+ } // else, continue
+ }
+ }
+
+ /**
+ * Checks if the permission is granted or denied in
+ * the current execution context.
+ * <P>
+ * An <code>ACL</code> may contain one or more <code>ACLEntry</code>.
+ * However, in case of multiple <code>ACLEntry</code>, a subject must
+ * pass ALL of the <code>ACLEntry</code> evaluation for permission
+ * to be granted
+ * <P>
+ * negative ("deny") aclEntries are treated differently than
+ * positive ("allow") statements. If a negative aclEntries
+ * fails the acl check, the permission check will return "false"
+ * right away; while in the case of a positive aclEntry, if the
+ * the aclEntry fails the acl check, the next aclEntry will be
+ * evaluated.
+ * @param name resource name
+ * @param perm permission requested
+ * @return true if access allowed
+ * false if should be passed down to the next node
+ * @exception EACLsException if access disallowed
+ */
+ private boolean checkACLs(String name, String perm)
+ throws EACLsException {
+ ACL acl = (ACL) mACLs.get(name);
+
+ // no such resource, pass it down
+ if (acl == null) {
+ String infoMsg = "checkACLs(): no acl for" +
+ name + "...pass down to next node";
+
+ log(ILogger.LL_INFO, infoMsg);
+
+ return false;
+ }
+
+ Enumeration e = acl.entries();
+
+ if ((e == null) || (e.hasMoreElements() == false)) {
+ // no acis for node, pass down to next node
+ String infoMsg = " AAclAuthz.checkACLs(): no acis for " +
+ name + " acl entry...pass down to next node";
+
+ log(ILogger.LL_INFO, infoMsg);
+
+ return false;
+ }
+
+ /**
+ * must pass all ACLEntry
+ */
+ for (; e.hasMoreElements();) {
+ ACLEntry entry = (ACLEntry) e.nextElement();
+
+ // if permission not pertinent, move on to next ACLEntry
+ if (entry.containPermission(perm) == true) {
+ if (evaluateExpressions(entry.getAttributeExpressions())) {
+ if (entry.checkPermission(perm) == false) {
+ log(ILogger.LL_SECURITY, " checkACLs(): permission denied");
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PERMISSION_DENIED"));
+ }
+ } else if (!entry.isNegative()) {
+ // didn't meet the access expression for "allow", failed
+ log(ILogger.LL_SECURITY, "checkACLs(): permission denied");
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PERMISSION_DENIED"));
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Resolves the given expressions.
+ * expression || expression || ...
+ * example:
+ * group="Administrators" || group="Operators"
+ */
+ private boolean evaluateExpressions(String s) {
+ // XXX - just handle "||" (or) among multiple expressions for now
+ // XXX - could use some optimization ... later
+
+ CMS.debug("evaluating expressions: " + s);
+
+ Vector v = new Vector();
+
+ while (s.length() > 0) {
+ int orIndex = s.indexOf("||");
+ int andIndex = s.indexOf("&&");
+
+ // this is the last expression
+ if (orIndex == -1 && andIndex == -1) {
+ boolean passed = evaluateExpression(s.trim());
+
+ v.addElement(Boolean.valueOf(passed));
+ break;
+
+ // || first
+ } else if (andIndex == -1 || (orIndex != -1 && orIndex < andIndex)) {
+ String s1 = s.substring(0, orIndex);
+ boolean passed = evaluateExpression(s1.trim());
+
+ v.addElement(new Boolean(passed));
+ v.addElement("||");
+ s = s.substring(orIndex + 2);
+ // && first
+ } else {
+ String s1 = s.substring(0, andIndex);
+ boolean passed = evaluateExpression(s1.trim());
+
+ v.addElement(new Boolean(passed));
+ v.addElement("&&");
+ s = s.substring(andIndex + 2);
+ }
+ }
+
+ if (v.size() == 1) {
+ Boolean bool = (Boolean) v.remove(0);
+
+ return bool.booleanValue();
+ }
+ boolean left = false;
+ String op = "";
+ boolean right = false;
+
+ while (v.size() > 0) {
+ if (op.equals(""))
+ left = ((Boolean) v.remove(0)).booleanValue();
+ op = (String) v.remove(0);
+ right = ((Boolean) v.remove(0)).booleanValue();
+ left = evaluateExp(left, op, right);
+ }
+
+ return left;
+ }
+
+ /**
+ * Resolves the given expression.
+ */
+ private boolean evaluateExpression(String expression) {
+ // XXX - just recognize "=" for now!!
+ int i = expression.indexOf("=");
+ String type = expression.substring(0, i);
+ String value = expression.substring(i + 1);
+ IAccessEvaluator evaluator = (IAccessEvaluator) mEvaluators.get(type);
+
+ if (evaluator == null) {
+ String errMsg = "evaluator for type " + type + "not found";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_NOT_FOUND", type));
+ return false;
+ }
+
+ return evaluator.evaluate(type, "=", value);
+ }
+
+ /*******************************************************
+ * with authToken
+ *******************************************************/
+
+ /**
+ * Checks if the permission is granted or denied with id from authtoken
+ * gotten from authentication that precedes authorization. If the code is
+ * marked as privileged, this methods will simply
+ * return.
+ * <P>
+ * note that if a resource does not exist in the aclResources
+ * entry, but a higher level node exist, it will still be
+ * evaluated. The highest level node's acl determines the
+ * permission. If the higher level node doesn't contain any acl
+ * information, then it's passed down to the lower node. If
+ * a node has no aci in its resourceACLs, then it's considered
+ * passed.
+ * <p>
+ * example: certServer.common.users, if failed permission check for
+ * "certServer", then it's considered failed, and there is no need to
+ * continue the check. If passed permission check for "certServer",
+ * then it's considered passed, and no need to continue the
+ * check. If certServer contains no aci then "certServer.common" will be
+ * checked for permission instead. If down to the leaf level,
+ * the node still contains no aci, then it's considered passed.
+ * If at the leaf level, no such resource exist, or no acis, it's
+ * considered passed.
+ * <p>
+ * If there are multiple aci's for a resource, ALL aci's will be
+ * checked, and only if all passed permission checks, will the
+ * eventual access be granted.
+ * @param authToken authentication token gotten from authentication
+ * @param name resource name
+ * @param perm permission requested
+ * @exception EACLsException access permission denied
+ */
+ public synchronized void checkPermission(IAuthToken authToken, String name,
+ String perm)
+ throws EACLsException {
+
+ Vector nodev = getNodes(name);
+ Enumeration nodes = nodev.elements();
+ String order = getOrder();
+ Enumeration entries = null;
+
+ if (order.equals("deny"))
+ entries = getDenyEntries(nodes, perm);
+ else
+ entries = getAllowEntries(nodes, perm);
+
+ boolean permitted = false;
+
+ while (entries.hasMoreElements()) {
+ ACLEntry entry = (ACLEntry) entries.nextElement();
+
+ CMS.debug("checkACLS(): ACLEntry expressions= " +
+ entry.getAttributeExpressions());
+ if (evaluateExpressions(authToken, entry.getAttributeExpressions())) {
+ log(ILogger.LL_SECURITY,
+ " checkACLs(): permission denied");
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PERMISSION_DENIED"));
+ }
+ }
+
+ nodes = nodev.elements();
+ if (order.equals("deny"))
+ entries = getAllowEntries(nodes, perm);
+ else
+ entries = getDenyEntries(nodes, perm);
+
+ while (entries.hasMoreElements()) {
+ ACLEntry entry = (ACLEntry) entries.nextElement();
+
+ CMS.debug("checkACLS(): ACLEntry expressions= " +
+ entry.getAttributeExpressions());
+ if (evaluateExpressions(authToken, entry.getAttributeExpressions())) {
+ permitted = true;
+ }
+ }
+
+ nodev = null;
+ if (permitted) {
+ String infoMsg = "checkPermission(): permission granted for the resource " +
+ name + " on operation " + perm;
+
+ log(ILogger.LL_INFO, infoMsg);
+ return;
+ } else {
+ Object[] params = new Object[2];
+
+ params[0] = name;
+ params[1] = perm;
+
+ String errMsg = "checkPermission(): permission denied for the resource " +
+ name + " on operation " + perm;
+
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("AUTHZ_EVALUATOR_ACCESS_DENIED", name, perm));
+
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_NO_PERMISSION",
+ (String[]) params));
+ }
+ }
+
+ protected Enumeration getAllowEntries(Enumeration nodes, String operation) {
+ String name = "";
+ ACL acl = null;
+ Enumeration e = null;
+ Vector v = new Vector();
+
+ while (nodes.hasMoreElements()) {
+ name = (String) nodes.nextElement();
+ acl = (ACL) mACLs.get(name);
+ if (acl == null)
+ continue;
+ e = acl.entries();
+ while (e.hasMoreElements()) {
+ ACLEntry entry = (ACLEntry) e.nextElement();
+
+ if (!entry.isNegative() &&
+ entry.containPermission(operation)) {
+ v.addElement(entry);
+ }
+ }
+ }
+
+ return v.elements();
+ }
+
+ protected Enumeration getDenyEntries(Enumeration nodes, String operation) {
+ String name = "";
+ ACL acl = null;
+ Enumeration e = null;
+ Vector v = new Vector();
+
+ while (nodes.hasMoreElements()) {
+ name = (String) nodes.nextElement();
+ acl = (ACL) mACLs.get(name);
+ if (acl == null)
+ continue;
+ e = acl.entries();
+ while (e.hasMoreElements()) {
+ ACLEntry entry = (ACLEntry) e.nextElement();
+
+ if (entry.isNegative() &&
+ entry.containPermission(operation)) {
+ v.addElement(entry);
+ }
+ }
+ }
+
+ return v.elements();
+ }
+
+ /**
+ * Resolves the given expressions.
+ * expression || expression || ...
+ * example:
+ * group="Administrators" || group="Operators"
+ */
+ private boolean evaluateExpressions(IAuthToken authToken, String s) {
+ // XXX - just handle "||" (or) among multiple expressions for now
+ // XXX - could use some optimization ... later
+ CMS.debug("evaluating expressions: " + s);
+
+ Vector v = new Vector();
+
+ while (s.length() > 0) {
+ int orIndex = s.indexOf("||");
+ int andIndex = s.indexOf("&&");
+
+ // this is the last expression
+ if (orIndex == -1 && andIndex == -1) {
+ boolean passed = evaluateExpression(authToken, s.trim());
+
+ CMS.debug("evaluated expression: " + s.trim() + " to be " + passed);
+ v.addElement(Boolean.valueOf(passed));
+ break;
+
+ // || first
+ } else if (andIndex == -1 || (orIndex != -1 && orIndex < andIndex)) {
+ String s1 = s.substring(0, orIndex);
+ boolean passed = evaluateExpression(authToken, s1.trim());
+
+ CMS.debug("evaluated expression: " + s1.trim() + " to be " + passed);
+ v.addElement(new Boolean(passed));
+ v.addElement("||");
+ s = s.substring(orIndex + 2);
+ // && first
+ } else {
+ String s1 = s.substring(0, andIndex);
+ boolean passed = evaluateExpression(authToken, s1.trim());
+
+ CMS.debug("evaluated expression: " + s1.trim() + " to be " + passed);
+ v.addElement(new Boolean(passed));
+ v.addElement("&&");
+ s = s.substring(andIndex + 2);
+ }
+ }
+
+ if (v.size() == 0) {
+ return false;
+ }
+
+ if (v.size() == 1) {
+ Boolean bool = (Boolean) v.remove(0);
+
+ return bool.booleanValue();
+ }
+
+ boolean left = false;
+ String op = "";
+ boolean right = false;
+
+ while (v.size() > 0) {
+ if (op.equals(""))
+ left = ((Boolean) v.remove(0)).booleanValue();
+ op = (String) v.remove(0);
+ right = ((Boolean) v.remove(0)).booleanValue();
+ left = evaluateExp(left, op, right);
+ }
+
+ return left;
+ }
+
+ public Vector getNodes(String resourceID) {
+ Enumeration parents = getTargetNames();
+ Vector v = new Vector();
+
+ if (resourceID != null && !resourceID.equals("")) {
+ v.addElement(resourceID);
+ } else {
+ return v;
+ }
+ int index = resourceID.lastIndexOf(".");
+ String name = resourceID;
+
+ while (index != -1) {
+ name = name.substring(0, index);
+ v.addElement(name);
+ index = name.lastIndexOf(".");
+ }
+
+ return v;
+ }
+
+ /**
+ * Resolves the given expression.
+ */
+ private boolean evaluateExpression(IAuthToken authToken, String expression) {
+ String op = getOp(expression);
+ String type = "";
+ String value = "";
+
+ if (!op.equals("")) {
+ int len = op.length();
+ int i = expression.indexOf(op);
+
+ type = expression.substring(0, i).trim();
+ value = expression.substring(i + len).trim();
+ }
+ IAccessEvaluator evaluator = (IAccessEvaluator) mEvaluators.get(type);
+
+ if (evaluator == null) {
+ String errMsg = "evaluator for type " + type + "not found";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_NOT_FOUND", type));
+ return false;
+ }
+
+ return evaluator.evaluate(authToken, type, op, value);
+ }
+
+ private String getOp(String exp) {
+ int i = exp.indexOf("!=");
+
+ if (i == -1) {
+ i = exp.indexOf("=");
+ if (i == -1) {
+ i = exp.indexOf(">");
+ if (i == -1) {
+ i = exp.indexOf("<");
+ if (i == -1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_OP_NOT_SUPPORTED", exp));
+ } else {
+ return "<";
+ }
+ } else {
+ return ">";
+ }
+ } else {
+ return "=";
+ }
+ } else {
+ return "!=";
+ }
+ return "";
+ }
+
+ private boolean evaluateExp(boolean left, String op, boolean right) {
+ if (op.equals("||")) {
+ if (left == false && right == false)
+ return false;
+ return true;
+ } else if (op.equals("&&")) {
+ if (left == true && right == true)
+ return true;
+ return false;
+ }
+ return false;
+ }
+
+ /*******************************************************
+ * end identification differentiation
+ *******************************************************/
+
+ /**
+ * This one only updates the memory. Classes extend this class should
+ * also update to a permanent storage
+ */
+ public void updateACLs(String id, String rights, String strACLs,
+ String desc) throws EACLsException {
+ ACL acl = (ACL) getACL(id);
+
+ String resourceACLs = id;
+
+ if (rights != null)
+ resourceACLs = id + ":" + rights + ":" + strACLs + ":" + desc;
+
+ // memory update
+ ACL ac = null;
+
+ try {
+ ac = (ACL) CMS.parseACL(resourceACLs);
+ } catch (EBaseException ex) {
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PARSING_ERROR_0"));
+ }
+
+ mACLs.put(ac.getName(), ac);
+ }
+
+ /**
+ * gets an enumeration of resources
+ * @return an enumeration of resources contained in the ACL table
+ */
+ public Enumeration aclResElements() {
+ return (mACLs.elements());
+ }
+
+ /**
+ * gets an enumeration of access evaluators
+ * @return an enumeraton of access evaluators
+ */
+ public Enumeration aclEvaluatorElements() {
+ return (mEvaluators.elements());
+ }
+
+ /**
+ * gets the access evaluators
+ * @return handle to the access evaluators table
+ */
+ public Hashtable getAccessEvaluators() {
+ return mEvaluators;
+ }
+
+ /**
+ * is this resource name unique
+ * @return true if unique; false otherwise
+ */
+ public boolean isTypeUnique(String type) {
+ if (mACLs.containsKey((Object) type)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHORIZATION,
+ level, msg);
+ }
+
+ /*********************************
+ * abstract methods
+ **********************************/
+
+ /**
+ * update acls. called after memory upate is done to flush to permanent
+ * storage.
+ * <p>
+ */
+ protected abstract void flushResourceACLs() throws EACLsException;
+
+ /**
+ * an abstract class that enforces implementation of the
+ * authorize() method that will authorize an operation on a
+ * particular resource
+ *
+ * @param authToken the authToken associated with a user
+ * @param resource - the protected resource name
+ * @param operation - the protected resource operation name
+ * @exception EBaseException If an internal error occurred.
+ * @return authzToken
+ */
+ public abstract AuthzToken authorize(IAuthToken authToken, String resource, String operation) throws EBaseException;
+
+ public String getOrder() {
+ IConfigStore mainConfig = CMS.getConfigStore();
+ String order = "";
+
+ try {
+ order = mainConfig.getString("authz.evaluateOrder", "");
+ if (order.startsWith("allow"))
+ return "allow";
+ else
+ return "deny";
+ } catch (Exception e) {
+ }
+ return "deny";
+ }
+
+ public boolean evaluateACLs(IAuthToken authToken, String exp) {
+ return evaluateExpressions(authToken, exp);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java b/pki/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java
new file mode 100644
index 000000000..c929f80ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java
@@ -0,0 +1,226 @@
+// --- 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.authorization;
+
+
+// cert server imports.
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.authentication.*;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.io.IOException;
+
+
+/**
+ * A class for basic acls authorization manager
+ *
+ * @version $Revision$, $Date$
+ */
+public class BasicAclAuthz extends AAclAuthz
+ implements IAuthzManager, IExtendedPluginInfo {
+
+ // members
+
+ /* name of this authorization manager instance */
+ private String mName = null;
+
+ /* name of the authorization manager plugin */
+ private String mImplName = null;
+
+ /* configuration store */
+ private IConfigStore mConfig;
+
+ /* the system logger */
+ private ILogger mLogger = null;
+
+ protected static final String PROP_BASEDN = "basedn";
+
+ private static boolean needsFlush = false;
+
+ static {
+ mExtendedPluginInfo.add("nothing for now");
+ }
+
+ /**
+ * Default constructor
+ */
+ public BasicAclAuthz() {
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ mConfigParams =
+ new String[] {
+ "dummy"
+ };
+ }
+
+ /**
+ *
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+ mLogger = CMS.getLogger();
+
+ super.init(config);
+
+ log(ILogger.LL_INFO, "initialization done");
+ }
+
+ /**
+ * gets the name of this authorization manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the plugin name of this authorization manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * check the authorization permission for the user associated with
+ * authToken on operation
+ * <p>
+ * Example:
+ * <p>
+ * For example, if UsrGrpAdminServlet needs to authorize the caller
+ * it would do be done in the following fashion:
+ * <PRE>
+ * try {
+ * authzTok = mAuthz.authorize("DirACLBasedAuthz", authToken, RES_GROUP, "read");
+ * } catch (EBaseException e) {
+ * log(ILogger.LL_FAILURE, "authorize call: "+ e.toString());
+ * }
+ * </PRE>
+ * @param authToken the authToken associated with a user
+ * @param resource - the protected resource name
+ * @param operation - the protected resource operation name
+ * @exception EAuthzInternalError if an internal error occurred.
+ * @exception EAuthzAccessDenied if access denied
+ * @return authzToken if success
+ */
+ public AuthzToken authorize(IAuthToken authToken, String resource, String operation)
+ throws EAuthzInternalError, EAuthzAccessDenied {
+ AuthzToken authzToken = new AuthzToken(this);
+
+ try {
+ checkPermission(authToken, resource, operation);
+
+ CMS.debug("BasicAclAuthz: authorization passed");
+
+ // compose AuthzToken
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_RESOURCE, resource);
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_OPERATION, operation);
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_STATUS,
+ AuthzToken.AUTHZ_STATUS_SUCCESS);
+ } catch (EACLsException e) {
+ // audit here later
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_AUTHORIZATION_FAILED"));
+ String params[] = {resource, operation};
+
+ throw new EAuthzAccessDenied(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZ_ACCESS_DENIED", params));
+ }
+
+ return authzToken;
+ }
+
+ public AuthzToken authorize(IAuthToken authToken, String expression)
+ throws EAuthzAccessDenied {
+ if (evaluateACLs(authToken, expression)) {
+ return (new AuthzToken(this));
+ } else {
+ String params[] = {expression};
+ throw new EAuthzAccessDenied(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZ_ACCESS_DENIED", params));
+ }
+ }
+
+ /**
+ * This currently does not flush to permanent storage
+ * @param id is the resource id
+ * @param strACLs
+ */
+ public void updateACLs(String id, String rights, String strACLs,
+ String desc) throws EACLsException {
+ try {
+ super.updateACLs(id, rights, strACLs, desc);
+ // flushResourceACLs();
+ needsFlush = false;
+ } catch (EACLsException ex) {
+ // flushing failed, set flag
+ needsFlush = true;
+
+ String errMsg = "updateACLs: failed to flushResourceACLs(): "
+ + ex.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_FLUSH_RESOURCES", ex.toString()));
+
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_UPDATE_FAIL"));
+ }
+ }
+
+ /**
+ * updates resourceACLs to permanent storage.
+ * currently not implemented for this authzMgr
+ */
+ protected void flushResourceACLs() throws EACLsException {
+ log(ILogger.LL_FAILURE, "flushResourceACL() is not implemented");
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_METHOD_NOT_IMPLEMENTED"));
+ }
+
+ /**
+ * graceful shutdown
+ */
+ public void shutdown() {
+ log(ILogger.LL_INFO, "shutting down");
+ }
+
+ /**
+ * Logs a message for this class in the system log file.
+ * @param level The log level.
+ * @param msg The message to log.
+ * @see com.netscape.certsrv.logging.ILogger
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHORIZATION,
+ level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java b/pki/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java
new file mode 100644
index 000000000..e8cb1f121
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java
@@ -0,0 +1,368 @@
+// --- 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.authorization;
+
+
+import netscape.ldap.*;
+
+// cert server imports.
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.authentication.*;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.io.IOException;
+
+
+/**
+ * A class for ldap acls based authorization manager
+ * The ldap server used for acls is the cms internal ldap db.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DirAclAuthz extends AAclAuthz
+ implements IAuthzManager, IExtendedPluginInfo {
+
+ // members
+
+ /* name of this authentication manager instance */
+ private String mName = null;
+
+ /* name of the authentication manager plugin */
+ private String mImplName = null;
+
+ /* configuration store */
+ private IConfigStore mConfig;
+
+ /* the system logger */
+ private ILogger mLogger = null;
+
+ protected static final String PROP_BASEDN = "basedn";
+
+ private ILdapConnFactory mLdapConnFactory = null;
+ private String mBaseDN = null;
+ private static boolean needsFlush = false;
+
+ static {
+ mExtendedPluginInfo.add("ldap.ldapconn.host;string,required;" +
+ "LDAP host to connect to");
+ mExtendedPluginInfo.add("ldap.ldapconn.port;number,required;" +
+ "LDAP port number (use 389, or 636 if SSL)");
+ mExtendedPluginInfo.add("ldap.ldapconn.secureConn;boolean;" +
+ "Use SSL to connect to directory?");
+ mExtendedPluginInfo.add("ldap.ldapconn.version;choice(3,2);" +
+ "LDAP protocol version");
+ mExtendedPluginInfo.add("ldap.basedn;string,required;Base DN to start sarching " +
+ "under. If the ACL's DN is 'cn=resourceACL, o=NetscapeCertificateServer' you " +
+ "might want to use 'o=NetscapeCertificateServer' here");
+ mExtendedPluginInfo.add("ldap.minConns;number;number of connections " +
+ "to keep open to directory server. Default 5.");
+ mExtendedPluginInfo.add("ldap.maxConns;number;when needed, connection "
+ +
+ "pool can grow to this many (multiplexed) connections. Default 1000");
+ }
+
+ /**
+ * Default constructor
+ */
+ public DirAclAuthz() {
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ mConfigParams =
+ new String[] {
+ "ldap.ldapconn.host",
+ "ldap.ldapconn.port",
+ "ldap.ldapconn.secureConn",
+ "ldap.ldapconn.version",
+ "ldap.basedn",
+ "ldap.minConns",
+ "ldap.maxConns",
+ };
+ }
+
+ /**
+ *
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+ mLogger = CMS.getLogger();
+
+ super.init(config);
+
+ // initialize LDAP connection factory
+ IConfigStore ldapConfig = mConfig.getSubStore("ldap");
+
+ if (ldapConfig == null) {
+ log(ILogger.LL_MISCONF, "failed to get config ldap info");
+ return;
+ }
+
+ mBaseDN = ldapConfig.getString(PROP_BASEDN, null);
+
+ try {
+ String name1 = ldapConfig.getString("ldapconn.host");
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ }
+
+ mLdapConnFactory = CMS.getLdapBoundConnFactory();
+ mLdapConnFactory.init(ldapConfig);
+
+ // retrieve aclResources from the LDAP server and load
+ // into memory
+ LDAPConnection conn = null;
+
+ CMS.debug("DirAclAuthz: about to ldap search aclResources");
+ try {
+ conn = getConn();
+ LDAPSearchResults res = conn.search(mBaseDN, LDAPv2.SCOPE_SUB,
+ "cn=aclResources", null, false);
+
+ returnConn(conn);
+ if (res.hasMoreElements()) {
+ log(ILogger.LL_INFO, "ldap search found cn=aclResources");
+
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ LDAPAttribute aclRes = entry.getAttribute("resourceACLS");
+
+ Enumeration en = aclRes.getStringValues();
+
+ for (; en != null && en.hasMoreElements();) {
+ addACLs((String) en.nextElement());
+ }
+ } else {
+ log(ILogger.LL_INFO, "ldap search found no cn=aclResources");
+ }
+ } catch (LDAPException e) {
+ String errMsg = "init() -" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_INIT_ERROR", e.toString()));
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_CONNECT_LDAP_FAIL", mBaseDN));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_INIT_ERROR", e.toString()));
+ }
+
+ log(ILogger.LL_INFO, "initialization done");
+ }
+
+ /**
+ * gets the name of this authorization manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the plugin name of this authorization manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * check the authorization permission for the user associated with
+ * authToken on operation
+ * <p>
+ * Example:
+ * <p>
+ * For example, if UsrGrpAdminServlet needs to authorize the caller
+ * it would do be done in the following fashion:
+ * <PRE>
+ * try {
+ * authzTok = mAuthz.authorize("DirAclAuthz", authToken, RES_GROUP, "read");
+ * } catch (EBaseException e) {
+ * log(ILogger.LL_FAILURE, "authorize call: "+ e.toString());
+ * }
+ * </PRE>
+ * @param authToken the authToken associated with a user
+ * @param resource - the protected resource name
+ * @param operation - the protected resource operation name
+ * @exception EBaseException If an internal error occurred.
+ * @return authzToken
+ */
+ public AuthzToken authorize(IAuthToken authToken, String resource, String operation)
+ throws EAuthzInternalError, EAuthzAccessDenied {
+ AuthzToken authzToken = new AuthzToken(this);
+
+ try {
+ checkPermission(authToken, resource, operation);
+ // compose AuthzToken
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_RESOURCE, resource);
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_OPERATION, operation);
+ authzToken.set(AuthzToken.TOKEN_AUTHZ_STATUS, AuthzToken.AUTHZ_STATUS_SUCCESS);
+ CMS.debug("DirAclAuthz: authorization passed");
+ } catch (EACLsException e) {
+ // audit here later
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_AUTHORIZATION_FAILED"));
+ String params[] = {resource, operation};
+
+ throw new EAuthzAccessDenied(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZ_ACCESS_DENIED", params));
+ }
+
+ return authzToken;
+ }
+
+ public AuthzToken authorize(IAuthToken authToken, String expression)
+ throws EAuthzAccessDenied {
+ if (evaluateACLs(authToken, expression)) {
+ return (new AuthzToken(this));
+ } else {
+ String params[] = {expression};
+ throw new EAuthzAccessDenied(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZ_ACCESS_DENIED", params));
+ }
+ }
+
+ /**
+ * update acls. when memory update is done, flush to ldap.
+ * <p>
+ * Currently, it is possible that when the memory is updated
+ * successfully, and the ldap isn't, the memory upates lingers.
+ * The result is that the changes will only be done on ldap at the
+ * next update, or when the system shuts down, another flush will be
+ * attempted.
+ * @param id is the resource id
+ * @param rights The allowable rights for this resource
+ * @param strACLs has the same format as a resourceACLs entry acis
+ * on the ldap server
+ * @param desc The description for this resource
+ */
+ public void updateACLs(String id, String rights, String strACLs,
+ String desc) throws EACLsException {
+ try {
+ super.updateACLs(id, rights, strACLs, desc);
+ flushResourceACLs();
+ needsFlush = false;
+ } catch (EACLsException ex) {
+ // flushing failed, set flag
+ needsFlush = true;
+
+ String errMsg = "updateACLs: failed to flushResourceACLs(): "
+ + ex.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_FLUSH_RESOURCES", ex.toString()));
+
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_UPDATE_FAIL"));
+ }
+ }
+
+ /**
+ * updates resourceACLs to ldap.
+ */
+ protected void flushResourceACLs() throws EACLsException {
+ // ldap update
+ LDAPConnection conn = null;
+
+ try {
+ LDAPAttribute attrs = new LDAPAttribute("resourceACLS");
+ LDAPModificationSet mod = new LDAPModificationSet();
+
+ Enumeration en = aclResElements();
+
+ if (en.hasMoreElements() == true) {
+ while (en.hasMoreElements()) {
+ ACL a = (ACL) en.nextElement();
+ String resAclString = a.getResourceACLs();
+
+ attrs.addValue(resAclString);
+ }
+
+ mod.add(LDAPModification.REPLACE, attrs);
+
+ conn = getConn();
+ conn.modify("cn=aclResources," + mBaseDN, mod);
+ }
+ } catch (LDAPException ex) {
+ System.out.println(ex.toString());
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_UPDATE_FAIL"));
+ } catch (Exception ex) {
+ System.out.println(ex.toString());
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_UPDATE_FAIL"));
+ } finally {
+ try {
+ returnConn(conn);
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, "couldn't return conn ?");
+ }
+ }
+ }
+
+ protected LDAPConnection getConn() throws ELdapException {
+ return mLdapConnFactory.getConn();
+ }
+
+ protected void returnConn(LDAPConnection conn) throws ELdapException {
+ mLdapConnFactory.returnConn(conn);
+ }
+
+ /**
+ * graceful shutdown
+ */
+ public void shutdown() {
+ if (needsFlush) {
+ // flush the changes
+ try {
+ flushResourceACLs();
+ } catch (EACLsException e) {
+ // flushing failed again...too bad
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_FLUSH_ERROR", e.toString()));
+ }
+ }
+
+ try {
+ mLdapConnFactory.reset();
+ mLdapConnFactory = null;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("AUTHZ_EVALUATOR_LDAP_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Logs a message for this class in the system log file.
+ * @param level The log level.
+ * @param msg The message to log.
+ * @see com.netscape.certsrv.logging.ILogger
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHORIZATION,
+ level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java
new file mode 100644
index 000000000..16039767d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java
@@ -0,0 +1,263 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.CertificateException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.GeneralName;
+import netscape.security.util.ObjectIdentifier;
+import com.netscape.certsrv.ca.*;
+import netscape.security.extensions.AuthInfoAccessExtension;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a Authority Information Access CRL extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSAuthInfoAccessExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ public static final String PROP_NUM_ADS = "numberOfAccessDescriptions";
+ public static final String PROP_ACCESS_METHOD = "accessMethod";
+ public static final String PROP_ACCESS_LOCATION_TYPE = "accessLocationType";
+ public static final String PROP_ACCESS_LOCATION = "accessLocation";
+
+ private static final String PROP_ACCESS_METHOD_OCSP = "ocsp";
+ private static final String PROP_ACCESS_METHOD_CAISSUERS = "caIssuers";
+ private static final String PROP_DIRNAME = "DirectoryName";
+ private static final String PROP_URINAME = "URI";
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSAuthInfoAccessExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ AuthInfoAccessExtension authInfoAccessExt = (AuthInfoAccessExtension) ext;
+
+ authInfoAccessExt.setCritical(critical);
+
+ return authInfoAccessExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config, Object ip,
+ boolean critical) {
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+ AuthInfoAccessExtension authInfoAccessExt = new AuthInfoAccessExtension(critical);
+
+ int numberOfAccessDescriptions = 0;
+
+ try {
+ numberOfAccessDescriptions = config.getInteger(PROP_NUM_ADS, 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_INVALID_NUM_ADS", e.toString()));
+ }
+
+ if (numberOfAccessDescriptions > 0) {
+
+ for (int i = 0; i < numberOfAccessDescriptions; i++) {
+ String accessMethod = null;
+ String accessLocationType = null;
+ String accessLocation = null;
+ ObjectIdentifier method = AuthInfoAccessExtension.METHOD_CA_ISSUERS;
+
+ try {
+ accessMethod = config.getString(PROP_ACCESS_METHOD + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AM_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AM_INVALID", e.toString()));
+ }
+
+ if (accessMethod != null && accessMethod.equals(PROP_ACCESS_METHOD_OCSP)) {
+ method = AuthInfoAccessExtension.METHOD_OCSP;
+ }
+
+ try {
+ accessLocationType = config.getString(PROP_ACCESS_LOCATION_TYPE + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_ALT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_ALT_INVALID", e.toString()));
+ }
+
+ try {
+ accessLocation = config.getString(PROP_ACCESS_LOCATION + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (accessLocationType != null && accessLocation != null && accessLocation.length() > 0) {
+ if (accessLocationType.equalsIgnoreCase(PROP_DIRNAME)) {
+ try {
+ X500Name dirName = new X500Name(accessLocation);
+ authInfoAccessExt.addAccessDescription(method, new GeneralName(dirName));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_500NAME", e.toString()));
+ }
+ } else if (accessLocationType.equalsIgnoreCase(PROP_URINAME)) {
+ URIName uriName = new URIName(accessLocation);
+ authInfoAccessExt.addAccessDescription(method, new GeneralName(uriName));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_POTINT_TYPE", accessLocation));
+ }
+ } else {
+ accessLocationType = PROP_URINAME;
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ if (hostname != null && port != null) {
+ accessLocation = "http://"+hostname+":"+port+"/ca/ee/ca/getCAChain?op=downloadBIN";
+ }
+ URIName uriName = new URIName(accessLocation);
+ authInfoAccessExt.addAccessDescription(AuthInfoAccessExtension.METHOD_CA_ISSUERS, new GeneralName(uriName));
+ }
+ }
+ }
+
+ return authInfoAccessExt;
+ }
+
+ public String getCRLExtOID() {
+ return AuthInfoAccessExtension.ID.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+
+ int numberOfAccessDescriptions = 0;
+
+ try {
+ numberOfAccessDescriptions = config.getInteger(PROP_NUM_ADS, 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_INVALID_NUM_ADS", e.toString()));
+ }
+ nvp.add(PROP_NUM_ADS, String.valueOf(numberOfAccessDescriptions));
+
+ for (int i = 0; i < numberOfAccessDescriptions; i++) {
+ String accessMethod = null;
+ String accessLocationType = null;
+ String accessLocation = null;
+
+ try {
+ accessMethod = config.getString(PROP_ACCESS_METHOD + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AM_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AM_INVALID", e.toString()));
+ }
+
+ if (accessMethod != null && accessMethod.length() > 0) {
+ nvp.add(PROP_ACCESS_METHOD + i, accessMethod);
+ } else {
+ nvp.add(PROP_ACCESS_METHOD + i, PROP_ACCESS_METHOD_CAISSUERS);
+ }
+
+ try {
+ accessLocationType = config.getString(PROP_ACCESS_LOCATION_TYPE + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_ALT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_ALT_INVALID", e.toString()));
+ }
+
+ if (accessLocationType != null && accessLocationType.length() > 0) {
+ nvp.add(PROP_ACCESS_LOCATION_TYPE + i, accessLocationType);
+ } else {
+ nvp.add(PROP_ACCESS_LOCATION_TYPE + i, PROP_URINAME);
+ }
+
+ try {
+ accessLocation = config.getString(PROP_ACCESS_LOCATION + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AL_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AIA_AD_AL_INVALID", e.toString()));
+ }
+
+ if (accessLocation != null && accessLocation.length() > 0) {
+ nvp.add(PROP_ACCESS_LOCATION + i, accessLocation);
+ } else {
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ if (hostname != null && port != null) {
+ accessLocation = "http://"+hostname+":"+port+"/ca/ee/ca/getCAChain?op=downloadBIN";
+ }
+ nvp.add(PROP_ACCESS_LOCATION + i, accessLocation);
+ }
+ }
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "enable;boolean;Check to enable Authority Information Access extension.",
+ "critical;boolean;Set criticality for Authority Information Access extension.",
+ PROP_NUM_ADS + ";number;Set number of Access Descriptions.",
+ PROP_ACCESS_METHOD + "0;choice(" + PROP_ACCESS_METHOD_CAISSUERS + "," +
+ PROP_ACCESS_METHOD_OCSP +");Select access description method.",
+ PROP_ACCESS_LOCATION_TYPE + "0;choice(" + PROP_URINAME + "," +
+ PROP_DIRNAME + ");Select access location type.",
+ PROP_ACCESS_LOCATION + "0;string;Enter access location " +
+ "corresponding to the selected access location type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-authorityinformationaccess",
+ PROP_ACCESS_METHOD + "1;choice(" + PROP_ACCESS_METHOD_CAISSUERS + "," +
+ PROP_ACCESS_METHOD_OCSP +");Select access description method.",
+ PROP_ACCESS_LOCATION_TYPE + "1;choice(" + PROP_URINAME + "," +
+ PROP_DIRNAME + ");Select access location type.",
+ PROP_ACCESS_LOCATION + "1;string;Enter access location " +
+ "corresponding to the selected access location type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-authorityinformationaccess",
+ PROP_ACCESS_METHOD + "2;choice(" + PROP_ACCESS_METHOD_CAISSUERS + "," +
+ PROP_ACCESS_METHOD_OCSP +");Select access description method.",
+ PROP_ACCESS_LOCATION_TYPE + "2;choice(" + PROP_URINAME + "," +
+ PROP_DIRNAME + ");Select access location type.",
+ PROP_ACCESS_LOCATION + "2;string;Enter access location " +
+ "corresponding to the selected access location type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-authorityinformationaccess",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The Freshest CRL is a non critical CRL extension " +
+ "that identifies the delta CRL distribution points for a particular CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSAuthInfoAccessExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java
new file mode 100644
index 000000000..5abd0de5d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java
@@ -0,0 +1,154 @@
+// --- 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.crl;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents an authority key identifier extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSAuthorityKeyIdentifierExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSAuthorityKeyIdentifierExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ AuthorityKeyIdentifierExtension authKeyIdExt = null;
+ KeyIdentifier keyId = null;
+ GeneralNames names = null;
+ SerialNumber sn = null;
+
+ try {
+ keyId = (KeyIdentifier) ((AuthorityKeyIdentifierExtension) ext).get(
+ AuthorityKeyIdentifierExtension.KEY_ID);
+ names = (GeneralNames) ((AuthorityKeyIdentifierExtension) ext).get(
+ AuthorityKeyIdentifierExtension.AUTH_NAME);
+ sn = (SerialNumber) ((AuthorityKeyIdentifierExtension) ext).get(
+ AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
+ authKeyIdExt = new AuthorityKeyIdentifierExtension(critical, keyId, names, sn);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AKI_EXT", e.toString()));
+ }
+ return authKeyIdExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ AuthorityKeyIdentifierExtension authKeyIdExt = null;
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+
+ try {
+ KeyIdentifier keyId = null;
+
+ try {
+ X509CertInfo info = (X509CertInfo)
+ ((ICertificateAuthority) crlIssuingPoint.getCertificateAuthority()).getCACert().get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ if (info != null) {
+ CertificateExtensions caCertExtensions = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+
+ if (caCertExtensions != null) {
+ for (int i = 0; i < caCertExtensions.size(); i++) {
+ Extension caCertExt = (Extension) caCertExtensions.elementAt(i);
+
+ if (caCertExt instanceof SubjectKeyIdentifierExtension) {
+ SubjectKeyIdentifierExtension id =
+ (SubjectKeyIdentifierExtension) caCertExt;
+
+ keyId = (KeyIdentifier)
+ id.get(SubjectKeyIdentifierExtension.KEY_ID);
+ }
+ }
+ }
+ }
+
+ } catch (CertificateParsingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CERT_PARSING_ERROR", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CERT_CERT_EXCEPTION", e.toString()));
+ }
+
+ if (keyId != null) {
+ authKeyIdExt = new AuthorityKeyIdentifierExtension(critical, keyId, null, null);
+ } else {
+ GeneralNames gNames = new GeneralNames();
+
+ gNames.addElement(((ICertificateAuthority) crlIssuingPoint.getCertificateAuthority()).getX500Name());
+
+ authKeyIdExt = new AuthorityKeyIdentifierExtension(critical, null, gNames,
+ new SerialNumber(((ICertificateAuthority) crlIssuingPoint.getCertificateAuthority()).getCACert().getSerialNumber()));
+ }
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_AKI_EXT", e.toString()));
+ }
+
+ return authKeyIdExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.AuthorityKey_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);CRL Extension Type. "+
+ //"This field is not editable.",
+ "enable;boolean;Check to enable Authority Key Identifier CRL extension.",
+ "critical;boolean;Set criticality for Authority Key Identifier CRL extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-authoritykeyidentifier",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The authority key identifier extension provides a means " +
+ "of identifying the public key corresponding to the private " +
+ "key used to sign a CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSAuthorityKeyIdentifierExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java
new file mode 100644
index 000000000..578faaa52
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java
@@ -0,0 +1,108 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.CRLNumberExtension;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a CRL number extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLNumberExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSCRLNumberExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ BigInteger crlNumber = null;
+ CRLNumberExtension crlNumberExt = null;
+
+ try {
+ crlNumber = (BigInteger)
+ ((CRLNumberExtension) ext).get(CRLNumberExtension.NUMBER);
+ crlNumberExt = new CRLNumberExtension(Boolean.valueOf(critical),
+ crlNumber);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_CRL_NUMBER_EXT", e.toString()));
+ }
+ return crlNumberExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ CRLNumberExtension crlNumberExt = null;
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+
+ try {
+ crlNumberExt = new CRLNumberExtension(Boolean.valueOf(critical),
+ crlIssuingPoint.getNextCRLNumber());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_CRL_NUMBER_EXT", e.toString()));
+ }
+ return crlNumberExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.CRLNumber_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Extension type. This field is not editable.",
+ "enable;boolean;Check to enable CRL Number extension.",
+ "critical;boolean;Set criticality for CRL Number extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-crlnumber",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The CRL number is a non-critical CRL extension " +
+ "which conveys a monotonically increasing sequence number " +
+ "for each CRL issued by a CA"
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSCRLNumberExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java
new file mode 100644
index 000000000..c8c70138b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java
@@ -0,0 +1,99 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.RevocationReason;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a CRL reason extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLReasonExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSCRLReasonExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ RevocationReason reason = null;
+ CRLReasonExtension crlReasonExt = null;
+
+ try {
+ reason = (RevocationReason) ((CRLReasonExtension) ext).get(CRLReasonExtension.REASON);
+ crlReasonExt = new CRLReasonExtension(Boolean.valueOf(critical), reason);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_CRL_REASON_EXT", e.toString()));
+ }
+ return crlReasonExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object crlIssuingPoint,
+ boolean critical) {
+ CRLReasonExtension crlReasonExt = null;
+
+ return crlReasonExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.ReasonCode_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Entry Extension type. This field is not editable.",
+ "enable;boolean;Check to enable reason code CRL entry extension.",
+ "critical;boolean;Set criticality for reason code CRL entry extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-crlreason",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The CRL reason code is a non-critical CRL entry extension " +
+ "that identifies the reason for the certificate revocation."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSCRLReasonExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java
new file mode 100644
index 000000000..2bde395a6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java
@@ -0,0 +1,222 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.URIName;
+import com.netscape.certsrv.ca.*;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.CertificateIssuerExtension;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+/**
+ * This represents a certificate issuer extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSCertificateIssuerExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSCertificateIssuerExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ CertificateIssuerExtension certIssuerExt = null;
+ GeneralNames names = null;
+
+ try {
+ names = (GeneralNames) ((CertificateIssuerExtension) ext).get(
+ CertificateIssuerExtension.CERTIFICATE_ISSUER);
+ certIssuerExt = new CertificateIssuerExtension(Boolean.valueOf(critical),
+ names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_CERT_ISSUER_EXT", e.toString()));
+ }
+ return certIssuerExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ CertificateIssuerExtension certIssuerExt = null;
+ int numNames = 0;
+
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+
+ try {
+ numNames = config.getInteger("numNames", 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_NUM_NAMES", e.toString()));
+ }
+ if (numNames > 0) {
+ GeneralNames names = new GeneralNames();
+
+ for (int i = 0; i < numNames; i++) {
+ String nameType = null;
+
+ try {
+ nameType = config.getString("nameType" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (nameType != null) {
+ String name = null;
+
+ try {
+ name = config.getString("name" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (name != null && name.length() > 0) {
+ if (nameType.equalsIgnoreCase("DirectoryName")) {
+ try {
+ X500Name dirName = new X500Name(name);
+
+ names.addElement(dirName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_500NAME", e.toString()));
+ }
+ } else if (nameType.equalsIgnoreCase("URI")) {
+ URIName uriName = new URIName(name);
+
+ names.addElement(uriName);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_NAME_TYPE", nameType));
+ }
+ }
+ }
+ }
+
+ if (names.size() > 0) {
+ try {
+ certIssuerExt = new CertificateIssuerExtension(
+ Boolean.valueOf(critical), names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_CERT_ISSUER_EXT", e.toString()));
+ }
+ }
+ }
+
+ return certIssuerExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.CertificateIssuer_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ int numNames = 0;
+
+ try {
+ numNames = config.getInteger("numNames", 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_NUM_NAMES", e.toString()));
+ }
+ nvp.add("numNames", String.valueOf(numNames));
+
+ for (int i = 0; i < numNames; i++) {
+ String nameType = null;
+
+ try {
+ nameType = config.getString("nameType" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (nameType != null && nameType.length() > 0) {
+ nvp.add("nameType" + i, nameType);
+ } else {
+ nvp.add("nameType" + i, "");
+ }
+
+ String name = null;
+
+ try {
+ name = config.getString("name" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (name != null && name.length() > 0) {
+ nvp.add("name" + i, name);
+ } else {
+ nvp.add("name" + i, "");
+ }
+ }
+
+ if (numNames < 3) {
+ for (int i = numNames; i < 3; i++) {
+ nvp.add("nameType" + i, "");
+ nvp.add("name" + i, "");
+ }
+ }
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);CRL Entry Extension type."+
+ //" This field is not editable.",
+ "enable;boolean;Check to enable Certificate Issuer CRL entry extension.",
+ "critical;boolean;Set criticality for Certificate Issuer CRL entry extension.",
+ "numNames;number;Set number of certificate issuer names for the CRL entry.",
+ "nameType0;choice(DirectoryName,URI);Select Certificate Issuer name type.",
+ "name0;string;Enter Certificate Issuer name corresponding to the selected name type.",
+ "nameType1;choice(DirectoryName,URI);Select Certificate Issuer name type.",
+ "name1;string;Enter Certificate Issuer name corresponding to the selected name type.",
+ "nameType2;choice(DirectoryName,URI);Select Certificate Issuer name type.",
+ "name2;string;Enter Certificate Issuer name corresponding to the selected name type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-certificateissuer",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This CRL entry extension identifies the certificate issuer" +
+ " associated with an entry in an indirect CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java
new file mode 100644
index 000000000..f263e0257
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java
@@ -0,0 +1,110 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a delta CRL indicator extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSDeltaCRLIndicatorExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSDeltaCRLIndicatorExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ BigInteger baseCRLNumber = null;
+ DeltaCRLIndicatorExtension deltaCRLIndicatorExt = null;
+
+ try {
+ baseCRLNumber = (BigInteger)
+ ((DeltaCRLIndicatorExtension) ext).get(DeltaCRLIndicatorExtension.NUMBER);
+ deltaCRLIndicatorExt = new DeltaCRLIndicatorExtension(
+ Boolean.valueOf(critical),
+ baseCRLNumber);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DELTA_CRL_EXT", e.toString()));
+ }
+ return deltaCRLIndicatorExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ DeltaCRLIndicatorExtension deltaCRLIndicatorExt = null;
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+
+ try {
+ deltaCRLIndicatorExt = new DeltaCRLIndicatorExtension(
+ Boolean.valueOf(critical),
+ crlIssuingPoint.getCRLNumber());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DELTA_CRL_EXT", e.toString()));
+ }
+ return deltaCRLIndicatorExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.DeltaCRLIndicator_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Extension type. This field is not editable.",
+ "enable;boolean;Check to enable Delta CRL Indicator extension.",
+ "critical;boolean;Set criticality for Delta CRL Indicator extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-crlnumber",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The Delta CRL Indicator is a critical CRL extension " +
+ "which identifies a delta-CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSDeltaCRLIndicatorExtension - " + msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java
new file mode 100644
index 000000000..3f500b464
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java
@@ -0,0 +1,238 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.URIName;
+import com.netscape.certsrv.ca.*;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.util.BitArray;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a freshest CRL extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSFreshestCRLExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ public static final String PROP_NUM_POINTS = "numPoints";
+ public static final String PROP_POINTTYPE = "pointType";
+ public static final String PROP_POINTNAME = "pointName";
+ public static final String PROP_DIRNAME = "DirectoryName";
+ public static final String PROP_URINAME = "URI";
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSFreshestCRLExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ FreshestCRLExtension freshestCRLExt = (FreshestCRLExtension) ext;
+
+ freshestCRLExt.setCritical(critical);
+
+ return freshestCRLExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config, Object ip,
+ boolean critical) {
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+ FreshestCRLExtension freshestCRLExt = null;
+
+ int numPoints = 0;
+
+ try {
+ numPoints = config.getInteger("numPoints", 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_INVALID_NUM_NAMES", e.toString()));
+ }
+
+ if (numPoints > 0) {
+
+ for (int i = 0; i < numPoints; i++) {
+ CRLDistributionPoint crlDP = new CRLDistributionPoint();
+ GeneralNames names = new GeneralNames();
+ String pointType = null;
+
+ try {
+ pointType = config.getString(PROP_POINTTYPE + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointType != null) {
+ String pointName = null;
+
+ try {
+ pointName = config.getString(PROP_POINTNAME + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointName != null && pointName.length() > 0) {
+ if (pointType.equalsIgnoreCase(PROP_DIRNAME)) {
+ try {
+ X500Name dirName = new X500Name(pointName);
+
+ names.addElement(dirName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_500NAME", e.toString()));
+ }
+ } else if (pointType.equalsIgnoreCase(PROP_URINAME)) {
+ URIName uriName = new URIName(pointName);
+
+ names.addElement(uriName);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_POTINT_TYPE", pointType));
+ }
+ }
+ }
+
+ if (names.size() > 0) {
+ try {
+ crlDP.setFullName(names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CANNOT_SET_NAME", e.toString()));
+ } catch (GeneralNamesException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CANNOT_SET_NAME", e.toString()));
+ }
+ }
+
+ if (i > 0) {
+ freshestCRLExt.addPoint(crlDP);
+ } else {
+ freshestCRLExt = new FreshestCRLExtension(crlDP);
+ }
+ }
+ }
+
+ return freshestCRLExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.FreshestCRL_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+
+ int numPoints = 0;
+
+ try {
+ numPoints = config.getInteger(PROP_NUM_POINTS, 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Invalid numPoints property for CRL " +
+ "Freshest CRL extension - " + e);
+ }
+ nvp.add(PROP_NUM_POINTS, String.valueOf(numPoints));
+
+ for (int i = 0; i < numPoints; i++) {
+ String pointType = null;
+
+ try {
+ pointType = config.getString(PROP_POINTTYPE + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointType != null && pointType.length() > 0) {
+ nvp.add(PROP_POINTTYPE + i, pointType);
+ } else {
+ nvp.add(PROP_POINTTYPE + i, "");
+ }
+
+ String pointName = null;
+
+ try {
+ pointName = config.getString(PROP_POINTNAME + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointName != null && pointName.length() > 0) {
+ nvp.add(PROP_POINTNAME + i, pointName);
+ } else {
+ nvp.add(PROP_POINTNAME + i, "");
+ }
+ }
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "enable;boolean;Check to enable Freshest CRL extension.",
+ "critical;boolean;Set criticality for Freshest CRL extension.",
+ PROP_NUM_POINTS + ";number;Set number of CRL distribution points.",
+ PROP_POINTTYPE + "0;choice(" + PROP_DIRNAME + "," + PROP_URINAME +
+ ");Select CRL distribution point name type.",
+ PROP_POINTNAME + "0;string;Enter CRL distribution point name " +
+ "corresponding to the selected point type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-issuingdistributionpoint",
+ PROP_POINTTYPE + "1;choice(" + PROP_DIRNAME + "," + PROP_URINAME +
+ ");Select CRL distribution point name type.",
+ PROP_POINTNAME + "1;string;Enter CRL distribution point name " +
+ "corresponding to the selected point type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-issuingdistributionpoint",
+ PROP_POINTTYPE + "2;choice(" + PROP_DIRNAME + "," + PROP_URINAME +
+ ");Select CRL distribution point name type.",
+ PROP_POINTNAME + "2;string;Enter CRL distribution point name " +
+ "corresponding to the selected point type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-issuingdistributionpoint",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The Freshest CRL is a non critical CRL extension " +
+ "that identifies the delta CRL distribution points for a particular CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSFreshestCRLExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java
new file mode 100644
index 000000000..df0e9e350
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java
@@ -0,0 +1,157 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.util.ObjectIdentifier;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a hold instruction extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSHoldInstructionExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ public static final String PROP_INSTR = "instruction";
+ public static final String PROP_INSTR_NONE = "none";
+ public static final String PROP_INSTR_CALLISSUER = "callissuer";
+ public static final String PROP_INSTR_REJECT = "reject";
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSHoldInstructionExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ HoldInstructionExtension holdInstrExt = null;
+
+ try {
+ ObjectIdentifier holdInstr =
+ ((HoldInstructionExtension) ext).getHoldInstructionCode();
+
+ holdInstrExt = new HoldInstructionExtension(Boolean.valueOf(critical),
+ holdInstr);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_INSTR_EXT", e.toString()));
+ }
+ return holdInstrExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ HoldInstructionExtension holdInstrExt = null;
+ String instruction = null;
+
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+
+ try {
+ instruction = config.getString(PROP_INSTR);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_INVALID", e.toString()));
+ }
+
+ ObjectIdentifier holdInstr = HoldInstructionExtension.NONE_HOLD_INSTR_OID;
+
+ if (instruction != null) {
+ if (instruction.equalsIgnoreCase(PROP_INSTR_CALLISSUER)) {
+ holdInstr = HoldInstructionExtension.CALL_ISSUER_HOLD_INSTR_OID;
+ } else if (instruction.equalsIgnoreCase(PROP_INSTR_REJECT)) {
+ holdInstr = HoldInstructionExtension.REJECT_HOLD_INSTR_OID;
+ }
+ }
+ try {
+ holdInstrExt = new HoldInstructionExtension(Boolean.valueOf(critical),
+ holdInstr);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_INSTR_EXT", e.toString()));
+ }
+
+ return holdInstrExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.HoldInstructionCode_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ String instruction = null;
+
+ try {
+ instruction = config.getString(PROP_INSTR);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_HOLD_INVALID", e.toString()));
+ }
+ if (instruction != null) {
+ if (!(instruction.equalsIgnoreCase(PROP_INSTR_NONE) ||
+ instruction.equalsIgnoreCase(PROP_INSTR_CALLISSUER) ||
+ instruction.equalsIgnoreCase(PROP_INSTR_REJECT))) {
+ instruction = PROP_INSTR_NONE;
+ }
+ } else {
+ instruction = PROP_INSTR_NONE;
+ }
+ nvp.add(PROP_INSTR, instruction);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Entry Extension type. This field is not editable.",
+ "enable;boolean;Check to enable Hold Instruction CRL entry extension.",
+ "critical;boolean;Set criticality for Hold Instruction CRL entry extension.",
+ PROP_INSTR + ";choice(" + PROP_INSTR_NONE + "," + PROP_INSTR_CALLISSUER + "," +
+ PROP_INSTR_REJECT + ");Select hold instruction code.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-holdinstruction",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The hold instruction code is a non-critical CRL entry " +
+ "extension that provides a registered instruction identifier " +
+ "which indicates the action to be taken after encountering " +
+ "a certificate that has been placed on hold."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSHoldInstructionExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java
new file mode 100644
index 000000000..d1dfce9df
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java
@@ -0,0 +1,101 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.util.Date;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.InvalidityDateExtension;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a invalidity date extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSInvalidityDateExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSInvalidityDateExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ InvalidityDateExtension invalidityDateExt = null;
+
+ try {
+ Date invalidityDate = ((InvalidityDateExtension) ext).getInvalidityDate();
+
+ invalidityDateExt = new InvalidityDateExtension(Boolean.valueOf(critical),
+ invalidityDate);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALIDITY_DATE_EXT", e.toString()));
+ }
+ return invalidityDateExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object crlIssuingPoint,
+ boolean critical) {
+ InvalidityDateExtension invalidityDateExt = null;
+
+ return invalidityDateExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.InvalidityDate_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Entry Extension type. This field is not editable.",
+ "enable;boolean;Check to enable Invalidity Date CRL entry extension.",
+ "critical;boolean;Set criticality for Invalidity Date CRL entry extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-invaliditydate",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The invalidity date is a non-critical CRL entry extension " +
+ "that provides the date on which it is known or suspected " +
+ "that the private key was compromised or that the certificate" +
+ " otherwise became invalid."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSInvalidityDateExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java
new file mode 100644
index 000000000..cf66e9d76
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java
@@ -0,0 +1,281 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.EDIPartyName;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a issuer alternative name extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSIssuerAlternativeNameExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ private static final String PROP_RFC822_NAME = "rfc822Name";
+ private static final String PROP_DNS_NAME = "dNSName";
+ private static final String PROP_DIR_NAME = "directoryName";
+ private static final String PROP_EDI_NAME = "ediPartyName";
+ private static final String PROP_URI_NAME = "URI";
+ private static final String PROP_IP_NAME = "iPAddress";
+ private static final String PROP_OID_NAME = "OID";
+ private static final String PROP_OTHER_NAME = "otherName";
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSIssuerAlternativeNameExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ IssuerAlternativeNameExtension issuerAltNameExt = null;
+ GeneralNames names = null;
+
+ try {
+ names = (GeneralNames) ((IssuerAlternativeNameExtension) ext).get(IssuerAlternativeNameExtension.ISSUER_NAME);
+ issuerAltNameExt = new IssuerAlternativeNameExtension(Boolean.valueOf(critical), names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_ALT_NAME_EXT", e.toString()));
+ }
+ return issuerAltNameExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+ IssuerAlternativeNameExtension issuerAltNameExt = null;
+ int numNames = 0;
+
+ try {
+ numNames = config.getInteger("numNames", 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_INVALID_NUM_NAMES", e.toString()));
+ }
+ if (numNames > 0) {
+ GeneralNames names = new GeneralNames();
+
+ for (int i = 0; i < numNames; i++) {
+ String nameType = null;
+
+ try {
+ nameType = config.getString("nameType" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (nameType != null && nameType.length() > 0) {
+ String name = null;
+
+ try {
+ name = config.getString("name" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_UNDEFINED_TYPE", Integer.toString(i), e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_INVALID_TYPE", Integer.toString(i), e.toString()));
+ }
+
+ if (name != null && name.length() > 0) {
+ if (nameType.equalsIgnoreCase(PROP_DIR_NAME)) {
+ try {
+ X500Name dirName = new X500Name(name);
+
+ names.addElement(dirName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_500NAME", e.toString()));
+ }
+ } else if (nameType.equalsIgnoreCase(PROP_RFC822_NAME)) {
+ RFC822Name rfc822Name = new RFC822Name(name);
+
+ names.addElement(rfc822Name);
+ } else if (nameType.equalsIgnoreCase(PROP_DNS_NAME)) {
+ DNSName dnsName = new DNSName(name);
+
+ names.addElement(dnsName);
+ } else if (nameType.equalsIgnoreCase(PROP_EDI_NAME)) {
+ EDIPartyName ediName = new EDIPartyName(name);
+
+ names.addElement(ediName);
+ } else if (nameType.equalsIgnoreCase(PROP_URI_NAME)) {
+ URIName uriName = new URIName(name);
+
+ names.addElement(uriName);
+ } else if (nameType.equalsIgnoreCase(PROP_IP_NAME)) {
+ IPAddressName ipName = new IPAddressName(name);
+
+ names.addElement(ipName);
+ } else if (nameType.equalsIgnoreCase(PROP_OID_NAME)) {
+ ObjectIdentifier oid = new ObjectIdentifier(name);
+ OIDName oidNmae = new OIDName(oid);
+
+ names.addElement(oidNmae);
+ } else if (nameType.equalsIgnoreCase(PROP_OTHER_NAME)) {
+
+ try {
+ byte[] val = com.netscape.osutil.OSUtil.AtoB(name);
+ DerValue derVal = new DerValue(new ByteArrayInputStream(val));
+ GeneralName generalName = new GeneralName(derVal);
+
+ names.addElement(generalName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_OTHER_NAME", e.toString()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_INVALID_TYPE", nameType, ""));
+ }
+ }
+ }
+ }
+
+ if (names.size() > 0) {
+ try {
+ issuerAltNameExt = new IssuerAlternativeNameExtension(
+ Boolean.valueOf(critical), names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_ISSUER_ALT_NAME_EXT", e.toString()));
+ }
+ }
+ }
+
+ return issuerAltNameExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.IssuerAlternativeName_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ int numNames = 0;
+
+ try {
+ numNames = config.getInteger("numNames", 0);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Invalid numNames property for CRL " +
+ "IssuerAlternativeName extension - " + e);
+ }
+ nvp.add("numNames", String.valueOf(numNames));
+
+ for (int i = 0; i < numNames; i++) {
+ String nameType = null;
+
+ try {
+ nameType = config.getString("nameType" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, "Undefined nameType" + i + " property for " +
+ "CRL IssuerAlternativeName extension - " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Invalid nameType" + i + " property for " +
+ "CRL IssuerAlternativeName extension - " + e);
+ }
+
+ if (nameType != null && nameType.length() > 0) {
+ nvp.add("nameType" + i, nameType);
+ } else {
+ nvp.add("nameType" + i, "");
+ }
+
+ String name = null;
+
+ try {
+ name = config.getString("name" + i);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, "Undefined name" + i + " property for " +
+ "CRL IssuerAlternativeName extension - " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Invalid name" + i + " property for " +
+ "CRL IssuerAlternativeName extension - " + e);
+ }
+
+ if (name != null && name.length() > 0) {
+ nvp.add("name" + i, name);
+ } else {
+ nvp.add("name" + i, "");
+ }
+ }
+
+ if (numNames < 3) {
+ for (int i = numNames; i < 3; i++) {
+ nvp.add("nameType" + i, "");
+ nvp.add("name" + i, "");
+ }
+ }
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Extension type. This field is not editable.",
+ "enable;boolean;Check to enable Issuer Alternative Name CRL extension.",
+ "critical;boolean;Set criticality for Issuer Alternative Name CRL extension.",
+ "numNames;number;Set number of alternative names for the CRL issuer.",
+ "nameType0;choice(" + PROP_RFC822_NAME + "," + PROP_DIR_NAME + "," + PROP_DNS_NAME + "," +
+ PROP_EDI_NAME + "," + PROP_URI_NAME + "," + PROP_IP_NAME + "," + PROP_OID_NAME + "," +
+ PROP_OTHER_NAME + ");Select Issuer Alternative Name type.",
+ "name0;string;Enter Issuer Alternative Name corresponding to the selected name type.",
+ "nameType1;choice(" + PROP_RFC822_NAME + "," + PROP_DIR_NAME + "," + PROP_DNS_NAME + "," +
+ PROP_EDI_NAME + "," + PROP_URI_NAME + "," + PROP_IP_NAME + "," + PROP_OID_NAME + "," +
+ PROP_OTHER_NAME + ");Select Issuer Alternative Name type.",
+ "name1;string;Enter Issuer Alternative Name corresponding to the selected name type.",
+ "nameType2;choice(" + PROP_RFC822_NAME + "," + PROP_DIR_NAME + "," + PROP_DNS_NAME + "," +
+ PROP_EDI_NAME + "," + PROP_URI_NAME + "," + PROP_IP_NAME + "," + PROP_OID_NAME + "," +
+ PROP_OTHER_NAME + ");Select Issuer Alternative Name type.",
+ "name2;string;Enter Issuer Alternative Name corresponding to the selected name type.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-issueralternativename",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The issuer alternative names extension allows additional" +
+ " identities to be associated with the issuer of the CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSIssuerAlternativeNameExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java b/pki/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java
new file mode 100644
index 000000000..f273c3201
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java
@@ -0,0 +1,336 @@
+// --- 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.crl;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.URIName;
+import com.netscape.certsrv.ca.*;
+import netscape.security.x509.RDN;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.IssuingDistributionPoint;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.util.BitArray;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represents a issuing distribution point extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSIssuingDistributionPointExtension
+ implements ICMSCRLExtension, IExtendedPluginInfo {
+ public static final String PROP_POINTTYPE = "pointType";
+ public static final String PROP_POINTNAME = "pointName";
+ public static final String PROP_DIRNAME = "DirectoryName";
+ public static final String PROP_URINAME = "URI";
+ public static final String PROP_RDNNAME = "RelativeToIssuer";
+ public static final String PROP_CACERTS = "onlyContainsCACerts";
+ public static final String PROP_USERCERTS = "onlyContainsUserCerts";
+ public static final String PROP_INDIRECT = "indirectCRL";
+ public static final String PROP_REASONS = "onlySomeReasons";
+
+ private static final String[] reasonFlags = {"unused",
+ "keyCompromise",
+ "cACompromise",
+ "affiliationChanged",
+ "superseded",
+ "cessationOfOperation",
+ "certificateHold",
+ "privilegeWithdrawn"};
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public CMSIssuingDistributionPointExtension() {
+ }
+
+ public Extension setCRLExtensionCriticality(Extension ext,
+ boolean critical) {
+ IssuingDistributionPointExtension issuingDPointExt =
+ (IssuingDistributionPointExtension) ext;
+
+ issuingDPointExt.setCritical(critical);
+
+ return issuingDPointExt;
+ }
+
+ public Extension getCRLExtension(IConfigStore config,
+ Object ip,
+ boolean critical) {
+
+ CMS.debug("in CMSIssuingDistributionPointExtension::getCRLExtension.");
+ ICRLIssuingPoint crlIssuingPoint = (ICRLIssuingPoint) ip;
+ IssuingDistributionPointExtension issuingDPointExt = null;
+ IssuingDistributionPoint issuingDPoint = new IssuingDistributionPoint();
+
+ GeneralNames names = new GeneralNames();
+ RDN rdnName = null;
+
+ String pointType = null;
+
+ try {
+ pointType = config.getString(PROP_POINTTYPE);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointType != null) {
+ String pointName = null;
+
+ try {
+ pointName = config.getString(PROP_POINTNAME);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+
+ if (pointName != null && pointName.length() > 0) {
+ if (pointType.equalsIgnoreCase(PROP_RDNNAME)) {
+ try {
+ rdnName = new RDN(pointName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_RDN", e.toString()));
+ }
+ } else if (pointType.equalsIgnoreCase(PROP_DIRNAME)) {
+ try {
+ X500Name dirName = new X500Name(pointName);
+
+ names.addElement(dirName);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_INVALID_500NAME", e.toString()));
+ }
+ } else if (pointType.equalsIgnoreCase(PROP_URINAME)) {
+ URIName uriName = new URIName(pointName);
+
+ names.addElement(uriName);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_POTINT_TYPE", pointType));
+ }
+ }
+ }
+
+ if (rdnName != null) {
+ issuingDPoint.setRelativeName(rdnName);
+ } else if (names.size() > 0) {
+ try {
+ issuingDPoint.setFullName(names);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CANNOT_SET_NAME", e.toString()));
+ } catch (GeneralNamesException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CANNOT_SET_NAME", e.toString()));
+ }
+ }
+
+ String reasons = null;
+
+ try {
+ reasons = config.getString(PROP_REASONS, null);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", PROP_REASONS, e.toString()));
+ }
+ if (reasons != null && reasons.length() > 0) {
+
+ boolean[] bits = {false, false, false, false, false, false, false};
+ int k = 0;
+ StringTokenizer st = new StringTokenizer(reasons, ",");
+
+ while (st.hasMoreTokens()) {
+ String bitName = st.nextToken();
+
+ for (int i = 1; i < reasonFlags.length; i++) {
+ if (bitName.equalsIgnoreCase(reasonFlags[i])) {
+ bits[i] = true;
+ k++;
+ break;
+ }
+ }
+ }
+ if (k > 0) {
+ BitArray ba = new BitArray(bits);
+
+ issuingDPoint.setOnlySomeReasons(ba);
+ }
+
+ }
+
+ try {
+ boolean caCertsOnly = config.getBoolean(PROP_CACERTS, false);
+
+ if (caCertsOnly)
+ issuingDPoint.setOnlyContainsCACerts(caCertsOnly);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "caCertsOnly", e.toString()));
+ }
+ try {
+ boolean userCertsOnly = config.getBoolean(PROP_USERCERTS, false);
+
+ if (userCertsOnly)
+ issuingDPoint.setOnlyContainsUserCerts(userCertsOnly);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "userCertsOnly", e.toString()));
+ }
+ try {
+ boolean indirectCRL = config.getBoolean(PROP_INDIRECT, false);
+
+ if (indirectCRL)
+ issuingDPoint.setIndirectCRL(indirectCRL);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "indirectCRL", e.toString()));
+ }
+
+ issuingDPointExt = new IssuingDistributionPointExtension(issuingDPoint);
+ issuingDPointExt.setCritical(critical);
+
+ return issuingDPointExt;
+ }
+
+ public String getCRLExtOID() {
+ return PKIXExtensions.IssuingDistributionPoint_Id.toString();
+ }
+
+ public void getConfigParams(IConfigStore config, NameValuePairs nvp) {
+ String pointType = null;
+
+ try {
+ pointType = config.getString(PROP_POINTTYPE);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+ if (pointType != null && pointType.length() > 0) {
+ nvp.add("pointType", pointType);
+ } else {
+ nvp.add("pointType", "");
+ }
+
+ String pointName = null;
+
+ try {
+ pointName = config.getString(PROP_POINTNAME);
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_UNDEFINED", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_CREATE_DIST_POINT_INVALID", e.toString()));
+ }
+ if (pointName != null && pointName.length() > 0) {
+ nvp.add("pointName", pointName);
+ } else {
+ nvp.add("pointName", "");
+ }
+
+ String reasons = null;
+
+ try {
+ reasons = config.getString(PROP_REASONS, null);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", PROP_REASONS, e.toString()));
+ }
+ if (reasons != null && reasons.length() > 0) {
+ nvp.add(PROP_REASONS, reasons);
+ } else {
+ nvp.add(PROP_REASONS, "");
+ }
+
+ try {
+ boolean caCertsOnly = config.getBoolean(PROP_CACERTS, false);
+
+ nvp.add(PROP_CACERTS, String.valueOf(caCertsOnly));
+ } catch (EBaseException e) {
+ nvp.add(PROP_CACERTS, "false");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "caCertsOnly", e.toString()));
+ }
+ // Disable these for now unitl we support them fully
+/*
+ try {
+ boolean userCertsOnly = config.getBoolean(PROP_USERCERTS, false);
+
+ nvp.add(PROP_USERCERTS, String.valueOf(userCertsOnly));
+ } catch (EBaseException e) {
+ nvp.add(PROP_USERCERTS, "false");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "userCertsOnly", e.toString()));
+ }
+
+ try {
+ boolean indirectCRL = config.getBoolean(PROP_INDIRECT, false);
+
+ nvp.add(PROP_INDIRECT, String.valueOf(indirectCRL));
+ } catch (EBaseException e) {
+ nvp.add(PROP_INDIRECT, "false");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CRL_INVALID_PROPERTY", "indirectCRL", e.toString()));
+ }
+*/
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ StringBuffer sb_reasons = new StringBuffer();
+ sb_reasons.append(reasonFlags[1]);
+
+ for (int i = 2; i < reasonFlags.length; i++) {
+ sb_reasons.append(", ");
+ sb_reasons.append(reasonFlags[i]);
+ }
+ String[] params = {
+ //"type;choice(CRLExtension,CRLEntryExtension);"+
+ //"CRL Extension type. This field is not editable.",
+ "enable;boolean;Check to enable Issuing Distribution Point CRL extension.",
+ "critical;boolean;Set criticality for Issuing Distribution Point CRL extension.",
+ PROP_POINTTYPE + ";choice(" + PROP_DIRNAME + "," + PROP_URINAME + "," +
+ PROP_RDNNAME + ");Select Issuing Distribution Point name type.",
+ PROP_POINTNAME + ";string;Enter Issuing Distribution Point name " +
+ "corresponding to the selected point type.",
+ PROP_REASONS + ";string;Select any combination of the following reasons: " +
+ sb_reasons.toString(),
+ PROP_CACERTS + ";boolean;Check if CRL contains CA certificates only",
+ // Remove these from the UI until they can be supported fully.
+ // PROP_USERCERTS + ";boolean;Check if CRL contains user certificates only",
+ // PROP_INDIRECT + ";boolean;Check if CRL is built indirectly.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ca-edit-crlextension-issuingdistributionpoint",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";The issuing distribution point is a critical CRL extension " +
+ "that identifies the CRL distribution point for a particular CRL."
+ };
+
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSIssuingDistributionPointExtension - " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
new file mode 100644
index 000000000..f51fd2cbb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
@@ -0,0 +1,182 @@
+// --- 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.evaluators;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.evaluators.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * A class represents a group acls evaluator.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class GroupAccessEvaluator implements IAccessEvaluator {
+ private String mType = "group";
+ private IUGSubsystem mUG = null;
+ private String mDescription = "group membership evaluator";
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Class constructor.
+ */
+ public GroupAccessEvaluator() {
+
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ if (mUG == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUTOR_UG_NULL"));
+ }
+ }
+
+ /**
+ * initialization. nothing for now.
+ */
+ public void init() {
+ CMS.debug("GroupAccessEvaluator: init");
+ }
+
+ /**
+ * gets the type name for this acl evaluator
+ * @return type for this acl evaluator: "group" or "at_group"
+ */
+ 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 uid in AuthToken to see if it has membership in
+ * group value
+ * @param authToken authentication token
+ * @param type must be "at_group"
+ * @param op must be "="
+ * @param value the group name
+ * @return true if AuthToken uid belongs to the group value,
+ * false otherwise
+ */
+ public boolean evaluate(IAuthToken authToken, String type, String op, String value) {
+
+ if (type.equals(mType)) {
+ // should define "uid" at a common place
+ String uid = null;
+
+ uid = authToken.getInString("userid");
+ if (uid == null) {
+ uid = authToken.getInString("uid");
+ if (uid == null) {
+ CMS.debug("GroupAccessEvaluator: evaluate: uid null");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUTOR_UID_NULL"));
+ return false;
+ }
+ }
+ CMS.debug("GroupAccessEvaluator: evaluate: uid="+uid +" value="+value);
+
+ String groupname = authToken.getInString("gid");
+
+ if (groupname != null) {
+ CMS.debug("GroupAccessEvaluator: evaluate: authToken gid="+groupname);
+ if (op.equals("=")) {
+ return groupname.equals(Utils.stripQuotes(value));
+ } else if (op.equals("!=")) {
+ return !groupname.equals(Utils.stripQuotes(value));
+ }
+ } else {
+ CMS.debug("GroupAccessEvaluator: evaluate: no gid in authToken");
+ IUser id = null;
+ try {
+ id = mUG.getUser(uid);
+ } catch (EBaseException e) {
+ CMS.debug("GroupAccessEvaluator: " + e.toString());
+ return false;
+ }
+
+ if (op.equals("=")) {
+ return mUG.isMemberOf(id, Utils.stripQuotes(value));
+ } else if (op.equals("!=")) {
+ return !(mUG.isMemberOf(id, Utils.stripQuotes(value)));
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * evaluates uid in SessionContext to see if it has membership in
+ * group value
+ * @param type must be "group"
+ * @param op must be "="
+ * @param value the group name
+ * @return true if SessionContext uid belongs to the group value,
+ * false otherwise
+ */
+ public boolean evaluate(String type, String op, String value) {
+
+ SessionContext mSC = SessionContext.getContext();
+
+ if (type.equals(mType)) {
+ IUser id = (IUser) mSC.get(SessionContext.USER);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUTOR_UID_NULL"));
+ return false;
+ }
+ if (op.equals("="))
+ return mUG.isMemberOf(id, Utils.stripQuotes(value));
+ else
+ return !(mUG.isMemberOf(id, Utils.stripQuotes(value)));
+
+ }
+
+ return false;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ACLS,
+ level, "GroupAccessEvaluator: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java
new file mode 100644
index 000000000..3c041219d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java
@@ -0,0 +1,130 @@
+// --- 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.evaluators;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.evaluators.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * A class represents a IP address acls evaluator.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class IPAddressAccessEvaluator implements IAccessEvaluator {
+ private String mType = "ipaddress";
+ private String mDescription = "IP Address evaluator";
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Class constructor.
+ */
+ public IPAddressAccessEvaluator() {
+ }
+
+ /**
+ * initialization. nothing for now.
+ */
+ public void init() {
+ }
+
+ /**
+ * gets the type name for this acl evaluator
+ * @return type for this acl evaluator: ipaddress
+ */
+ 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;
+ }
+
+ /**
+ * Gets the IP address from session context
+ * @param authToken authentication token
+ * @param type must be "ipaddress"
+ * @param op must be "=" or "!="
+ * @param value the ipaddress
+ */
+ public boolean evaluate(IAuthToken authToken, String type, String op, String value) {
+
+ return evaluate(type, op, value);
+ }
+
+ /**
+ * evaluates uid in SessionContext to see if it has membership in
+ * group value
+ * @param type must be "group"
+ * @param op must be "="
+ * @param value the group name
+ * @return true if SessionContext uid belongs to the group value,
+ * false otherwise
+ */
+ public boolean evaluate(String type, String op, String value) {
+
+ SessionContext mSC = SessionContext.getContext();
+
+ value = Utils.stripQuotes(value);
+ String ipaddress = (String) mSC.get(SessionContext.IPADDRESS);
+
+ if (type.equals(mType)) {
+ if (ipaddress == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUATOR_IPADDRESS_NULL"));
+ return false;
+ }
+ if (op.equals("=")) {
+ return ipaddress.matches(value);
+ } else {
+ return !(ipaddress.matches(value));
+ }
+
+ }
+
+ return false;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ACLS,
+ level, "GroupAccessEvaluator: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
new file mode 100644
index 000000000..dcdfe2c48
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
@@ -0,0 +1,153 @@
+// --- 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.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 acls evaluator.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserAccessEvaluator implements IAccessEvaluator {
+ private String mType = "user";
+ private String mDescription = "user equivalence evaluator";
+ private ILogger mLogger = CMS.getLogger();
+
+ private final static String ANYBODY = "anybody";
+ private final static String EVERYBODY = "everybody";
+
+ /**
+ * Class constructor.
+ */
+ public UserAccessEvaluator() {
+ }
+
+ /**
+ * initialization. nothing for now.
+ */
+ public void init() {
+ CMS.debug("UserAccessEvaluator: init");
+ }
+
+ /**
+ * gets the type name for this acl evaluator
+ * @return type for this acl evaluator: "user" or "at_user"
+ */
+ 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_user"
+ * @param op must be "="
+ * @param value the user id
+ * @return true if AuthToken uid is same as value, false otherwise
+ */
+ public boolean evaluate(IAuthToken authToken, String type, String op, String value) {
+
+ 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) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("EVALUTOR_UID_IS_NULL"));
+ return false;
+ }
+
+ if (op.equals("="))
+ return s.equalsIgnoreCase(uid);
+ else if (op.equals("!="))
+ return !(s.equalsIgnoreCase(uid));
+ }
+
+ return false;
+ }
+
+ /**
+ * Evaluates the user in session context to see if it's equal to value
+ * @param type must be "user"
+ * @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)) {
+ String s = Utils.stripQuotes(value);
+
+ if (s.equals(ANYBODY) && op.equals("="))
+ return true;
+
+ IUser id = (IUser) mSC.get(SessionContext.USER);
+
+ if (op.equals("="))
+ return s.equalsIgnoreCase(id.getName());
+ else if (op.equals("!="))
+ return !(s.equalsIgnoreCase(id.getName()));
+ }
+
+ return false;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ACLS,
+ level, "UserAccessEvaluator: " + msg);
+ }
+
+}
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..e5faeeff5
--- /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/jobs/AJobBase.java b/pki/base/common/src/com/netscape/cms/jobs/AJobBase.java
new file mode 100644
index 000000000..2e26264f8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/jobs/AJobBase.java
@@ -0,0 +1,281 @@
+// --- 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.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This abstract class is a base job for real job extentions for the
+ * Jobs Scheduler.
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.jobs.IJob
+ */
+public abstract class AJobBase implements IJob, Runnable {
+ // config parameters...
+ protected static final String PROP_SUMMARY = "summary";
+ protected static final String PROP_ENABLED = "enabled";
+ protected static final String PROP_EMAIL_SUBJECT = "emailSubject";
+ protected static final String PROP_EMAIL_TEMPLATE = "emailTemplate";
+ protected static final String PROP_ITEM_TEMPLATE = "itemTemplate";
+ protected static final String PROP_SENDER_EMAIL = "senderEmail";
+ protected static final String PROP_RECEIVER_EMAIL = "recipientEmail";
+
+ protected static final String STATUS_FAILURE = "failed";
+ protected static final String STATUS_SUCCESS = "succeeded";
+
+ // variables used by the Job Scheduler Daemon
+ protected String mImplName = null;
+ protected IConfigStore mConfig;
+ protected String mId = null;
+ protected String mCron = null;
+ protected IJobCron mJobCron = null;
+
+ protected ILogger mLogger = CMS.getLogger();
+ protected static String[] mConfigParams = null;
+
+ protected String mSummaryMailSubject = null;
+ protected boolean mMailHTML = false;
+ protected String mMailForm = null;
+ protected String mItemForm = null;
+ protected String mSummarySenderEmail = null;
+ protected String mSummaryReceiverEmail = null;
+ protected Hashtable mContentParams = new Hashtable();
+ protected Hashtable mItemParams = new Hashtable();
+
+ public AJobBase() {
+ }
+
+ /**
+ * tells if the job is enabled
+ * @return a boolean value indicating whether the job is enabled
+ * or not
+ */
+ public boolean isEnabled() {
+ boolean enabled = false;
+
+ try {
+ enabled = mConfig.getBoolean(PROP_ENABLED, false);
+ } catch (EBaseException e) {
+ }
+ return enabled;
+ }
+
+ /***********************
+ * abstract methods
+ ***********************/
+ public abstract void init(ISubsystem owner, String id, String implName, IConfigStore
+ config) throws EBaseException;
+
+ public abstract void run();
+
+ /***********************
+ * public methods
+ ***********************/
+
+ /**
+ * get instance id.
+ * @return a String identifier
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * set instance id.
+ * @param id String id of the instance
+ */
+ public void setId(String id) {
+ mId = id;
+ }
+
+ /**
+ * get cron string associated with this job
+ * @return a JobCron object that represents the schedule of this job
+ */
+ public IJobCron getJobCron() {
+ return mJobCron;
+ }
+
+ /**
+ * gets the plugin name of this job.
+ * @return a String that is the name of this implementation
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * Gets the configuration substore used by this job
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /*
+ * get form file content from disk
+ */
+ protected String getTemplateContent(String templatePath) {
+ String templateString = null;
+
+ /*
+ * get template file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(templatePath);
+
+ if (template != null) {
+ if (!template.init()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_TEMPLATE_INIT_ERROR"));
+ return null;
+ }
+
+ // this should take care of inner tempaltes not being html
+ // we go with the outter template
+ if (template.isHTML()) {
+ mMailHTML = true;
+ }
+ templateString = template.toString();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_TEMPLATE_INIT_ERROR"));
+ }
+
+ return templateString;
+ }
+
+ protected void mailSummary(String content) {
+ // no need for email resolver here...
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSummarySenderEmail);
+ mn.setTo(mSummaryReceiverEmail);
+ mn.setSubject(mSummaryMailSubject);
+ if (mMailHTML == true) {
+ mn.setContentType("text/html");
+ }
+
+ mn.setContent(content);
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ // already logged, lets audit
+ mLogger.log(ILogger.EV_AUDIT, null,
+ ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_SEND_NOTIFICATION", e.toString()));
+ } catch (IOException e) {
+ // already logged, lets audit
+ mLogger.log(ILogger.EV_AUDIT, null,
+ ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_SEND_NOTIFICATION", e.toString()));
+ }
+ }
+
+ protected void buildItemParams(X509CertImpl cert) {
+ mItemParams.put(IEmailFormProcessor.TOKEN_SERIAL_NUM,
+ (Object) cert.getSerialNumber().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ (Object) cert.getSerialNumber().toString(16));
+ mItemParams.put(IEmailFormProcessor.TOKEN_ISSUER_DN,
+ (Object) cert.getIssuerDN().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ (Object) cert.getSubjectDN().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_NOT_AFTER,
+ (Object) cert.getNotAfter().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_NOT_BEFORE,
+ (Object) cert.getNotBefore().toString());
+ // ... and more
+ }
+
+ protected void buildItemParams(IRequest r) {
+ String re = r.getExtDataInString(IRequest.HTTP_PARAMS, "csrRequestorEmail");
+
+ if (re != null) {
+ mItemParams.put(IEmailFormProcessor.TOKEN_REQUESTOR_EMAIL, re);
+ }
+
+ String ct = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (ct != null) {
+ mItemParams.put(IEmailFormProcessor.TOKEN_CERT_TYPE, ct);
+ }
+
+ String rt = r.getExtDataInString(IRequest.REQ_TYPE);
+
+ if (rt != null) {
+ mItemParams.put(IEmailFormProcessor.TOKEN_REQUEST_TYPE, rt);
+ }
+ }
+
+ protected void buildItemParams(String name, String val) {
+ if (val != null)
+ mItemParams.put(name, val);
+ else {
+ CMS.debug("AJobBase: buildItemParams: null value for name= " + name);
+ mItemParams.put(name, "");
+ }
+ }
+
+ protected void buildContentParams(String name, String val) {
+ if (val != null)
+ mContentParams.put(name, val);
+ else {
+ CMS.debug("AJobBase: buildContentParams: null value for name= " + name);
+ mContentParams.put(name, "");
+ }
+ }
+
+ /**
+ * logs an entry in the log file. Used by classes extending this class.
+ * @param level log level
+ * @param msg log message in String
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, mId + ": " + msg);
+ }
+
+ /**
+ * capable of logging multiline entry in the log file. Used by classes extending this class.
+ * @param level log level
+ * @param msg log message in String
+ * @param multiline boolean indicating whether the message is a
+ * multi-lined message.
+ */
+ public void log(int level, String msg, boolean multiline) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, mId + ": " + msg, multiline);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java b/pki/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java
new file mode 100644
index 000000000..5da23d045
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java
@@ -0,0 +1,405 @@
+// --- 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.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.DateFormat;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * a job for the Jobs Scheduler. This job checks in the internal ldap
+ * db for valid certs that have not been published to the
+ * publishing directory.
+ * <p>
+ * the $TOKENS that are available for the this jobs's summary outer form are:<br>
+ * <UL>
+ * $Status
+ * $InstanceID
+ * $SummaryItemList
+ * $SummaryTotalNum
+ * $SummaryTotalSuccess
+ * $SummaryTotalfailure
+ * $ExecutionTime
+ * </UL>
+ * and for the inner list items:
+ * <UL>
+ * $SerialNumber
+ * $IssuerDN
+ * $SubjectDN
+ * $NotAfter
+ * $NotBefore
+ * $RequestorEmail
+ * $CertType
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PublishCertsJob extends AJobBase
+ implements IJob, Runnable, IExtendedPluginInfo {
+
+ ICertificateAuthority mCa = null;
+ IRequestQueue mReqQ = null;
+ ICertificateRepository mRepository = null;
+ IPublisherProcessor mPublisherProcessor = null;
+ private boolean mSummary = false;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {
+ "enabled",
+ "cron",
+ "summary.enabled",
+ "summary.emailSubject",
+ "summary.emailTemplate",
+ "summary.itemTemplate",
+ "summary.senderEmail",
+ "summary.recipientEmail"
+ };
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+ static {
+ mExtendedPluginInfo = new Vector();
+ };
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ IExtendedPluginInfo.HELP_TEXT +
+ "; A job that checks for valid certificates in the " +
+ "database, that have not been published and publish them to " +
+ "the publishing directory",
+ "cron;string;Format: minute hour dayOfMonth month " +
+ "dayOfWeek. Use '*' for 'every'. For dayOfWeek, 0 is Sunday",
+ "summary.senderEmail;string;Specify the address to be used " +
+ "as the email's 'sender'. Bounces go to this address.",
+ "summary.recipientEmail;string;Who should receive summaries",
+ "enabled;boolean;Enable this plugin",
+ "summary.enabled;boolean;Enable the summary. You must enabled " +
+ "this for the job to work.",
+ "summary.emailSubject;string;Subject of summary email",
+ "summary.emailTemplate;string;Fully qualified pathname of " +
+ "template file of email to be sent",
+ "summary.itemTemplate;string;Fully qualified pathname of " +
+ "file containing template for each item",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-jobrules-unpublishexpiredjobs",
+ };
+
+ return s;
+ }
+
+ /**
+ * initialize from the configuration file
+ */
+ public void init(ISubsystem owner, String id, String implName, IConfigStore config) throws
+ EBaseException {
+ mConfig = config;
+ mId = id;
+ mImplName = implName;
+
+ mCa = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ if (mCa == null) {
+ return;
+ }
+
+ mReqQ = mCa.getRequestQueue();
+ mRepository = (ICertificateRepository) mCa.getCertificateRepository();
+ mPublisherProcessor = mCa.getPublisherProcessor();
+
+ // read from the configuration file
+ mCron = mConfig.getString(IJobCron.PROP_CRON);
+ if (mCron == null) {
+ return;
+ }
+
+ // parse cron string into a JobCron class
+ IJobsScheduler scheduler = (IJobsScheduler) owner;
+
+ mJobCron = scheduler.createJobCron(mCron);
+
+ // initialize the summary related config info
+ IConfigStore sc = mConfig.getSubStore(PROP_SUMMARY);
+
+ if (sc.getBoolean(PROP_ENABLED, false)) {
+ mSummary = true;
+ mSummaryMailSubject = sc.getString(PROP_EMAIL_SUBJECT);
+ mMailForm = sc.getString(PROP_EMAIL_TEMPLATE);
+ mItemForm = sc.getString(PROP_ITEM_TEMPLATE);
+ mSummarySenderEmail = sc.getString(PROP_SENDER_EMAIL);
+ mSummaryReceiverEmail = sc.getString(PROP_RECEIVER_EMAIL);
+ } else {
+ mSummary = false;
+ }
+ }
+
+ /**
+ * look in the internal db for certificateRecords that are
+ * valid but not published
+ * The publish() method should set <b>InLdapPublishDir</b> flag accordingly.
+ * if publish unsuccessfully, log it -- unsuccessful certs should be
+ * picked up and attempted again at the next scheduled run
+ */
+ public void run() {
+ CMS.debug("in PublishCertsJob "+
+ getId()+ " : run()");
+ // get time now..."now" is before the loop
+ Date date = CMS.getCurrentDate();
+ long now = date.getTime();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(date);
+
+ // form filter
+ String filter = // might need to use "metaInfo"
+ "(!(certMetainfo=" + ICertRecord.META_LDAPPUBLISH +
+ ":true))";
+
+ Enumeration unpublishedCerts = null;
+
+ try {
+ unpublishedCerts = mRepository.findCertRecs(filter);
+ // bug 399150
+ /*
+ CertRecordList list = null;
+ list = mRepository.findCertRecordsInList(filter, null, "serialno", 5);
+ int size = list.getSize();
+ expired = list.getCertRecords(0, size - 1);
+ */
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ int count = 0; // how many have been published successfully
+ int negCount = 0; // how many have NOT been published successfully
+ String contentForm = null;
+ String itemForm = null;
+ String itemListContent = null;
+
+ if (mSummary == true) {
+ contentForm = getTemplateContent(mMailForm);
+ itemForm = getTemplateContent(mItemForm);
+ }
+
+ // filter out the invalid ones and publish them
+ // publish() will set inLdapPublishDir flag
+ while (unpublishedCerts != null && unpublishedCerts.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) unpublishedCerts.nextElement();
+
+ if (rec == null) break;
+ X509CertImpl cert = rec.getCertificate();
+ Date notBefore = cert.getNotBefore();
+ Date notAfter = cert.getNotAfter();
+
+ // skip CA certs
+ if (cert.getBasicConstraintsIsCA() == true)
+ continue;
+
+ // skip the expired certs
+ if (notAfter.before(date))
+ continue;
+
+ if (mSummary == true)
+ buildItemParams(cert);
+
+ // get request id from cert record MetaInfo
+ MetaInfo minfo = null;
+
+ try {
+ minfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_INFO_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+
+ String ridString = null;
+
+ try {
+ if (minfo != null)
+ ridString = (String) minfo.get(ICertRecord.META_REQUEST_ID);
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ } catch (NullPointerException e) {
+ // no requestId in MetaInfo...skip to next record
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ // get request from request id
+ IRequest req = null;
+
+ try {
+ req = mReqQ.findRequest(rid);
+ if (req != null) {
+ if (mSummary == true)
+ buildItemParams(req);
+ }
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_FIND_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ try {
+ if ((mPublisherProcessor != null) &&
+ mPublisherProcessor.enabled()) {
+ mPublisherProcessor.publishCert((X509Certificate) cert, req);
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_SUCCESS);
+ count += 1;
+ } else {
+ negCount += 1;
+ }
+ } catch (Exception e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_PUBLISH_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ } // ridString != null
+ else {
+ try {
+ if ((mPublisherProcessor != null) &&
+ mPublisherProcessor.enabled()) {
+ mPublisherProcessor.publishCert((X509Certificate) cert, null);
+
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_SUCCESS);
+ count += 1;
+ } else {
+ negCount += 1;
+ }
+ } catch (Exception e) {
+ negCount += 1;
+
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_PUBLISH_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ } // ridString == null
+
+ // inLdapPublishDir flag should have been set by the
+ // publish() method
+
+ // if summary is enabled, form the item content
+ if (mSummary) {
+ IEmailFormProcessor emailItemFormProcessor =
+ CMS.getEmailFormProcessor();
+ String c = emailItemFormProcessor.getEmailContent(itemForm,
+ mItemParams);
+
+ // add item content to the item list
+ if (itemListContent == null) {
+ itemListContent = c;
+ } else {
+ itemListContent += c;
+ }
+ }
+ }
+
+ // time for summary
+ if (mSummary == true) {
+ buildContentParams(IEmailFormProcessor.TOKEN_ID,
+ mId);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_ITEM_LIST,
+ itemListContent);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_TOTAL_NUM,
+ String.valueOf(count + negCount));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_SUCCESS_NUM,
+ String.valueOf(count));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_FAILURE_NUM,
+ String.valueOf(negCount));
+ buildContentParams(IEmailFormProcessor.TOKEN_EXECUTION_TIME,
+ nowString);
+
+ IEmailFormProcessor emailFormProcessor = CMS.getEmailFormProcessor();
+ String mailContent =
+ emailFormProcessor.getEmailContent(contentForm,
+ mContentParams);
+
+ mailSummary(mailContent);
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java b/pki/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java
new file mode 100644
index 000000000..03df4843d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java
@@ -0,0 +1,718 @@
+// --- 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.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.DateFormat;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+
+
+/**
+ * A job for the Jobs Scheduler. This job checks in the internal ldap
+ * db for certs about to expire within the next configurable days and
+ * sends email notifications to the appropriate recipients.
+ *
+ * the $TOKENS that are available for the this jobs's summary outer form are:<br
+ >
+ * <UL>
+ * <LI>$Status
+ * <LI>$InstanceID
+ * <LI>$SummaryItemList
+ * <LI>$SummaryTotalNum
+ * <LI>$SummaryTotalSuccess
+ * <LI>$SummaryTotalfailure
+ * <LI>$ExecutionTime
+ * </UL>
+ * and for the inner list items:
+ * <UL>
+ * <LI>$SerialNumber
+ * <LI>$IssuerDN
+ * <LI>$SubjectDN
+ * <LI>$NotAfter
+ * <LI>$NotBefore
+ * <LI>$RequestorEmail
+ * <LI>$CertType
+ * <LI>$RequestType
+ * <LI>$HttpHost
+ * <LI>$HttpPort
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.jobs.IJob
+ * @see com.netscape.cms.jobs.AJobBase
+ */
+public class RenewalNotificationJob
+ extends AJobBase
+ implements IJob, Runnable, IExtendedPluginInfo {
+
+ // config parameters...
+ public static final String PROP_CRON = "cron";
+
+ /**
+ * Profile ID specifies which profile approves the certificate.
+ */
+ public static final String PROP_PROFILE_ID = "profileId";
+
+ /**
+ * This job will send notification at this much time before the
+ * enpiration date
+ */
+ public static final String PROP_NOTIFYTRIGGEROFFSET =
+ "notifyTriggerOffset";
+
+ /**
+ * This job will stop sending notification this much time after
+ * the expiration date
+ */
+ public static final String PROP_NOTIFYENDOFFSET = "notifyEndOffset";
+
+ /**
+ * sender email address as appeared on the notification email
+ */
+ public static final String PROP_SENDEREMAIL =
+ "senderEmail";
+
+ /**
+ * email subject line as appeared on the notification email
+ */
+ public static final String PROP_EMAILSUBJECT =
+ "emailSubject";
+
+ /**
+ * location of the template file used for email notification
+ */
+ public static final String PROP_EMAILTEMPLATE = "emailTemplate";
+ public static final String PROP_MAXNOTIFYCOUNT = "maxNotifyCount";
+
+ /**
+ * sender email as appeared on the notification summary email
+ */
+ public static final String PROP_SUMMARY_SENDEREMAIL = "summary.senderEmail";
+
+ /**
+ * recipient of the notification summary email
+ */
+ public static final String PROP_SUMMARY_RECIPIENTEMAIL = "summary.recipientEmail";
+
+ /**
+ * email subject as appeared on the notification summary email
+ */
+ public static final String PROP_SUMMARY_SUBJECT = "summary.emailSubject";
+
+ /**
+ * location of the email template used for notification summary
+ */
+ public static final String PROP_SUMMARY_TEMPLATE = "summary.emailTemplate";
+
+ /**
+ * location of the template file for each item appeared on the
+ * notification summary
+ */
+ public static final String PROP_SUMMARY_ITEMTEMPLATE = "summary.itemTemplate";
+
+ /*
+ * Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {
+ "enabled",
+ PROP_CRON,
+ PROP_PROFILE_ID,
+ PROP_NOTIFYTRIGGEROFFSET,
+ PROP_NOTIFYENDOFFSET,
+ PROP_SENDEREMAIL,
+ PROP_EMAILSUBJECT,
+ PROP_EMAILTEMPLATE,
+ "summary.enabled",
+ PROP_SUMMARY_RECIPIENTEMAIL,
+ PROP_SUMMARY_SENDEREMAIL,
+ PROP_SUMMARY_SUBJECT,
+ PROP_SUMMARY_ITEMTEMPLATE,
+ PROP_SUMMARY_TEMPLATE,
+ };
+
+ protected ICertificateRepository mCertDB = null;
+ protected ICertificateAuthority mCA = null;
+ protected boolean mSummary = false;
+ protected String mEmailSender = null;
+ protected String mEmailSubject = null;
+ protected String mEmailTemplateName = null;
+ protected String mSummaryItemTemplateName = null;
+ protected String mSummaryTemplateName = null;
+ protected boolean mSummaryHTML = false;
+ protected boolean mHTML = false;
+
+ protected String mHttpHost = null;
+ protected String mHttpPort = null;
+
+ private int mPreDays = 0;
+ private long mPreMS = 0;
+ private int mPostDays = 0;
+ private long mPostMS = 0;
+ private int mMaxNotifyCount = 1;
+ private String[] mProfileId = null;
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+
+ static {
+ mExtendedPluginInfo = new Vector();
+ };
+
+ /**
+ * class constructor
+ */
+ public RenewalNotificationJob () {
+ }
+
+ /**
+ * holds help text for this plugin
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ IExtendedPluginInfo.HELP_TEXT +
+ "; A job that checks for expiring or expired certs" +
+ "notifyTriggerOffset before and notifyEndOffset after " +
+ "the expiration date",
+
+ PROP_PROFILE_ID + ";string;Specify the ID of the profile which "+
+ "approved the certificates that are about to expire. For multiple "+
+ "profiles, each entry is separated by white space. For example, " +
+ "if the administrator just wants to give automated notification " +
+ "when the SSL server certificates are about to expire, then "+
+ "he should enter \"caServerCert caAgentServerCert\" in the profileId textfield. "+
+ "Blank field means all profiles.",
+ PROP_NOTIFYTRIGGEROFFSET + ";number,required;How long (in days) before " +
+ "certificate expiration will the first notification " +
+ "be sent",
+ PROP_NOTIFYENDOFFSET + ";number,required;How long (in days) after " +
+ "certificate expiration will notifications " +
+ "continue to be resent if certificate is not renewed",
+ PROP_CRON + ";string,required;Format: minute hour dayOfMonth Mmonth " +
+ "dayOfWeek. Use '*' for 'every'. For dayOfWeek, 0 is Sunday",
+ PROP_SENDEREMAIL + ";string,required;Specify the address to be used " +
+ "as the email's 'sender'. Bounces go to this address.",
+ PROP_EMAILSUBJECT + ";string,required;Email subject",
+ PROP_EMAILTEMPLATE + ";string,required;Fully qualified pathname of " +
+ "template file of email to be sent",
+ "enabled;boolean;Enable this plugin",
+ "summary.enabled;boolean;Enabled sending of summaries",
+ PROP_SUMMARY_SENDEREMAIL + ";string,required;Sender email address of summary",
+ PROP_SUMMARY_RECIPIENTEMAIL + ";string,required;Who should receive summaries",
+ PROP_SUMMARY_SUBJECT + ";string,required;Subject of summary email",
+ PROP_SUMMARY_TEMPLATE + ";string,required;Fully qualified pathname of " +
+ "template file of email to be sent",
+ PROP_SUMMARY_ITEMTEMPLATE + ";string,required;Fully qualified pathname of " +
+ "file with template to be used for each summary item",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-jobrules-renewalnotification",
+ };
+
+ return s;
+ }
+
+ /**
+ * Initialize from the configuration file.
+ * @param id String name of this instance
+ * @param implName string name of this implementation
+ * @param config configuration store for this instance
+ * @exception EBaseException
+ */
+ public void init(ISubsystem owner, String id, String implName, IConfigStore config) throws
+ EBaseException {
+ mConfig = config;
+ mId = id;
+ mImplName = implName;
+
+ mCA = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ if (mCA == null) {
+ mSummary = false;
+ return;
+ }
+
+ mCertDB = (ICertificateRepository) mCA.getCertificateRepository();
+
+ mCron = mConfig.getString(IJobCron.PROP_CRON);
+ if (mCron == null) {
+ return;
+ }
+
+ // parse cron string into a JobCron class
+ IJobsScheduler scheduler = (IJobsScheduler) owner;
+
+ mJobCron = scheduler.createJobCron(mCron);
+ }
+
+ /**
+ * finds out which cert needs notification and notifies the
+ * responsible parties
+ */
+ public void run() {
+ // for forming renewal URL at template
+ mHttpHost = CMS.getEEHost();
+ mHttpPort = CMS.getEESSLPort();
+
+ // read from the configuration file
+ try {
+ mPreDays = mConfig.getInteger(PROP_NOTIFYTRIGGEROFFSET, 30); // in days
+ mPostDays = mConfig.getInteger(PROP_NOTIFYENDOFFSET, 15); // in days
+
+ mEmailSender = mConfig.getString(PROP_SENDEREMAIL);
+ mEmailSubject = mConfig.getString(PROP_EMAILSUBJECT);
+ mEmailTemplateName = mConfig.getString(PROP_EMAILTEMPLATE);
+
+ // initialize the summary related config info
+ IConfigStore sc = mConfig.getSubStore(PROP_SUMMARY);
+
+ if (sc.getBoolean(PROP_ENABLED, false)) {
+ mSummary = true;
+ mSummaryItemTemplateName =
+ mConfig.getString(PROP_SUMMARY_ITEMTEMPLATE);
+ mSummarySenderEmail =
+ mConfig.getString(PROP_SUMMARY_SENDEREMAIL);
+ mSummaryReceiverEmail =
+ mConfig.getString(PROP_SUMMARY_RECIPIENTEMAIL);
+ mSummaryMailSubject =
+ mConfig.getString(PROP_SUMMARY_SUBJECT);
+ mSummaryTemplateName =
+ mConfig.getString(PROP_SUMMARY_TEMPLATE);
+ } else {
+ mSummary = false;
+ }
+
+ long msperday = 86400 * 1000;
+ long mspredays = mPreDays;
+ long mspostdays = mPostDays;
+
+ mPreMS = mspredays * msperday;
+ mPostMS = mspostdays * msperday;
+
+ Date now = CMS.getCurrentDate();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(now);
+
+ /*
+ * look in the internal db for certificateRecords that are
+ * 1. within the expiration notification period
+ * 2. has not yet been renewed
+ * 3. notify - use EmailTemplateProcessor to formulate
+ * content, then send
+ * if notified successfully, mark "STATUS_SUCCESS",
+ * else, if notified unsuccessfully, mark "STATUS_FAILURE".
+ */
+
+ /* 1) make target notAfter string */
+
+ Date expiryDate = null;
+ Date stopDate = null;
+
+ /* 2) Assemble ldap Search filter string */
+ // date format: 19991215125306Z
+ long expiryMS = now.getTime() + mPreMS;
+ long stopMS = now.getTime() - mPostMS;
+
+ expiryDate = new Date(expiryMS);
+ stopDate = new Date(stopMS);
+
+ // All cert records which:
+ // 1) expire before the deadline
+ // 2) have not already been renewed
+ // filter format:
+ // (& (notafter<='time')(!(certAutoRenew=DONE))(!certAutoRenew=DISABLED))
+
+ StringBuffer f = new StringBuffer();
+ String profileId = "";
+ try {
+ profileId = mConfig.getString(PROP_PROFILE_ID, "");
+ } catch (EBaseException ee) {
+ }
+
+ if (profileId != null && profileId.length() > 0) {
+ StringTokenizer tokenizer = new StringTokenizer(profileId);
+ int num = tokenizer.countTokens();
+ mProfileId = new String[num];
+ for (int i=0; i<num; i++)
+ mProfileId[i] = tokenizer.nextToken();
+ }
+
+ f.append("(&");
+ if (mProfileId != null) {
+ if (mProfileId.length == 1)
+ f.append("("+ICertRecord.ATTR_META_INFO+ "=" +
+ ICertRecord.META_PROFILE_ID +":"+mProfileId[0]+")");
+ else {
+ f.append("(|");
+ for (int i=0; i<mProfileId.length; i++) {
+ f.append("("+ICertRecord.ATTR_META_INFO+ "=" +
+ ICertRecord.META_PROFILE_ID +":"+mProfileId[i]+")");
+ }
+ f.append(")");
+ }
+ }
+
+ f.append("(" + ICertRecord.ATTR_X509CERT + ".notAfter" + "<=" + expiryDate.getTime() + ")");
+ f.append("(" + ICertRecord.ATTR_X509CERT + ".notAfter" + ">=" + stopDate.getTime() + ")");
+ f.append("(!(" + ICertRecord.ATTR_AUTO_RENEW + "=" + ICertRecord.AUTO_RENEWAL_DONE + "))");
+ f.append("(!(" + ICertRecord.ATTR_AUTO_RENEW + "=" + ICertRecord.AUTO_RENEWAL_DISABLED + "))");
+ f.append("(!(" + ICertRecord.ATTR_CERT_STATUS + "=" + ICertRecord.STATUS_REVOKED + "))");
+ f.append("(!(" + ICertRecord.ATTR_CERT_STATUS + "=" + ICertRecord.STATUS_REVOKED_EXPIRED + "))");
+ f.append(")");
+ String filter = f.toString();
+
+ String emailTemplate =
+ getTemplateContent(mEmailTemplateName);
+
+ mHTML = mMailHTML;
+
+ try {
+ String summaryItemTemplate = null;
+
+ if (mSummary == true) {
+ summaryItemTemplate =
+ getTemplateContent(mSummaryItemTemplateName);
+ }
+
+ ItemCounter ic = new ItemCounter();
+ CertRecProcessor cp = new CertRecProcessor(this, emailTemplate, summaryItemTemplate, ic);
+ //CertRecordList list = mCertDB.findCertRecordsInList(filter, null, "serialno", 5);
+ //list.processCertRecords(0, list.getSize() - 1, cp);
+
+ Enumeration en = mCertDB.findCertRecs(filter);
+
+ while (en.hasMoreElements()) {
+ Object element = (Object) en.nextElement();
+
+ try {
+ cp.process(element);
+ } catch (Exception e) {
+ //Don't abort the entire operation. The error should already be logged
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_FAILED_PROCESS", e.toString()));
+ }
+ }
+
+ // Now send the summary
+
+ if (mSummary == true) {
+ try {
+ String summaryTemplate =
+ getTemplateContent(mSummaryTemplateName);
+
+ mSummaryHTML = mMailHTML;
+
+ buildContentParams(IEmailFormProcessor.TOKEN_ID,
+ mId);
+
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_ITEM_LIST,
+ ic.mItemListContent);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_TOTAL_NUM,
+ String.valueOf(ic.mNumFail + ic.mNumSuccessful));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_SUCCESS_NUM,
+ String.valueOf(ic.mNumSuccessful));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_FAILURE_NUM,
+ String.valueOf(ic.mNumFail));
+
+ buildContentParams(IEmailFormProcessor.TOKEN_EXECUTION_TIME,
+ nowString);
+
+ IEmailFormProcessor summaryEmfp = CMS.getEmailFormProcessor();
+
+ String summaryContent =
+ summaryEmfp.getEmailContent(summaryTemplate,
+ mContentParams);
+
+ if (summaryContent == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_SUMMARY_CONTENT_NULL"));
+ mailSummary(" no summaryContent");
+ } else {
+ mMailHTML = mSummaryHTML;
+ mailSummary(summaryContent);
+ }
+ } catch (Exception e) {
+ // log error
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("JOBS_EXCEPTION_IN_RUN", e.toString()));
+ }
+ }
+ } catch (EBaseException e) {
+ // log error
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ } catch (EBaseException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("Configuration error:", ex.toString()));
+ }
+ }
+
+ private String makeLDAPDateString(Date d) {
+
+ String ldfYear = "" + Integer.toString(d.getYear());
+
+ String ldfMonth = getPadded(d.getMonth());
+ String ldfDate = getPadded(d.getDate());
+ String ldfHours = getPadded(d.getHours());
+ String ldfMinutes = getPadded(d.getMinutes());
+ String ldfSeconds = getPadded(d.getSeconds());
+
+ return ldfYear + ldfMonth + ldfDate + ldfHours + ldfMinutes + ldfSeconds + "Z";
+ }
+
+ private String getPadded(int i) {
+ if (i < 10) {
+ return "0" + Integer.toString(i);
+ } else {
+ return "" + Integer.toString(i);
+ }
+ }
+
+ /**
+ * get instance id.
+ * @return a String identifier
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * set instance id.
+ * @param id String id of the instance
+ */
+ public void setId(String id) {
+ mId = id;
+ }
+
+ /**
+ * get cron string associated with this job
+ * @return a JobCron object that represents the schedule of this job
+ */
+ public IJobCron getJobCron() {
+ return mJobCron;
+ }
+
+ /**
+ * gets the plugin name of this job.
+ * @return a String that is the name of this implementation
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * Gets the configuration substore used by this job
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ protected void mailUser(String subject,
+ String msg,
+ String sender,
+ IRequest req,
+ ICertRecord cr)
+ throws IOException, ENotificationException, EBaseException {
+
+ IMailNotification mn = CMS.getMailNotification();
+
+ String rcp = null;
+ // boolean sendFailed = false;
+ Exception sendFailedException = null;
+
+ IEmailResolverKeys keys = CMS.getEmailResolverKeys();
+
+ try {
+ if (req != null) {
+ keys.set(IEmailResolverKeys.KEY_REQUEST, req);
+ }
+ if (cr != null) {
+ Object c = cr.getCertificate();
+
+ if (c != null) {
+ keys.set(IEmailResolverKeys.KEY_CERT, cr.getCertificate());
+ }
+ }
+
+ IEmailResolver er = CMS.getReqCertSANameEmailResolver();
+
+ rcp = er.getEmail(keys);
+
+ } catch (Exception e) {
+ // already logged by the resolver
+ // sendFailed = true;
+ sendFailedException = e;
+ throw (ENotificationException) sendFailedException;
+ }
+
+ mn.setTo(rcp);
+
+ if (sender != null) mn.setFrom(sender);
+ else mn.setFrom("nobody");
+
+ if (subject != null) mn.setSubject(subject);
+ else mn.setFrom("Important message from Certificate Authority");
+
+ if (mHTML == true) mn.setContentType("text/html");
+
+ String failedString = null;
+
+ mn.setContent(msg);
+
+ mn.sendNotification();
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+}
+
+
+class CertRecProcessor implements IElementProcessor {
+ protected RenewalNotificationJob mJob;
+ protected String mEmailTemplate;
+ protected String mSummaryItemTemplate;
+ protected ItemCounter mIC;
+
+ public CertRecProcessor(RenewalNotificationJob job, String emailTemplate,
+ String summaryItemTemplate, ItemCounter ic) {
+ mJob = job;
+ mEmailTemplate = emailTemplate;
+ mSummaryItemTemplate = summaryItemTemplate;
+ mIC = ic;
+ }
+
+ public void process(Object o) throws EBaseException {
+
+ // Get each certRecord
+ ICertRecord cr = (ICertRecord) o;
+
+ String ridString = null;
+ boolean numFailCounted = false;
+
+ if (cr != null) {
+ mJob.buildItemParams(cr.getCertificate());
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ mJob.mHttpHost);
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_HTTP_PORT, mJob.mHttpPort);
+
+ MetaInfo metaInfo = null;
+
+ metaInfo = (MetaInfo) cr.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ mIC.mNumFail++;
+ numFailCounted = true;
+ if (mJob.mSummary == true)
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ mJob.STATUS_FAILURE);
+ mJob.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_GET_CERT_ERROR",
+ cr.getCertificate().getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+ }
+
+ IRequest req = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ try {
+ req = mJob.mCA.getRequestQueue().findRequest(rid);
+ } catch (Exception e) {
+ // it is ok not to be able to get the request. The main reason
+ // to get the request is to retrieve the requestor's email.
+ // We can retrieve the email from the CertRecord.
+ CMS.debug("huh RenewalNotificationJob Exception: "+e.toString());
+ }
+
+ if (req != null)
+ mJob.buildItemParams(req);
+ } // ridString != null
+
+ try {
+ // send mail to user
+
+ IEmailFormProcessor emfp = CMS.getEmailFormProcessor();
+ String message = emfp.getEmailContent(mEmailTemplate,
+ mJob.mItemParams);
+
+ mJob.mailUser(mJob.mEmailSubject,
+ message,
+ mJob.mEmailSender,
+ req,
+ cr);
+
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ mJob.STATUS_SUCCESS);
+
+ mIC.mNumSuccessful++;
+
+ } catch (Exception e) {
+ CMS.debug("RenewalNotificationJob Exception: "+e.toString());
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_STATUS, mJob.STATUS_FAILURE);
+ mJob.log(ILogger.LL_FAILURE, e.toString(), ILogger.L_MULTILINE);
+ if (numFailCounted == false) {
+ mIC.mNumFail++;
+ }
+ }
+
+ if (mJob.mSummary == true) {
+ IEmailFormProcessor summaryItemEmfp =
+ CMS.getEmailFormProcessor();
+ String c =
+ summaryItemEmfp.getEmailContent(mSummaryItemTemplate,
+ mJob.mItemParams);
+
+ if (mIC.mItemListContent == null) {
+ mIC.mItemListContent = c;
+ } else {
+ mIC.mItemListContent += c;
+ }
+ }
+ }
+}
+
+
+class ItemCounter {
+ public int mNumSuccessful = 0;
+ public int mNumFail = 0;
+ public String mItemListContent = null;
+}
diff --git a/pki/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java b/pki/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java
new file mode 100644
index 000000000..88a8bf35d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java
@@ -0,0 +1,219 @@
+// --- 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.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.DateFormat;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * A job for the Jobs Scheduler. This job checks in the internal ldap
+ * db for requests currently in the request queue and send a summary
+ * report to the administrator
+ * <p>
+ * the $TOKENS that are available for the this jobs's summary outer form are:<br>
+ * <UL>
+ * $InstanceID
+ * $SummaryTotalNum
+ * $ExecutionTime
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.jobs.IJob
+ * @see com.netscape.cms.jobs.AJobBase
+ */
+public class RequestInQueueJob extends AJobBase
+ implements IJob, Runnable, IExtendedPluginInfo {
+ protected static final String PROP_SUBSYSTEM_ID = "subsystemId";
+
+ IAuthority mSub = null;
+ IRequestQueue mReqQ = null;
+ private boolean mSummary = false;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {
+ "enabled",
+ "cron",
+ "subsystemId",
+ "summary.enabled",
+ "summary.emailSubject",
+ "summary.emailTemplate",
+ "summary.senderEmail",
+ "summary.recipientEmail"
+ };
+
+ /**
+ * holds help text for this plugin
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ IExtendedPluginInfo.HELP_TEXT +
+ "; A job that checks for enrollment requests in the " +
+ "queue, and reports to recipientEmail",
+ "cron;string;Format: minute hour dayOfMonth month " +
+ "dayOfWeek. Use '*' for 'every'. For dayOfWeek, 0 is Sunday",
+ "summary.senderEmail;string;Specify the address to be used " +
+ "as the email's 'sender'. Bounces go to this address.",
+ "summary.recipientEmail;string;Who should receive summaries",
+ "enabled;boolean;Enable this plugin",
+ "summary.enabled;boolean;Enable the summary. You must enabled " +
+ "this for the job to work.",
+ "summary.emailSubject;string;Subject of summary email",
+ "summary.emailTemplate;string;Fully qualified pathname of " +
+ "template file of email to be sent",
+ "subsystemId;choice(ca,ra);The type of subsystem this job is " +
+ "for",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-jobrules-requestinqueuejob",
+ };
+
+ return s;
+ }
+
+ /**
+ * initialize from the configuration file
+ * @param id String name of this instance
+ * @param implName string name of this implementation
+ * @param config configuration store for this instance
+ * @exception EBaseException
+ */
+ public void init(ISubsystem owner, String id, String implName, IConfigStore config) throws
+ EBaseException {
+ mConfig = config;
+ mId = id;
+ mImplName = implName;
+
+ // read from the configuration file
+ String sub = mConfig.getString(PROP_SUBSYSTEM_ID);
+
+ mSub = (IAuthority)
+ CMS.getSubsystem(sub);
+ if (mSub == null) {
+ // take this as disable
+ mSummary = false;
+ return;
+ }
+
+ mReqQ = mSub.getRequestQueue();
+
+ mCron = mConfig.getString(IJobCron.PROP_CRON);
+ if (mCron == null) {
+ return;
+ }
+
+ // parse cron string into a JobCron class
+ IJobsScheduler scheduler = (IJobsScheduler) owner;
+
+ mJobCron = scheduler.createJobCron(mCron);
+
+ // initialize the summary related config info
+ IConfigStore sc = mConfig.getSubStore(PROP_SUMMARY);
+
+ if (sc.getBoolean(PROP_ENABLED, false)) {
+ mSummary = true;
+ mSummaryMailSubject = sc.getString(PROP_EMAIL_SUBJECT);
+ mMailForm = sc.getString(PROP_EMAIL_TEMPLATE);
+ // mItemForm = sc.getString(PROP_ITEM_TEMPLATE);
+ mSummarySenderEmail = sc.getString(PROP_SENDER_EMAIL);
+ mSummaryReceiverEmail = sc.getString(PROP_RECEIVER_EMAIL);
+ } else {
+ mSummary = false;
+ }
+ }
+
+ /**
+ * summarize the queue status and mail it
+ */
+ public void run() {
+ if (mSummary == false) return;
+
+ Date date = CMS.getCurrentDate();
+ long now = date.getTime();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(date);
+
+ int count = 0;
+ IRequestList list =
+ mReqQ.listRequestsByStatus(RequestStatus.PENDING);
+
+ while (list != null && list.hasMoreElements()) {
+ RequestId rid = list.nextRequestId();
+
+ /* This is way too slow
+ // get request from request id
+ IRequest req = null;
+ try {
+ req = mReqQ.findRequest(rid);
+ } catch (EBaseException e) {
+ System.out.println(e.toString());
+ }
+ */
+ count++;
+ }
+
+ // if (count == 0) return;
+
+ String contentForm = null;
+
+ contentForm = getTemplateContent(mMailForm);
+
+ buildContentParams(IEmailFormProcessor.TOKEN_ID, mId);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_TOTAL_NUM,
+ String.valueOf(count));
+ buildContentParams(IEmailFormProcessor.TOKEN_EXECUTION_TIME,
+ nowString);
+
+ IEmailFormProcessor emailFormProcessor = CMS.getEmailFormProcessor();
+ String mailContent =
+ emailFormProcessor.getEmailContent(contentForm,
+ mContentParams);
+
+ mailSummary(mailContent);
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java b/pki/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java
new file mode 100644
index 000000000..1813bd639
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java
@@ -0,0 +1,395 @@
+// --- 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.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.DateFormat;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * a job for the Jobs Scheduler. This job checks in the internal ldap
+ * db for certs that have expired and remove them from the ldap
+ * publishing directory.
+ * <p>
+ * the $TOKENS that are available for the this jobs's summary outer form are:<br>
+ * <UL>
+ * $Status
+ * $InstanceID
+ * $SummaryItemList
+ * $SummaryTotalNum
+ * $SummaryTotalSuccess
+ * $SummaryTotalfailure
+ * $ExecutionTime
+ * </UL>
+ * and for the inner list items:
+ * <UL>
+ * $SerialNumber
+ * $IssuerDN
+ * $SubjectDN
+ * $NotAfter
+ * $NotBefore
+ * $RequestorEmail
+ * $CertType
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ */
+public class UnpublishExpiredJob extends AJobBase
+ implements IJob, Runnable, IExtendedPluginInfo {
+
+ ICertificateAuthority mCa = null;
+ IRequestQueue mReqQ = null;
+ ICertificateRepository mRepository = null;
+ IPublisherProcessor mPublisherProcessor = null;
+ private boolean mSummary = false;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {
+ "enabled",
+ "cron",
+ "summary.enabled",
+ "summary.emailSubject",
+ "summary.emailTemplate",
+ "summary.itemTemplate",
+ "summary.senderEmail",
+ "summary.recipientEmail"
+ };
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector mExtendedPluginInfo = null;
+ static {
+ mExtendedPluginInfo = new Vector();
+ };
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ IExtendedPluginInfo.HELP_TEXT +
+ "; A job that checks for expired certificates in the " +
+ "database, and removes them from the publishing " +
+ "directory",
+ "cron;string;Format: minute hour dayOfMonth month " +
+ "dayOfWeek. Use '*' for 'every'. For dayOfWeek, 0 is Sunday",
+ "summary.senderEmail;string;Specify the address to be used " +
+ "as the email's 'sender'. Bounces go to this address.",
+ "summary.recipientEmail;string;Who should receive summaries",
+ "enabled;boolean;Enable this plugin",
+ "summary.enabled;boolean;Enable the summary. You must enabled " +
+ "this for the job to work.",
+ "summary.emailSubject;string;Subject of summary email",
+ "summary.emailTemplate;string;Fully qualified pathname of " +
+ "template file of email to be sent",
+ "summary.itemTemplate;string;Fully qualified pathname of " +
+ "file containing template for each item",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-jobrules-unpublishexpiredjobs",
+ };
+
+ return s;
+ }
+
+ /**
+ * initialize from the configuration file
+ */
+ public void init(ISubsystem owner, String id, String implName, IConfigStore config) throws
+ EBaseException {
+ mConfig = config;
+ mId = id;
+ mImplName = implName;
+
+ mCa = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ if (mCa == null) {
+ return;
+ }
+
+ mReqQ = mCa.getRequestQueue();
+ mRepository = (ICertificateRepository) mCa.getCertificateRepository();
+ mPublisherProcessor = mCa.getPublisherProcessor();
+
+ // read from the configuration file
+ mCron = mConfig.getString(IJobCron.PROP_CRON);
+ if (mCron == null) {
+ return;
+ }
+
+ // parse cron string into a JobCron class
+ IJobsScheduler scheduler = (IJobsScheduler) owner;
+
+ mJobCron = scheduler.createJobCron(mCron);
+
+ // initialize the summary related config info
+ IConfigStore sc = mConfig.getSubStore(PROP_SUMMARY);
+
+ if (sc.getBoolean(PROP_ENABLED, false)) {
+ mSummary = true;
+ mSummaryMailSubject = sc.getString(PROP_EMAIL_SUBJECT);
+ mMailForm = sc.getString(PROP_EMAIL_TEMPLATE);
+ mItemForm = sc.getString(PROP_ITEM_TEMPLATE);
+ mSummarySenderEmail = sc.getString(PROP_SENDER_EMAIL);
+ mSummaryReceiverEmail = sc.getString(PROP_RECEIVER_EMAIL);
+ } else {
+ mSummary = false;
+ }
+ }
+
+ /**
+ * look in the internal db for certificateRecords that are
+ * expired.
+ * remove them from ldap publishing directory
+ * if remove successfully, mark <i>false</i> on the
+ * <b>InLdapPublishDir</b> flag,
+ * else, if remove unsuccessfully, log it
+ */
+ public void run() {
+ // System.out.println("in ExpiredUnpublishJob "+
+ // getId()+ " : run()");
+ // get time now..."now" is before the loop
+ Date date = CMS.getCurrentDate();
+ long now = date.getTime();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(date);
+
+ // form filter
+ String filter = "(&(x509Cert.notAfter<=" + now +
+ ")(!(x509Cert.notAfter=" + now + "))" +
+ "(" + "certMetainfo=" + ICertRecord.META_LDAPPUBLISH +
+ ":true))";
+ // a test for without CertRecord.META_LDAPPUBLISH
+ //String filter = "(x509Cert.notAfter<="+ now +")";
+
+ Enumeration expired = null;
+
+ try {
+ expired = mRepository.findCertRecs(filter);
+ // bug 399150
+ /*
+ CertRecordList list = null;
+ list = mRepository.findCertRecordsInList(filter, null, "serialno", 5);
+ int size = list.getSize();
+ expired = list.getCertRecords(0, size - 1);
+ */
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ int count = 0; // how many have been unpublished successfully
+ int negCount = 0; // how many have NOT been unpublished successfully
+ String contentForm = null;
+ String itemForm = null;
+ String itemListContent = null;
+
+ if (mSummary == true) {
+ contentForm = getTemplateContent(mMailForm);
+ itemForm = getTemplateContent(mItemForm);
+ }
+
+ // unpublish them and unpublish() will set inLdapPublishDir flag
+ while (expired != null && expired.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) expired.nextElement();
+
+ if (rec == null) break;
+ X509CertImpl cert = rec.getCertificate();
+
+ if (mSummary == true)
+ buildItemParams(cert);
+
+ // get request id from cert record MetaInfo
+ MetaInfo minfo = null;
+
+ try {
+ minfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_INFO_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+
+ String ridString = null;
+
+ try {
+ if (minfo != null)
+ ridString = (String) minfo.get(ICertRecord.META_REQUEST_ID);
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ } catch (NullPointerException e) {
+ // no requestId in MetaInfo...skip to next record
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ // get request from request id
+ IRequest req = null;
+
+ try {
+ req = mReqQ.findRequest(rid);
+ if (req != null) {
+ if (mSummary == true)
+ buildItemParams(req);
+ }
+ } catch (EBaseException e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_FIND_REQUEST_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ try {
+ if ((mPublisherProcessor != null) &&
+ mPublisherProcessor.enabled()) {
+ mPublisherProcessor.unpublishCert((X509Certificate) cert, req);
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_SUCCESS);
+ count += 1;
+ } else {
+ negCount += 1;
+ }
+ } catch (Exception e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_UNPUBLISH_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ } // ridString != null
+ else {
+ try {
+ if ((mPublisherProcessor != null) &&
+ mPublisherProcessor.enabled()) {
+ mPublisherProcessor.unpublishCert((X509Certificate) cert, null);
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_SUCCESS);
+ count += 1;
+ } else {
+ negCount += 1;
+ }
+ } catch (Exception e) {
+ negCount += 1;
+ if (mSummary == true)
+ buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
+ STATUS_FAILURE);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("JOBS_UNPUBLISH_ERROR",
+ cert.getSerialNumber().toString(16) +
+ e.toString()));
+ }
+ } // ridString == null
+
+ // inLdapPublishDir flag should have been set by the
+ // unpublish() method
+
+ // if summary is enabled, form the item content
+ if (mSummary) {
+ IEmailFormProcessor emailItemFormProcessor =
+ CMS.getEmailFormProcessor();
+ String c = emailItemFormProcessor.getEmailContent(itemForm,
+ mItemParams);
+
+ // add item content to the item list
+ if (itemListContent == null) {
+ itemListContent = c;
+ } else {
+ itemListContent += c;
+ }
+ }
+ }
+
+ // time for summary
+ if (mSummary == true) {
+ buildContentParams(IEmailFormProcessor.TOKEN_ID,
+ mId);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_ITEM_LIST,
+ itemListContent);
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_TOTAL_NUM,
+ String.valueOf(count + negCount));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_SUCCESS_NUM,
+ String.valueOf(count));
+ buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_FAILURE_NUM,
+ String.valueOf(negCount));
+ buildContentParams(IEmailFormProcessor.TOKEN_EXECUTION_TIME,
+ nowString);
+
+ IEmailFormProcessor emailFormProcessor = CMS.getEmailFormProcessor();
+ String mailContent =
+ emailFormProcessor.getEmailContent(contentForm,
+ mContentParams);
+
+ mailSummary(mailContent);
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java b/pki/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java
new file mode 100644
index 000000000..c9b4c4a7f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java
@@ -0,0 +1,445 @@
+// --- 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.listeners;
+
+
+import java.io.File;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.listeners.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.apps.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import java.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import java.text.DateFormat;
+
+
+/**
+ * a listener for every completed enrollment request
+ * <p>
+ * Here is a list of available $TOKENs for email notification
+ templates if certificate is successfully issued:
+ * <UL>
+ * <LI>$InstanceID
+ * <LI>$SerialNumber
+ * <LI>$HexSerialNumber
+ * <LI>$HttpHost
+ * <LI>$HttpPort
+ * <LI>$RequestId
+ * <LI>$IssuerDN
+ * <LI>$SubjectDN
+ * <LI>$NotBefore
+ * <LI>$NotAfter
+ * <LI>$SenderEmail
+ * <LI>$RecipientEmail
+ * </UL>
+ * <p>
+ * Here is a list of available $TOKENs for email notification
+ templates if certificate request is rejected:
+ * <UL>
+ * <LI>$RequestId
+ * <LI>$InstanceID
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertificateIssuedListener implements IRequestListener {
+ protected final static String PROP_CERT_ISSUED_SUBSTORE = "certIssued";
+ protected static final String PROP_ENABLED = "enabled";
+ protected final static String PROP_NOTIFY_SUBSTORE = "notification";
+
+ protected final static String PROP_SENDER_EMAIL = "senderEmail";
+ protected final static String PROP_EMAIL_SUBJECT = "emailSubject";
+ public final static String PROP_EMAIL_TEMPLATE = "emailTemplate";
+
+ protected final static String REJECT_FILE_NAME = "certRequestRejected";
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private String mSenderEmail = null;
+ private String mSubject = null;
+ private String mSubject_Success = null;
+ private String mFormPath = null;
+ private String mRejectPath = null;
+ private Hashtable mContentParams = new Hashtable();
+
+ private ICertAuthority mSub = null;
+ private IConfigStore mConfig = null;
+ private DateFormat mDateFormat = null;
+ private ICertAuthority mSubsystem = null;
+ private String mHttpHost = null;
+ private String mHttpPort = null;
+ private RequestId mReqId = null;
+
+ public CertificateIssuedListener() {
+ }
+
+ public void init(ISubsystem sub, IConfigStore config)
+ throws EListenersException, EPropertyNotFound, EBaseException {
+ mSubsystem = (ICertAuthority) sub;
+ mConfig = mSubsystem.getConfigStore();
+
+ IConfigStore nc = mConfig.getSubStore(PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(PROP_CERT_ISSUED_SUBSTORE);
+
+ mEnabled = rc.getBoolean(PROP_ENABLED, false);
+
+ mSenderEmail = rc.getString(PROP_SENDER_EMAIL);
+ if (mSenderEmail == null) {
+ throw new EListenersException(CMS.getLogMessage("NO_NOTIFY_SENDER_EMAIL_CONFIG_FOUND"));
+ }
+
+ mFormPath = rc.getString(PROP_EMAIL_TEMPLATE);
+ String mDir = null;
+
+ // figure out the reject email path: same dir as form path,
+ // same ending as form path
+ int ridx = mFormPath.lastIndexOf(File.separator);
+
+ if (ridx == -1) {
+ CMS.debug("CertificateIssuedListener: file separator: " + File.separator
+ +
+ " not found. Use default /");
+ ridx = mFormPath.lastIndexOf("/");
+ mDir = mFormPath.substring(0, ridx + 1);
+ } else {
+ mDir = mFormPath.substring(0, ridx +
+ File.separator.length());
+ }
+ CMS.debug("CertificateIssuedListener: template file directory: " + mDir);
+ mRejectPath = mDir + REJECT_FILE_NAME;
+ if (mFormPath.endsWith(".html"))
+ mRejectPath += ".html";
+ else if (mFormPath.endsWith(".HTML"))
+ mRejectPath += ".HTML";
+ else if (mFormPath.endsWith(".htm"))
+ mRejectPath += ".htm";
+ else if (mFormPath.endsWith(".HTM"))
+ mRejectPath += ".HTM";
+
+ CMS.debug("CertificateIssuedListener: Reject file path: " + mRejectPath);
+
+ mDateFormat = DateFormat.getDateTimeInstance();
+
+ mSubject_Success = rc.getString(PROP_EMAIL_SUBJECT,
+ "Your Certificate Request");
+ mSubject = new String(mSubject_Success);
+
+ // form the cert retrieval URL for the notification
+ mHttpHost = CMS.getEEHost();
+ mHttpPort = CMS.getEESSLPort();
+
+ // register for this event listener
+ mSubsystem.registerRequestListener(this);
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug("CertificateIssuedListener: accept " +
+ r.getRequestId().toString());
+ if (mEnabled != true) return;
+
+ mSubject = mSubject_Success;
+ mReqId = r.getRequestId();
+ // is it rejected?
+ String rs = r.getRequestStatus().toString();
+
+ if (rs.equals("rejected")) {
+ CMS.debug("CertificateIssuedListener: Request status: " + rs);
+ rejected(r);
+ return;
+ }
+
+ CMS.debug("CertificateIssuedListener: accept check status ");
+
+ // check if it is profile request
+ String profileId = r.getExtDataInString("profileId");
+
+ // check if request failed.
+ if (profileId == null) {
+ if (r.getExtDataInInteger(IRequest.RESULT) == null)
+ return;
+ if ((r.getExtDataInInteger(IRequest.RESULT)).equals(IRequest.RES_ERROR)) {
+ CMS.debug("CertificateIssuedListener: Request errored. " +
+ "No need to email notify for enrollment request id " +
+ mReqId);
+ return;
+ }
+ }
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.ENROLLMENT_REQUEST) ||
+ requestType.equals(IRequest.RENEWAL_REQUEST)) {
+ CMS.debug("accept() enrollment/renewal request...");
+ // Get the certificate from the request
+ X509CertImpl issuedCert[] = null;
+
+ // handle profile-based enrollment's notification
+ if (profileId == null) {
+ issuedCert = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ } else {
+ issuedCert = new X509CertImpl[1];
+ issuedCert[0] =
+ r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ }
+
+ if (issuedCert != null) {
+ CMS.debug("CertificateIssuedListener: Sending email notification..");
+
+ // do we have an email to send?
+ String mEmail = null;
+ IEmailResolverKeys keys = CMS.getEmailResolverKeys();
+
+ try {
+ keys.set(IEmailResolverKeys.KEY_REQUEST, r);
+ keys.set(IEmailResolverKeys.KEY_CERT,
+ issuedCert[0]);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET_RESOLVER", e.toString()));
+ }
+
+ IEmailResolver er = CMS.getReqCertSANameEmailResolver();
+
+ try {
+ mEmail = er.getEmail(keys);
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ }
+
+ // now we can mail
+ if ((mEmail != null) && (!mEmail.equals(""))) {
+ mailIt(mEmail, issuedCert);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_NOTIFY_ERROR",
+ issuedCert[0].getSerialNumber().toString(), mReqId.toString()));
+ // send failure notification to "sender"
+ mSubject = "Certificate Issued notification undeliverable";
+ mailIt(mSenderEmail, issuedCert);
+ }
+ }
+ }
+ }
+
+ private void mailIt(String mEmail, X509CertImpl issuedCert[]) {
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSenderEmail);
+ mn.setTo(mEmail);
+ mn.setSubject(mSubject);
+
+ /*
+ * get template file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(mFormPath);
+
+ /*
+ * parse and process the template
+ */
+ if (template != null) {
+ if (!template.init()) {
+ return;
+ }
+
+ buildContentParams(issuedCert, mEmail);
+ IEmailFormProcessor et = CMS.getEmailFormProcessor();
+ String c = et.getEmailContent(template.toString(), mContentParams);
+
+ if (template.isHTML()) {
+ mn.setContentType("text/html");
+ }
+ mn.setContent(c);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_TEMPLATE_ERROR",
+ issuedCert[0].getSerialNumber().toString(), mReqId.toString()));
+
+ mn.setContent("Serial Number = " +
+ issuedCert[0].getSerialNumber() +
+ "; Request ID = " + mReqId);
+ }
+
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ }
+
+ private void rejected(IRequest r) {
+ // do we have an email to send?
+ String mEmail = null;
+ IEmailResolverKeys keys = CMS.getEmailResolverKeys();
+
+ try {
+ keys.set(IEmailResolverKeys.KEY_REQUEST, r);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET_RESOLVER", e.toString()));
+ }
+
+ IEmailResolver er = CMS.getReqCertSANameEmailResolver();
+
+ try {
+ mEmail = er.getEmail(keys);
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ // now we can mail
+ if ((mEmail != null) && !mEmail.equals("")) {
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSenderEmail);
+ mn.setTo(mEmail);
+ mn.setSubject(mSubject);
+
+ /*
+ * get rejection file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(mRejectPath);
+
+ if (template != null) {
+ if (!template.init()) {
+ return;
+ }
+
+ if (template.isHTML()) {
+ mn.setContentType("text/html");
+ }
+
+ // build some token data
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ mReqId = r.getRequestId();
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ (Object) mReqId.toString());
+ IEmailFormProcessor et = CMS.getEmailFormProcessor();
+ String c = et.getEmailContent(template.toString(), mContentParams);
+
+ mn.setContent(c);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_CERT_ISSUED_REJECTION"));
+ mn.setContent("Your Certificate Request has been rejected. Please contact your administrator for assistance");
+ }
+
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ // already logged, lets audit
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_REJECTION_NOTIFICATION", mReqId.toString()));
+
+ }
+ }
+
+ private void buildContentParams(X509CertImpl issuedCert[], String mEmail) {
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SERIAL_NUM,
+ (Object) issuedCert[0].getSerialNumber().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ (Object) Long.toHexString(issuedCert[0].getSerialNumber().longValue()));
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ (Object) mReqId.toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ (Object) mHttpHost);
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_PORT,
+ (Object) mHttpPort);
+ mContentParams.put(IEmailFormProcessor.TOKEN_ISSUER_DN,
+ (Object) issuedCert[0].getIssuerDN().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ (Object) issuedCert[0].getSubjectDN().toString());
+
+ Date date = (Date) issuedCert[0].getNotAfter();
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_NOT_AFTER,
+ mDateFormat.format(date));
+
+ date = (Date) issuedCert[0].getNotBefore();
+ mContentParams.put(IEmailFormProcessor.TOKEN_NOT_BEFORE,
+ mDateFormat.format(date));
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_SENDER_EMAIL,
+ (Object) mSenderEmail);
+ mContentParams.put(IEmailFormProcessor.TOKEN_RECIPIENT_EMAIL,
+ (Object) mEmail);
+ // ... and more
+ }
+
+ /**
+ * sets the configurable parameters
+ */
+ public void set(String name, String val) {
+ if (name.equalsIgnoreCase(PROP_ENABLED)) {
+ if (val.equalsIgnoreCase("true")) {
+ mEnabled = true;
+ } else {
+ mEnabled = false;
+ }
+ } else if (name.equalsIgnoreCase(PROP_SENDER_EMAIL)) {
+ mSenderEmail = val;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_SUBJECT)) {
+ mSubject_Success = val;
+ mSubject = mSubject_Success;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_TEMPLATE)) {
+ mFormPath = val;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET"));
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java b/pki/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java
new file mode 100644
index 000000000..5a1500587
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java
@@ -0,0 +1,439 @@
+// --- 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.listeners;
+
+
+import java.io.File;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.listeners.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.apps.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import java.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import java.text.DateFormat;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.ca.*;
+
+
+/**
+ * a listener for every completed enrollment request
+ * <p>
+ * Here is a list of available $TOKENs for email notification
+ templates if certificate is successfully issued:
+ * <UL>
+ * <LI>$InstanceID
+ * <LI>$SerialNumber
+ * <LI>$HexSerialNumber
+ * <LI>$HttpHost
+ * <LI>$HttpPort
+ * <LI>$RequestId
+ * <LI>$IssuerDN
+ * <LI>$SubjectDN
+ * <LI>$NotBefore
+ * <LI>$NotAfter
+ * <LI>$SenderEmail
+ * <LI>$RecipientEmail
+ * </UL>
+ * <p>
+ * Here is a list of available $TOKENs for email notification
+ templates if certificate request is revoked:
+ * <UL>
+ * <LI>$RequestId
+ * <LI>$InstanceID
+ * </UL>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertificateRevokedListener implements IRequestListener {
+ protected final static String PROP_CERT_ISSUED_SUBSTORE = "certRevoked";
+ protected static final String PROP_ENABLED = "enabled";
+ protected final static String PROP_NOTIFY_SUBSTORE = "notification";
+
+ protected final static String PROP_SENDER_EMAIL = "senderEmail";
+ protected final static String PROP_EMAIL_SUBJECT = "emailSubject";
+ public final static String PROP_EMAIL_TEMPLATE = "emailTemplate";
+
+ protected final static String REJECT_FILE_NAME = "certRequestRejected";
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private String mSenderEmail = null;
+ private String mSubject = null;
+ private String mSubject_Success = null;
+ private String mFormPath = null;
+ private String mRejectPath = null;
+ private Hashtable mContentParams = new Hashtable();
+
+ private ICertAuthority mSub = null;
+ private IConfigStore mConfig = null;
+ private DateFormat mDateFormat = null;
+ private ICertAuthority mSubsystem = null;
+ private String mHttpHost = null;
+ private String mHttpPort = null;
+ private RequestId mReqId = null;
+
+ public CertificateRevokedListener() {
+ }
+
+ public void init(ISubsystem sub, IConfigStore config)
+ throws EListenersException, EPropertyNotFound, EBaseException {
+ mSubsystem = (ICertAuthority) sub;
+ mConfig = mSubsystem.getConfigStore();
+
+ IConfigStore nc = mConfig.getSubStore(PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(PROP_CERT_ISSUED_SUBSTORE);
+
+ mEnabled = rc.getBoolean(PROP_ENABLED, false);
+
+ mSenderEmail = rc.getString(PROP_SENDER_EMAIL);
+ if (mSenderEmail == null) {
+ throw new EListenersException(CMS.getLogMessage("NO_NOTIFY_SENDER_EMAIL_CONFIG_FOUND"));
+ }
+
+ mFormPath = rc.getString(PROP_EMAIL_TEMPLATE);
+ String mDir = null;
+
+ // figure out the reject email path: same dir as form path,
+ // same ending as form path
+ int ridx = mFormPath.lastIndexOf(File.separator);
+
+ if (ridx == -1) {
+ CMS.debug("CertificateRevokedListener: file separator: " + File.separator
+ +
+ " not found. Use default /");
+ ridx = mFormPath.lastIndexOf("/");
+ mDir = mFormPath.substring(0, ridx + 1);
+ } else {
+ mDir = mFormPath.substring(0, ridx +
+ File.separator.length());
+ }
+ CMS.debug("CertificateRevokedListener: template file directory: " + mDir);
+ mRejectPath = mDir + REJECT_FILE_NAME;
+ if (mFormPath.endsWith(".html"))
+ mRejectPath += ".html";
+ else if (mFormPath.endsWith(".HTML"))
+ mRejectPath += ".HTML";
+ else if (mFormPath.endsWith(".htm"))
+ mRejectPath += ".htm";
+ else if (mFormPath.endsWith(".HTM"))
+ mRejectPath += ".HTM";
+
+ CMS.debug("CertificateRevokedListener: Reject file path: " + mRejectPath);
+
+ mDateFormat = DateFormat.getDateTimeInstance();
+
+ mSubject_Success = rc.getString(PROP_EMAIL_SUBJECT,
+ "Your Certificate Request");
+ mSubject = new String(mSubject_Success);
+
+ // form the cert retrieval URL for the notification
+ mHttpHost = CMS.getEEHost();
+ mHttpPort = CMS.getEESSLPort();
+
+ // register for this event listener
+ mSubsystem.registerRequestListener(this);
+ }
+
+ public void accept(IRequest r) {
+ if (mEnabled != true) return;
+
+ mSubject = mSubject_Success;
+ mReqId = r.getRequestId();
+ // is it revoked?
+ String rs = r.getRequestStatus().toString();
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.REVOCATION_REQUEST) == false)
+ return;
+ if (rs.equals("complete") == false) {
+ CMS.debug("CertificateRevokedListener: Request status: " + rs);
+ //revoked(r);
+ return;
+ }
+
+ // check if request failed.
+ if (r.getExtDataInInteger(IRequest.RESULT) == null)
+ return;
+
+ if ((r.getExtDataInInteger(IRequest.RESULT)).equals(IRequest.RES_ERROR)) {
+ CMS.debug("CertificateRevokedListener: Request errored. " +
+ "No need to email notify for enrollment request id " +
+ mReqId);
+ return;
+ }
+
+ if (requestType.equals(IRequest.REVOCATION_REQUEST)) {
+ CMS.debug("CertificateRevokedListener: accept() revocation request...");
+ // Get the certificate from the request
+ //X509CertImpl issuedCert[] =
+ // (X509CertImpl[])
+ RevokedCertImpl crlentries[] =
+ r.getExtDataInRevokedCertArray(IRequest.CERT_INFO);
+
+ if (crlentries != null) {
+ CMS.debug("CertificateRevokedListener: Sending email notification..");
+
+ // do we have an email to send?
+ String mEmail = null;
+ IEmailResolverKeys keys = CMS.getEmailResolverKeys();
+
+ try {
+ keys.set(IEmailResolverKeys.KEY_REQUEST, r);
+ keys.set(IEmailResolverKeys.KEY_CERT,
+ crlentries[0]);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET_RESOLVER", e.toString()));
+ }
+
+ IEmailResolver er = CMS.getReqCertSANameEmailResolver();
+
+ try {
+ mEmail = er.getEmail(keys);
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_EXCEPTION",
+ e.toString()));
+ }
+
+ // now we can mail
+ if ((mEmail != null) && (!mEmail.equals(""))) {
+ mailIt(mEmail, crlentries);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_NOTIFY_ERROR",
+ crlentries[0].getSerialNumber().toString(), mReqId.toString()));
+ // send failure notification to "sender"
+ mSubject = "Certificate Issued notification undeliverable";
+ mailIt(mSenderEmail, crlentries);
+ }
+ }
+ }
+ }
+
+ private void mailIt(String mEmail, RevokedCertImpl crlentries[]) {
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSenderEmail);
+ mn.setTo(mEmail);
+ mn.setSubject(mSubject);
+
+ /*
+ * get template file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(mFormPath);
+
+ /*
+ * parse and process the template
+ */
+ if (template != null) {
+ if (!template.init()) {
+ return;
+ }
+
+ buildContentParams(crlentries, mEmail);
+ IEmailFormProcessor et = CMS.getEmailFormProcessor();
+ String c = et.getEmailContent(template.toString(), mContentParams);
+
+ if (template.isHTML()) {
+ mn.setContentType("text/html");
+ }
+ mn.setContent(c);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_TEMPLATE_ERROR",
+ crlentries[0].getSerialNumber().toString(), mReqId.toString()));
+
+ mn.setContent("Serial Number = " +
+ crlentries[0].getSerialNumber() +
+ "; Request ID = " + mReqId);
+ }
+
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ }
+
+ private void revoked(IRequest r) {
+ // do we have an email to send?
+ String mEmail = null;
+ IEmailResolverKeys keys = CMS.getEmailResolverKeys();
+
+ try {
+ keys.set(IEmailResolverKeys.KEY_REQUEST, r);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET_RESOLVER", e.toString()));
+ }
+
+ IEmailResolver er = CMS.getReqCertSANameEmailResolver();
+
+ try {
+ mEmail = er.getEmail(keys);
+ } catch (ENotificationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ // now we can mail
+ if ((mEmail != null) && !mEmail.equals("")) {
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSenderEmail);
+ mn.setTo(mEmail);
+ mn.setSubject(mSubject);
+
+ /*
+ * get rejection file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(mRejectPath);
+
+ if (template != null) {
+ if (!template.init()) {
+ return;
+ }
+
+ if (template.isHTML()) {
+ mn.setContentType("text/html");
+ }
+
+ // build some token data
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ mReqId = r.getRequestId();
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ (Object) mReqId.toString());
+ IEmailFormProcessor et = CMS.getEmailFormProcessor();
+ String c = et.getEmailContent(template.toString(), mContentParams);
+
+ mn.setContent(c);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_CERT_ISSUED_REJECTION"));
+ mn.setContent("Your Certificate Request has been revoked. Please contact your administrator for assistance");
+ }
+
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ // already logged, lets audit
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_REJECTION_NOTIFICATION", mReqId.toString()));
+
+ }
+ }
+
+ private void buildContentParams(RevokedCertImpl crlentries[], String mEmail) {
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SERIAL_NUM,
+ (Object) crlentries[0].getSerialNumber().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ (Object) Long.toHexString(crlentries[0].getSerialNumber().longValue()));
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ (Object) mReqId.toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ (Object) mHttpHost);
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_PORT,
+ (Object) mHttpPort);
+
+ try {
+ RevokedCertImpl revCert = (RevokedCertImpl) crlentries[0];
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ICertificateRepository certDB = ca.getCertificateRepository();
+ X509Certificate cert = certDB.getX509Certificate(revCert.getSerialNumber());
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_ISSUER_DN,
+ (Object) cert.getIssuerDN().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ (Object) cert.getSubjectDN().toString());
+ Date date = (Date) crlentries[0].getRevocationDate();
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_REVOCATION_DATE,
+ mDateFormat.format(date));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET_RESOLVER", e.toString()));
+ }
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_SENDER_EMAIL,
+ (Object) mSenderEmail);
+ mContentParams.put(IEmailFormProcessor.TOKEN_RECIPIENT_EMAIL,
+ (Object) mEmail);
+ // ... and more
+ }
+
+ /**
+ * sets the configurable parameters
+ */
+ public void set(String name, String val) {
+ if (name.equalsIgnoreCase(PROP_ENABLED)) {
+ if (val.equalsIgnoreCase("true")) {
+ mEnabled = true;
+ } else {
+ mEnabled = false;
+ }
+ } else if (name.equalsIgnoreCase(PROP_SENDER_EMAIL)) {
+ mSenderEmail = val;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_SUBJECT)) {
+ mSubject_Success = val;
+ mSubject = mSubject_Success;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_TEMPLATE)) {
+ mFormPath = val;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET"));
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java b/pki/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java
new file mode 100644
index 000000000..c678a4b4b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java
@@ -0,0 +1,182 @@
+// --- 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.listeners;
+
+
+import java.io.File;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.listeners.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.listeners.*;
+import com.netscape.certsrv.notification.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.common.*;
+import java.text.DateFormat;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This represnets a listener that removes pin from LDAP directory.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PinRemovalListener implements IRequestListener {
+ protected static final String PROP_ENABLED = "enabled";
+ protected static final String PROP_LDAP = "ldap";
+ protected static final String PROP_BASEDN = "ldap.basedn";
+ protected static final String PROP_PINATTR = "pinAttr";
+
+ protected String mName = null;
+ protected String mImplName = null;
+ protected String mBaseDN = null;
+ protected String mPinAttr = null;
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private Hashtable mContentParams = new Hashtable();
+
+ private ICertAuthority mSub = null;
+ private IConfigStore mConfig = null;
+ private IConfigStore mLdapConfig = null;
+ private RequestId mReqId = null;
+ private ILdapConnFactory mConnFactory = null;
+ private LDAPConnection mRemovePinLdapConnection = null;
+
+ public PinRemovalListener() {
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getImplName() {
+ return mImplName;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void shutdown() {
+ }
+
+ protected String[] configParams = { "a" };
+
+ public String[] getConfigParams()
+ throws EBaseException {
+
+ if (1 == 2) throw new EBaseException("");
+ return configParams;
+ }
+
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException {
+ init(null, null, config);
+ }
+
+ public void init(String name, String ImplName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = ImplName;
+ mConfig = config;
+
+ mLdapConfig = mConfig.getSubStore(PROP_LDAP);
+ mConnFactory = CMS.getLdapBoundConnFactory();
+ mConnFactory.init(mLdapConfig);
+ mRemovePinLdapConnection = mConnFactory.getConn();
+
+ mEnabled = mConfig.getBoolean(PROP_ENABLED, false);
+ mBaseDN = mConfig.getString(PROP_BASEDN, "");
+ mPinAttr = mConfig.getString(PROP_PINATTR, "pin");
+
+ }
+
+ public void accept(IRequest r) {
+ if (mEnabled != true) return;
+
+ mReqId = r.getRequestId();
+
+ String rs = r.getRequestStatus().toString();
+
+ CMS.debug("PinRemovalListener: Request status: " + rs);
+ if (!rs.equals("complete")) {
+ CMS.debug("PinRemovalListener: - request not complete - not removing pin");
+ return;
+ }
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.ENROLLMENT_REQUEST) ||
+ requestType.equals(IRequest.RENEWAL_REQUEST)) {
+
+ String uid = r.getExtDataInString(
+ IRequest.HTTP_PARAMS, "uid");
+
+ if (uid == null) {
+ log(ILogger.LL_INFO, "did not find UID parameter in this request");
+ return;
+ }
+
+ String userdn = null;
+
+ try {
+ LDAPSearchResults res = mRemovePinLdapConnection.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+
+ if (!res.hasMoreElements()) {
+ log(ILogger.LL_SECURITY, "uid " + uid + " does not exist in the ldap " +
+ " server. Could not remove pin");
+ return;
+ }
+
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ userdn = entry.getDN();
+
+ mRemovePinLdapConnection.modify(userdn,
+ new LDAPModification(
+ LDAPModification.DELETE,
+ new LDAPAttribute(mPinAttr)));
+
+ log(ILogger.LL_INFO, "Removed pin for user \"" + userdn + "\"");
+
+ } catch (LDAPException e) {
+ log(ILogger.LL_SECURITY, "could not remove pin for " + userdn);
+ }
+
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "PinRemovalListener: " + msg);
+ }
+
+ public void set(String name, String val) {
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/listeners/RequestInQListener.java b/pki/base/common/src/com/netscape/cms/listeners/RequestInQListener.java
new file mode 100644
index 000000000..3027415be
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/listeners/RequestInQListener.java
@@ -0,0 +1,277 @@
+// --- 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.listeners;
+
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.listeners.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.profile.input.SubjectNameInput;
+import com.netscape.cms.profile.input.SubmitterInfoInput;
+
+import java.io.IOException;
+import java.util.*;
+
+
+/**
+ * a listener for every request gets into the request queue.
+ * <p>
+ * Here is a list of available $TOKENs for email notification templates:
+ * <UL>
+ * <LI>$RequestorEmail
+ * <LI>$CertType
+ * <LI>$RequestType
+ * <LI>$RequestId
+ * <LI>$HttpHost
+ * <LI>$HttpPort
+ * <LI>$SenderEmail
+ * <LI>$RecipientEmail
+ * </UL>
+ *
+ */
+public class RequestInQListener implements IRequestListener {
+ protected static final String PROP_ENABLED = "enabled";
+ protected final static String PROP_SENDER_EMAIL = "senderEmail";
+ protected final static String PROP_RECVR_EMAIL = "recipientEmail";
+ public final static String PROP_EMAIL_TEMPLATE = "emailTemplate";
+ protected static final String PROP_EMAIL_SUBJECT = "emailSubject";
+
+ protected final static String PROP_NOTIFY_SUBSTORE = "notification";
+ protected final static String PROP_REQ_IN_Q_SUBSTORE = "requestInQ";
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private String mSenderEmail = null;
+ private String mRecipientEmail = null;
+ private String mEmailSubject = null;
+ private String mFormPath = null;
+ private IConfigStore mConfig = null;
+ private Hashtable mContentParams = new Hashtable();
+ private String mId = "RequestInQListener";
+ private ICertAuthority mSubsystem = null;
+ private String mHttpHost = null;
+ private String mAgentPort = null;
+
+ /**
+ * Constructor
+ */
+ public RequestInQListener() {
+ }
+
+ /**
+ * initializes the listener from the configuration
+ */
+ public void init(ISubsystem sub, IConfigStore config)
+ throws EListenersException, EPropertyNotFound, EBaseException {
+
+ mSubsystem = (ICertAuthority) sub;
+ mConfig = mSubsystem.getConfigStore();
+
+ IConfigStore nc = mConfig.getSubStore(PROP_NOTIFY_SUBSTORE);
+ IConfigStore rq = nc.getSubStore(PROP_REQ_IN_Q_SUBSTORE);
+
+ mEnabled = rq.getBoolean(PROP_ENABLED, false);
+
+ mSenderEmail = rq.getString(PROP_SENDER_EMAIL);
+ if (mSenderEmail == null) {
+ throw new EListenersException(CMS.getLogMessage("NO_NOTIFY_SENDER_EMAIL_CONFIG_FOUND"));
+ }
+ mRecipientEmail = rq.getString(PROP_RECVR_EMAIL);
+ if (mRecipientEmail == null) {
+ throw new EListenersException(CMS.getLogMessage("NO_NOTIFY_RECVR_EMAIL_CONFIG_FOUND"));
+ }
+
+ mEmailSubject = rq.getString(PROP_EMAIL_SUBJECT);
+ if (mEmailSubject == null) {
+ mEmailSubject = "Request in Queue";
+ }
+
+ mFormPath = rq.getString(PROP_EMAIL_TEMPLATE);
+
+ // make available http host and port for forming url in templates
+ mHttpHost = CMS.getAgentHost();
+ mAgentPort = CMS.getAgentPort();
+ if (mAgentPort == null)
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_REQUEST_PORT_NOT_FOUND"));
+ else
+ CMS.debug("RequestInQuListener: agentport = " + mAgentPort);
+
+ // register for this event listener
+ mSubsystem.registerPendingListener(this);
+ }
+
+ /**
+ * carries out the operation when the listener is triggered.
+ * @param r IRequest structure holding the request information
+ * @see com.netscape.certsrv.request.IRequest
+ */
+ public void accept(IRequest r) {
+
+ if (mEnabled != true) return;
+
+ // regardless of type of request...notify for everything
+ // no need for email resolver here...
+ IMailNotification mn = CMS.getMailNotification();
+
+ mn.setFrom(mSenderEmail);
+ mn.setTo(mRecipientEmail);
+ mn.setSubject(mEmailSubject + " (request id: " +
+ r.getRequestId() + ")");
+
+ /*
+ * get form file from disk
+ */
+ IEmailTemplate template = CMS.getEmailTemplate(mFormPath);
+
+ /*
+ * parse and process the template
+ */
+ if (template != null) {
+ if (!template.init()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_TEMPLATE_NOT_INIT"));
+ return;
+ }
+
+ buildContentParams(r);
+ IEmailFormProcessor et = CMS.getEmailFormProcessor();
+ String c = et.getEmailContent(template.toString(), mContentParams);
+
+ if (template.isHTML()) {
+ mn.setContentType("text/html");
+ }
+ mn.setContent(c);
+ } else {
+ // log and mail
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_TEMPLATE_NOT_GET"));
+ mn.setContent("Template not retrievable for Request in Queue notification");
+ }
+
+ try {
+ mn.sendNotification();
+ } catch (ENotificationException e) {
+ // already logged, lets audit
+ mLogger.log(ILogger.EV_AUDIT, null,
+ ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_SEND_FAILED", e.toString()));
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LISTENERS_SEND_FAILED", e.toString()));
+ }
+ }
+
+ private void buildContentParams(IRequest r) {
+ mContentParams.clear();
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ Object val = null;
+
+ String profileId = r.getExtDataInString("profileId");
+
+ if (profileId == null) {
+ val = r.getExtDataInString(IRequest.HTTP_PARAMS, "csrRequestorEmail");
+ } else {
+ // use the submitter info if available, otherwise, use the
+ // subject name input email
+ val = r.getExtDataInString(SubmitterInfoInput.EMAIL);
+
+ if ((val == null) || (((String) val).compareTo("") == 0)) {
+ val = r.getExtDataInString(SubjectNameInput.VAL_EMAIL);
+ }
+ }
+ if (val != null)
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUESTOR_EMAIL,
+ val);
+
+ if (profileId == null) {
+ val = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+ } else {
+ val = profileId;
+ }
+ if (val != null) {
+ mContentParams.put(IEmailFormProcessor.TOKEN_CERT_TYPE,
+ val);
+ }
+
+ RequestId reqId = r.getRequestId();
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ (Object) reqId.toString());
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID, mId);
+
+ val = r.getRequestType();
+ if (val != null)
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_TYPE,
+ val);
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ (Object) mHttpHost);
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_PORT,
+ (Object) mAgentPort);
+
+ mContentParams.put(IEmailFormProcessor.TOKEN_SENDER_EMAIL,
+ (Object) mSenderEmail);
+ mContentParams.put(IEmailFormProcessor.TOKEN_RECIPIENT_EMAIL,
+ (Object) mRecipientEmail);
+ }
+
+ /**
+ * sets the configurable parameters
+ * @param name a String represents the name of the configuration parameter to be set
+ * @param val a String containing the value to be set for name
+ */
+ public void set(String name, String val) {
+ if (name.equalsIgnoreCase(PROP_ENABLED)) {
+ if (val.equalsIgnoreCase("true")) {
+ mEnabled = true;
+ } else {
+ mEnabled = false;
+ }
+ } else if (name.equalsIgnoreCase(PROP_SENDER_EMAIL)) {
+ mSenderEmail = val;
+ } else if (name.equalsIgnoreCase(PROP_RECVR_EMAIL)) {
+ mRecipientEmail = val;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_SUBJECT)) {
+ mEmailSubject = val;
+ } else if (name.equalsIgnoreCase(PROP_EMAIL_TEMPLATE)) {
+ mFormPath = val;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LISTENERS_CERT_ISSUED_SET"));
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/logging/LogEntry.java b/pki/base/common/src/com/netscape/cms/logging/LogEntry.java
new file mode 100644
index 000000000..cc64ea6f6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/logging/LogEntry.java
@@ -0,0 +1,136 @@
+// --- 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.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A log entry of LogFile
+ *
+ * @version $Revision$, $Date$
+ */
+public class LogEntry {
+ private String mEntry;
+ private String mLevel;
+ private String mSource;
+ private String mDetail;
+ private String mDate;
+ private String mTime;
+ private Vector mRow;
+
+ private final String DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss z";
+
+ /**
+ * Constructor for a LogEntry.
+ *
+ */
+ public LogEntry(String entry) throws ParseException {
+ mEntry = entry;
+ mRow = parse();
+ }
+
+ /**
+ * parse a log entry
+ *
+ * return a vector of the segments of the entry
+ */
+
+ public Vector parse() throws ParseException {
+ int x = mEntry.indexOf("[");
+
+ if (x == -1)
+ throw new ParseException(mEntry, 0);
+ String temp = mEntry.substring(x + 1);
+
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(mEntry, 0);
+
+ String dateStr = temp.substring(0, x);
+ SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
+ Date date = format.parse(dateStr);
+
+ mDate = DateFormat.getDateInstance().format(date);
+ mTime = DateFormat.getTimeInstance().format(date);
+
+ temp = temp.substring(x + 2);
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(mEntry, 0);
+ mSource = temp.substring(1, x);
+
+ temp = temp.substring(x + 2);
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(mEntry, 0);
+ mLevel = temp.substring(1, x);
+
+ mDetail = temp.substring(x + 2);
+
+ Vector row = new Vector();
+
+ row.addElement(mSource);
+ row.addElement(mLevel);
+ row.addElement(mDate);
+ row.addElement(mTime);
+ row.addElement(mDetail);
+
+ //System.out.println(mSource +"," + mLevel +","+ mDate+","+mTime+","+mDetail);
+ return row;
+
+ }
+
+ public String getSource() {
+ return mSource;
+ }
+
+ public String getLevel() {
+ return mLevel;
+ }
+
+ public String getDetail() {
+ return mDetail;
+ }
+
+ public String getDate() {
+ return mDate;
+ }
+
+ public String getTime() {
+ return mTime;
+ }
+
+ public Vector getRow() {
+ return mRow;
+ }
+
+ public String getEntry() {
+ return mEntry;
+ }
+
+ public void appendDetail(String msg) {
+ mDetail = mDetail + "\n" + msg;
+ mEntry = mEntry + "\n" + msg;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/logging/LogFile.java b/pki/base/common/src/com/netscape/cms/logging/LogFile.java
new file mode 100644
index 000000000..8c9a38410
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/logging/LogFile.java
@@ -0,0 +1,1492 @@
+// --- 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.logging;
+
+
+import java.lang.*;
+import java.io.*;
+import java.io.File.*;
+import java.util.*;
+import java.text.*;
+import java.security.*;
+import java.security.Security;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.util.*;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.util.Base64OutputStream;
+import java.io.CharConversionException;
+
+/**
+ * A log event listener which write logs to log files
+ *
+ * @version $Revision$, $Date$
+ **/
+public class LogFile implements ILogEventListener, IExtendedPluginInfo {
+ public static final String PROP_TYPE = "type";
+ public static final String PROP_REGISTER = "register";
+ public static final String PROP_ON = "enable";
+ public static final String PROP_TRACE = "trace";
+ public static final String PROP_SIGNED_AUDIT_LOG_SIGNING = "logSigning";
+ public static final String PROP_SIGNED_AUDIT_CERT_NICKNAME =
+ "signedAuditCertNickname";
+ public static final String PROP_SIGNED_AUDIT_EVENTS = "events";
+ public static final String PROP_LEVEL = "level";
+ static final String PROP_FILE_NAME = "fileName";
+ static final String PROP_LAST_HASH_FILE_NAME = "lastHashFileName";
+ static final String PROP_BUFFER_SIZE = "bufferSize";
+ static final String PROP_FLUSH_INTERVAL = "flushInterval";
+
+ private final static String LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP =
+ "LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP_2";
+ private final static String LOGGING_SIGNED_AUDIT_SIGNING =
+ "LOGGING_SIGNED_AUDIT_SIGNING_3";
+ private final static String LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN =
+ "LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN_2";
+ private final static String LOG_SIGNED_AUDIT_EXCEPTION =
+ "LOG_SIGNED_AUDIT_EXCEPTION_1";
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ protected IConfigStore mConfig = null;
+
+ /**
+ * The date string used in the log file name
+ */
+ static final String DATE_PATTERN = "yyyyMMddHHmmss";
+
+ //It may be interesting to make this flexable someday....
+ protected SimpleDateFormat mLogFileDateFormat = new SimpleDateFormat(DATE_PATTERN);
+
+ /**
+ * The default output stream buffer size in bytes
+ */
+ static final int BUFFER_SIZE = 512;
+
+ /**
+ * The default output flush interval in seconds
+ */
+ static final int FLUSH_INTERVAL = 5;
+
+ /**
+ * The log file
+ */
+ protected File mFile = null;
+
+ /**
+ * The log file name
+ */
+ protected String mFileName = null;
+
+ /**
+ * The log file output stream
+ */
+ protected BufferedWriter mLogWriter = null;
+
+ /**
+ * The log date entry format pattern
+ */
+ protected String mDatePattern = "dd/MMM/yyyy:HH:mm:ss z";
+
+ /**
+ * The log date entry format
+ */
+ protected SimpleDateFormat mLogDateFormat = new SimpleDateFormat(mDatePattern);
+
+ /**
+ * The date object used for log entries
+ */
+ protected Date mDate = new Date();
+
+ /**
+ * The number of bytes written to the current log file
+ */
+ protected int mBytesWritten = 0;
+
+ /**
+ * The output buffer size in bytes
+ */
+ protected int mBufferSize = BUFFER_SIZE;
+
+ /**
+ * The output buffer flush interval
+ */
+ protected int mFlushInterval = FLUSH_INTERVAL;
+
+ /**
+ * The number of unflushed bytes
+ */
+ protected int mBytesUnflushed = 0;
+
+ /**
+ * The output buffer flush interval thread
+ */
+ private Thread mFlushThread = null;
+
+ /**
+ * The current pid for the log entries
+ */
+ protected int mPid = CMS.getpid();
+
+ /**
+ * The selected log event types
+ */
+ protected String mSelectedEventsList = null;
+ protected Vector mSelectedEvents = null;
+
+ /**
+ * The eventType that this log is triggered
+ */
+ protected String mType = null;
+
+ /**
+ * The log is turned on/off
+ */
+ protected boolean mOn = false;
+
+ /**
+ * Should this log listener self-register or not
+ */
+ protected boolean mRegister = false;
+
+ protected boolean mTrace = false;
+
+ /**
+ * Log signing is on/off
+ */
+ protected boolean mLogSigning = false;
+
+ /**
+ * Nickname of certificate to use to sign log.
+ */
+ private String mSAuditCertNickName = "";
+
+ /**
+ * The provider used by the KeyGenerator and Mac
+ */
+ static final String CRYPTO_PROVIDER = "Mozilla-JSS";
+
+ /**
+ * The log level threshold
+ * Only logs with level greater or equal than this value will be written
+ */
+ protected long mLevel = 1;
+
+ /**
+ * Constructor for a LogFile.
+ *
+ */
+ public LogFile() {
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ try {
+ mOn = config.getBoolean(PROP_ON, true);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_ON));
+ }
+
+ try {
+ mLogSigning = config.getBoolean(PROP_SIGNED_AUDIT_LOG_SIGNING,
+ false);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_SIGNED_AUDIT_LOG_SIGNING));
+ }
+
+ if (mOn && mLogSigning) {
+ try {
+ mSAuditCertNickName = config.getString(
+ PROP_SIGNED_AUDIT_CERT_NICKNAME);
+ CMS.debug("LogFile: init(): audit log signing enabled. signedAuditCertNickname="+ mSAuditCertNickName);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "."
+ + PROP_SIGNED_AUDIT_CERT_NICKNAME));
+ }
+ if (mSAuditCertNickName == null ||
+ mSAuditCertNickName.trim().equals("")) {
+ throw new ELogException(CMS.getUserMessage(
+ "CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "."
+ + PROP_SIGNED_AUDIT_CERT_NICKNAME));
+ }
+ }
+
+ // selective logging
+ mSelectedEventsList = null;
+ try {
+ mSelectedEventsList = config.getString(PROP_SIGNED_AUDIT_EVENTS);
+ } catch (EBaseException e) {
+ // when not specified, ALL are selected by default
+ }
+ mSelectedEvents = string2Vector(mSelectedEventsList);
+
+ try {
+ init(config);
+ } catch (IOException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_UNEXPECTED_EXCEPTION", e.toString()));
+ }
+ }
+
+ /**
+ * turns a comma-separated String into a Vector
+ */
+ protected Vector string2Vector(String theString) {
+ Vector theVector = new Vector();
+ if (theString == null) {
+ return theVector;
+ }
+
+ StringTokenizer tokens = new StringTokenizer(theString,
+ ",");
+ while (tokens.hasMoreTokens()) {
+ String eventId = tokens.nextToken().trim();
+
+ theVector.addElement(eventId);
+ CMS.debug("LogFile: log event type selected: "+eventId);
+ }
+ return theVector;
+ }
+
+ /**
+ * add the event to the selected events list
+ * @param event to be selected
+ */
+ public void selectEvent(String event) {
+ if (!mSelectedEvents.contains(event))
+ mSelectedEvents.addElement(event);
+ }
+
+ /**
+ * remove the event from the selected events list
+ * @param event to be de-selected
+ */
+ public void deselectEvent(String event) {
+ if (mSelectedEvents.contains(event))
+ mSelectedEvents.removeElement(event);
+ }
+
+ /**
+ * replace the selected events list
+ * @param events comma-separated event list
+ */
+ public void replaceEvents(String events) {
+ Vector v = string2Vector(events);
+ mSelectedEvents.removeAllElements();
+ mSelectedEvents = v;
+ }
+
+ public static String base64Encode(byte[] bytes) throws IOException {
+ // All this streaming is lame, but Base64OutputStream needs a
+ // PrintStream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(new
+ PrintStream(new
+ FilterOutputStream(output)
+ )
+ );
+
+ b64.write(bytes);
+ b64.flush();
+
+ // This is internationally safe because Base64 chars are
+ // contained within 8859_1
+ return output.toString("8859_1");
+ }
+
+ private static boolean mInSignedAuditLogFailureMode = false;
+
+ private static synchronized void shutdownCMS() {
+ if( mInSignedAuditLogFailureMode == false ) {
+
+ // Set signed audit log failure mode true
+ // No, this isn't a race condition, because the method is
+ // synchronized. We just want to avoid an infinite loop.
+ mInSignedAuditLogFailureMode = true;
+
+ // Block all new incoming requests
+ if( CMS.areRequestsDisabled() == false ) {
+ // XXX is this a race condition?
+ CMS.disableRequests();
+ }
+
+ // Terminate all requests in process
+ CMS.terminateRequests();
+
+ // Call graceful shutdown of the CMS server
+ // Call force shutdown to get added functionality of
+ // making sure to kill the web server.
+
+ CMS.forceShutdown();
+ }
+ }
+
+ /**
+ * Initialize and open the log using the parameters from a config store
+ *
+ * @param config The property config store to find values in
+ */
+ public void init(IConfigStore config) throws IOException,
+ EBaseException {
+ String fileName = null;
+ String defaultFileName = null;
+ String signedAuditDefaultFileName = "";
+
+ mConfig = config;
+
+ try {
+ mTrace = config.getBoolean(PROP_TRACE, false);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_TRACE));
+ }
+
+ try {
+ mType = config.getString(PROP_TYPE, "system");
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_TYPE));
+ }
+
+ try {
+ mRegister = config.getBoolean(PROP_REGISTER, true);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_REGISTER));
+ }
+
+ if (mOn) {
+ if (mRegister) {
+ CMS.getLogger().getLogQueue().addLogEventListener(this);
+ }
+ } else {
+ // shutdown the listener, remove the listener
+ if (mRegister) {
+ CMS.getLogger().getLogQueue().removeLogEventListener(this);
+ shutdown();
+ }
+ }
+
+ try {
+ mLevel = config.getInteger(PROP_LEVEL, 3);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_LEVEL));
+ }
+
+ try {
+ // retrieve the subsystem
+ String subsystem = "";
+
+ ISubsystem caSubsystem = CMS.getSubsystem( "ca" );
+ if( caSubsystem != null ) {
+ subsystem = "ca";
+ }
+
+ ISubsystem raSubsystem = CMS.getSubsystem( "ra" );
+ if( raSubsystem != null ) {
+ subsystem = "ra";
+ }
+
+ ISubsystem kraSubsystem = CMS.getSubsystem( "kra" );
+ if( kraSubsystem != null ) {
+ subsystem = "kra";
+ }
+
+ ISubsystem ocspSubsystem = CMS.getSubsystem( "ocsp" );
+ if( ocspSubsystem != null ) {
+ subsystem = "ocsp";
+ }
+
+ // retrieve the instance name
+ String instIDPath = CMS.getInstanceDir();
+ int index = instIDPath.lastIndexOf( "/" );
+ String instID = instIDPath.substring( index + 1 );
+
+ // build the default signedAudit file name
+ signedAuditDefaultFileName = subsystem + "_"
+ + instID + "_" + "audit";
+
+ } catch( Exception e2 ) {
+ throw new ELogException(
+ CMS.getUserMessage( "CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." +
+ PROP_FILE_NAME ) );
+ }
+
+ // the default value is determined by the eventType.
+ if (mType.equals(ILogger.PROP_SIGNED_AUDIT)) {
+ defaultFileName = "logs/signedAudit/" + signedAuditDefaultFileName;
+ }else if (mType.equals(ILogger.PROP_SYSTEM)) {
+ defaultFileName = "logs/system";
+ }else if (mType.equals(ILogger.PROP_AUDIT)) {
+ defaultFileName = "logs/transactions";
+ }else {
+ //wont get here
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_INVALID_LOG_TYPE",
+ config.getName()));
+ }
+
+ try {
+ fileName = config.getString(PROP_FILE_NAME, defaultFileName);
+ } catch (EBaseException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ config.getName() + "." + PROP_FILE_NAME));
+ }
+
+ if (mOn) {
+ init(fileName, config.getInteger(PROP_BUFFER_SIZE, BUFFER_SIZE),
+ config.getInteger(PROP_FLUSH_INTERVAL, FLUSH_INTERVAL));
+ }
+ }
+
+ /**
+ * Initialize and open the log
+ *
+ * @param bufferSize The buffer size for the output stream in bytes
+ * @param flushInterval The interval in seconds to flush the log
+ */
+ public void init(String fileName, int bufferSize, int flushInterval) throws IOException,ELogException {
+
+ if (fileName == null)
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_INVALID_FILE_NAME", "null"));
+
+ //If we want to reuse the old log files
+ //mFileName = fileName + "." + mLogFileDateFormat.format(mDate);
+ mFileName = fileName;
+ if( !Utils.isNT() ) {
+ // Always insure that a physical file exists!
+ Utils.exec( "touch " + mFileName );
+ Utils.exec( "chmod 00640 " + mFileName );
+ }
+ mFile = new File(mFileName);
+ mBufferSize = bufferSize;
+ setFlushInterval(flushInterval);
+ open();
+ }
+
+ private PrivateKey mSigningKey = null;
+ private Signature mSignature = null;
+
+ private void setupSigning() throws EBaseException {
+ try {
+
+ Provider[] providers = java.security.Security.getProviders();
+ int ps = providers.length;
+ for (int i = 0; i<ps; i++) {
+ CMS.debug("LogFile: provider "+i+"= "+providers[i].getName());
+ }
+
+ CryptoManager cm = CryptoManager.getInstance();
+
+ // find CertServer's private key
+ X509Certificate cert = cm.findCertByNickname( mSAuditCertNickName );
+ if (cert != null) {
+ CMS.debug("LogFile: setupSignig(): found cert:"+mSAuditCertNickName);
+ } else {
+ CMS.debug("LogFile: setupSignig(): cert not found:"+mSAuditCertNickName);
+ }
+ mSigningKey = cm.findPrivKeyByCert(cert);
+
+ String sigAlgorithm;
+ if( mSigningKey instanceof RSAPrivateKey ) {
+ sigAlgorithm = "SHA-256/RSA";
+ } else if( mSigningKey instanceof DSAPrivateKey ) {
+ sigAlgorithm = "SHA-256/DSA";
+ } else {
+ throw new NoSuchAlgorithmException("Unknown private key type");
+ }
+
+ CryptoToken savedToken = cm.getThreadToken();
+ try {
+ CryptoToken keyToken =
+ ((org.mozilla.jss.pkcs11.PK11PrivKey)mSigningKey)
+ .getOwningToken();
+ cm.setThreadToken(keyToken);
+ mSignature = java.security.Signature.getInstance(sigAlgorithm,
+ CRYPTO_PROVIDER);
+ } finally {
+ cm.setThreadToken(savedToken);
+ }
+
+ mSignature.initSign(mSigningKey);
+
+ // get the last signature from the currently-opened file
+ String entry = getLastSignature(mFile);
+ if( entry != null ) {
+ mSignature.update(entry.getBytes("UTF-8"));
+ mSignature.update(LINE_SEP_BYTE);
+ }
+
+ // Always start off with a signature. That way, even if there
+ // were problems with the log file we inherited, we will
+ // get a fresh start with this instance.
+ pushSignature();
+
+ } catch (CryptoManager.NotInitializedException nie) {
+ setupSigningFailure("BASE_CRYPTOMANAGER_UNINITIALIZED", nie);
+ } catch (ObjectNotFoundException onfe) {
+ setupSigningFailure("LOG_SIGNING_CERT_NOT_FOUND", onfe);
+ } catch (TokenException te) {
+ setupSigningFailure("BASE_TOKEN_ERROR_0", te);
+ } catch (NoSuchAlgorithmException nsae) {
+ setupSigningFailure("LOG_NO_SUCH_ALGORITHM_0", nsae);
+ } catch (NoSuchProviderException nspe) {
+ setupSigningFailure("BASE_PROVIDER_NOT_SUPPORTED", nspe);
+ } catch (InvalidKeyException ike) {
+ setupSigningFailure("BASE_INVALID_KEY", ike);
+ } catch (SignatureException se) {
+ setupSigningFailure("LOG_SIGNING_OP_FAILED", se);
+ } catch (UnsupportedEncodingException uee) {
+ setupSigningFailure("LOG_UNEXPECTED_EXCEPTION", uee);
+ } catch (IOException ioe) {
+ setupSigningFailure("LOG_UNEXPECTED_EXCEPTION", ioe);
+ } catch (Exception e) {
+ setupSigningFailure("LOG_UNEXPECTED_EXCEPTION", e);
+ }
+ }
+
+ private static void setupSigningFailure(String logMessageCode, Exception e)
+ throws EBaseException
+ {
+ try {
+ ConsoleError.send( new SystemEvent(
+ CMS.getLogMessage(logMessageCode)));
+ } catch(Exception e2) {
+ // don't allow an exception while printing to the console
+ // prevent us from running the rest of this function.
+ e2.printStackTrace();
+ }
+ e.printStackTrace();
+ shutdownCMS();
+ throw new EBaseException(e.toString());
+ }
+
+ /**
+ * Startup the instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP used at audit
+ * function startup
+ * </ul>
+ * @exception EBaseException if an internal error occurred
+ */
+ public void startup() throws EBaseException {
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ CMS.debug("LogFile: entering LogFile.startup()");
+ if( mOn && mLogSigning ) {
+ try {
+ setupSigning();
+ audit( CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS) );
+ } catch(EBaseException e) {
+ audit( CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUDIT_LOG_STARTUP,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE) );
+ throw e;
+ }
+ }
+
+ }
+
+
+ /**
+ * Retrieves the eventType this log is triggered.
+ */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Retrieves the log on/off.
+ */
+ public String getOn() {
+ String logStatus = null;
+ return logStatus.valueOf( mOn );
+ }
+
+ /**
+ * Retrieves the log level threshold.
+ */
+ public long getLevel() {
+ return mLevel;
+ }
+
+ /**
+ * Retrieves the base log file name.
+ */
+ public String getName() {
+ return mFileName;
+ }
+
+ private boolean firstOpen = true;
+
+ /**
+ * Record that the signed audit log has been signed
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_SIGNING used when a signature on the
+ * audit log is generated (same as "flush" time)
+ * </ul>
+ * @exception IOException for input/output problems
+ * @exception ELogException when plugin implementation fails
+ * @exception SignatureException when signing fails
+ * @exception InvalidKeyException when an invalid key is utilized
+ */
+ private void pushSignature() throws IOException, ELogException,
+ SignatureException, InvalidKeyException
+ {
+ byte[] sigBytes = null;
+
+ if( mSignature == null ) {
+ return;
+ }
+
+ sigBytes = mSignature.sign();
+ mSignature.initSign(mSigningKey);
+
+ Object o[] = new Object[1];
+ o[0] = null;
+
+ // cook up a signed audit log message to record mac
+ // so as to avoid infinite recursiveness of calling
+ // the log() method
+ String auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SIGNING,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS,
+ base64Encode( sigBytes ) );
+
+ if( mSignedAuditLogger == null ) {
+ return;
+ }
+
+ ILogEvent ev = mSignedAuditLogger.create(
+ ILogger.EV_SIGNED_AUDIT,
+ ( Properties ) null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ auditMessage,
+ o,
+ ILogger.L_SINGLELINE );
+
+ String logMesg = logEvt2String(ev);
+ doLog(logMesg, true);
+ }
+
+ private static String getLastSignature(File f) throws IOException {
+ BufferedReader r = new BufferedReader( new FileReader(f) );
+ String lastSig = null;
+ String curLine = null;
+ while( (curLine = r.readLine()) != null ) {
+ if( curLine.indexOf("AUDIT_LOG_SIGNING") != -1 ) {
+ lastSig = curLine;
+ }
+ }
+ r.close();
+ return lastSig;
+ }
+
+ /**
+ * Open the log file. This creates the buffered FileWriter
+ *
+ */
+ protected synchronized void open() throws IOException {
+ RandomAccessFile out;
+
+ try {
+ out = new RandomAccessFile(mFile, "rw");
+ out.seek(out.length());
+ //XXX int or long?
+ mBytesWritten = (int) out.length();
+ if( !Utils.isNT() ) {
+ try {
+ Utils.exec( "chmod 00640 " + mFile.getCanonicalPath() );
+ } catch( IOException e ) {
+ CMS.debug( "Unable to change file permissions on "
+ + mFile.toString() );
+ }
+ }
+ mLogWriter = new BufferedWriter(
+ new FileWriter(out.getFD()), mBufferSize);
+
+ // The first time we open, mSignature will not have been
+ // initialized yet. That's ok, we will push our first signature
+ // in setupSigning().
+ if( mLogSigning && (mSignature != null)) {
+ try {
+ pushSignature();
+ } catch (ELogException le) {
+ ConsoleError.send(
+ new SystemEvent(CMS.getUserMessage("CMS_LOG_ILLEGALARGUMENT",
+ mFileName)));
+ }
+ }
+ } catch (IllegalArgumentException iae) {
+ ConsoleError.send(
+ new SystemEvent(CMS.getUserMessage("CMS_LOG_ILLEGALARGUMENT",
+ mFileName)));
+ } catch(GeneralSecurityException gse) {
+ // error with signed audit log, shutdown CMS
+ gse.printStackTrace();
+ shutdownCMS();
+ }
+
+ mBytesUnflushed = 0;
+ }
+
+ /**
+ * Flush the log file. Also update the MAC for hash protected logs
+ *
+ */
+ public synchronized void flush() {
+ try {
+ if( mLogSigning ) {
+ try {
+ pushSignature();
+ } catch (ELogException le) {
+ ConsoleError.send(new SystemEvent(CMS.getUserMessage("CMS_LOG_FLUSH_LOG_FAILED", mFileName, le.toString())));
+ }
+ }
+
+ if (mLogWriter != null) {
+ mLogWriter.flush();
+ }
+ } catch (IOException e) {
+ ConsoleError.send(new SystemEvent(CMS.getUserMessage("CMS_LOG_FLUSH_LOG_FAILED", mFileName, e.toString())));
+ } catch(GeneralSecurityException gse) {
+ // error with signed audit log, shutdown CMS
+ gse.printStackTrace();
+ shutdownCMS();
+ }
+
+ mBytesUnflushed = 0;
+ }
+
+ /**
+ * Close the log file
+ *
+ */
+ protected synchronized void close() {
+ try {
+ flush();
+ if (mLogWriter != null) {
+ mLogWriter.close();
+ }
+ } catch (IOException e) {
+ ConsoleError.send(new SystemEvent(CMS.getUserMessage("CMS_LOG_CLOSE_FAILED", mFileName, e.toString())));
+ }
+ mLogWriter = null;
+ }
+
+ /**
+ * Shutdown this log file.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN used at audit
+ * function shutdown
+ * </ul>
+ */
+ public synchronized void shutdown() {
+ String auditMessage = null;
+
+ CMS.debug("LogFile:In log shutdown");
+
+ setFlushInterval(0);
+
+ // log signed audit shutdown success
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUDIT_LOG_SHUTDOWN,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS );
+
+ audit( auditMessage );
+
+ close();
+ }
+
+ /**
+ * Set the flush interval
+ * <P>
+ * @param flushInterval The amount of time in seconds until the log
+ * is flush. A value of 0 will disable autoflush. This will also set
+ * the update period for hash protected logs.
+ **/
+ public synchronized void setFlushInterval(int flushInterval) {
+ mFlushInterval = flushInterval * 1000;
+
+ if ((mFlushThread == null) && (mFlushInterval > 0)) {
+ mFlushThread = new FlushThread();
+ mFlushThread.setDaemon(true);
+ mFlushThread.start();
+ }
+
+ this.notify();
+ }
+
+ /**
+ * Log flush thread. Sleep for the flush interval and flush the
+ * log. Changing flush interval to 0 will cause this thread to exit.
+ */
+ final class FlushThread extends Thread {
+
+ /**
+ * Flush thread constructor including thread name
+ */
+ public FlushThread() {
+ super();
+ super.setName(mFileName + ".flush-" + (Thread.activeCount() + 1));
+ }
+
+ public void run() {
+ while (mFlushInterval > 0) {
+ // Sleep for the interval and then flush the log
+ synchronized (LogFile.this) {
+ try {
+ LogFile.this.wait(mFlushInterval);
+ } catch (InterruptedException e) {
+ // This shouldn't happen very often
+ ConsoleError.send(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_THREAD_INTERRUPT", "flush")));
+ }
+ }
+
+ if (mFlushInterval == 0) {
+ break;
+ }
+
+ if (mBytesUnflushed > 0) {
+ flush();
+ }
+ }
+ mFlushThread = null;
+ }
+ }
+
+ /**
+ * Synchronized method to write a string to the log file. All I18N
+ * should take place before this call.
+ *
+ * @param entry The log entry string
+ */
+ protected synchronized void log(String entry) throws ELogException {
+ doLog(entry, false);
+ }
+
+ // Standard line separator byte. We always sign this line separator,
+ // regardless of what we actually write to the file, so that signature
+ // verification is platform-independent.
+ private static final byte LINE_SEP_BYTE = 0x0a;
+
+ /**
+ * This method actually does the logging, and is not overridden
+ * by subclasses, so you can call it and know that it will do exactly
+ * what you see below.
+ */
+ private synchronized void doLog(String entry, boolean noFlush)
+ throws ELogException {
+ if (mLogWriter == null) {
+ String[] params = { mFileName, entry };
+
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_LOGFILE_CLOSED", params));
+ } else {
+ try {
+ mLogWriter.write(entry, 0/*offset*/, entry.length());
+
+ if (mLogSigning==true) {
+ if(mSignature != null) {
+ // include newline for calculating MAC
+ mSignature.update(entry.getBytes("UTF-8"));
+ } else {
+ CMS.debug("LogFile: mSignature is not yet ready... null in log()");
+ }
+ }
+ if (mTrace) {
+ CharArrayWriter cw = new CharArrayWriter(200);
+ PrintWriter pw = new PrintWriter(cw);
+ Exception e = new Exception();
+ e.printStackTrace(pw);
+ char[] c = cw.toCharArray();
+ cw.close();
+ pw.close();
+
+ CharArrayReader cr = new CharArrayReader(c);
+ LineNumberReader lr = new LineNumberReader(cr);
+
+ String text = null;
+ String method = null;
+ String fileAndLine = null;
+ if (lr.ready()) {
+ text = lr.readLine();
+ do {
+ text = lr.readLine();
+ } while (text.indexOf("logging") != -1);
+ int p = text.indexOf("(");
+ fileAndLine = text.substring(p);
+
+ String classandmethod = text.substring(0, p);
+ int q = classandmethod.lastIndexOf(".");
+ method = classandmethod.substring(q + 1);
+ mLogWriter.write(fileAndLine, 0/*offset*/, fileAndLine.length());
+ mLogWriter.write(" ", 0/*offset*/, " ".length());
+ mLogWriter.write(method, 0/*offset*/, method.length());
+ }
+ }
+ mLogWriter.newLine();
+
+ if (mLogSigning==true){
+ if(mSignature != null) {
+ mSignature.update(LINE_SEP_BYTE);
+ } else {
+ CMS.debug("LogFile: mSignature is null in log() 2");
+ }
+ }
+ } catch (IOException e) {
+ ConsoleError.send(new SystemEvent(CMS.getUserMessage("CMS_LOG_WRITE_FAILED", mFileName, entry, e.toString())));
+ } catch (IllegalStateException e) {
+ CMS.debug("LogFile: exception thrown in log(): "+e.toString());
+ ConsoleError.send(new SignedAuditEvent(CMS.getLogMessage(LOG_SIGNED_AUDIT_EXCEPTION,e.toString())));
+ } catch( GeneralSecurityException gse ) {
+ // DJN: handle error
+ CMS.debug("LogFile: exception thrown in log(): "
+ + gse.toString());
+ gse.printStackTrace();
+ ConsoleError.send(new SignedAuditEvent(CMS.getLogMessage(
+ LOG_SIGNED_AUDIT_EXCEPTION,gse.toString())));
+ }
+
+
+ // XXX
+ // Although length will be in Unicode dual-bytes, the PrintWriter
+ // will only print out 1 byte per character. I suppose this could
+ // be dependent on the encoding of your log file, but it ain't that
+ // smart yet. Also, add one for the newline. (hmm, on NT, CR+LF)
+ int nBytes = entry.length() + 1;
+
+ mBytesWritten += nBytes;
+ mBytesUnflushed += nBytes;
+
+ if (mBufferSize > 0 && mBytesUnflushed > mBufferSize && !noFlush) {
+ flush();
+ }
+ }
+ }
+
+ /**
+ * Write an event to the log file
+ *
+ * @param ev The event to be logged.
+ */
+ public void log(ILogEvent ev) throws ELogException {
+ if (ev instanceof AuditEvent) {
+ if (!mType.equals("transaction") || (!mOn) || mLevel > ev.getLevel()) {
+ return;
+ }
+ } else if (ev instanceof SystemEvent) {
+ if (!mType.equals("system") || (!mOn) || mLevel > ev.getLevel()) {
+ return;
+ }
+ } else if (ev instanceof SignedAuditEvent) {
+ if (!mType.equals("signedAudit") || (!mOn) || mLevel > ev.getLevel()) {
+ return;
+ }
+ }
+
+ // Is the event type selected?
+ // If no selection specified in configuration, then all are selected
+ // If no type specified in propertity file, then treated as selected
+ if (mSelectedEvents.size() > 0) {
+ String type = ev.getEventType();
+ if (type != null) {
+ if (!mSelectedEvents.contains(type)) {
+ CMS.debug("LogFile: event type not selected: "+type);
+ return;
+ }
+ }
+ }
+
+ String entry = logEvt2String(ev);
+
+ log(entry);
+ }
+
+ public String logEvt2String(ILogEvent ev) {
+ String entry = null;
+
+ // Hmm.. multiple threads could hit this and reset the time.
+ // Do we care?
+ mDate.setTime(ev.getTimeStamp());
+
+ // XXX
+ // This should follow the Common Log Format which still needs
+ // some work.
+ if (ev.getMultiline() == ILogger.L_MULTILINE) {
+ entry = mPid + "." + Thread.currentThread().getName() + " - ["
+ + mLogDateFormat.format(mDate) + "] [" +
+ Integer.toString(ev.getSource()) + "] [" + Integer.toString(ev.getLevel())
+ + "] " + prepareMultiline(ev.toString());
+ } else {
+ entry = mPid + "." + Thread.currentThread().getName() + " - ["
+ + mLogDateFormat.format(mDate) + "] [" +
+ Integer.toString(ev.getSource()) + "] [" + Integer.toString(ev.getLevel())
+ + "] " + ev.toString();
+ }
+
+ return entry;
+ }
+
+ /**
+ * change multi-line log entry by replace "\n" with "\n "
+ *
+ * @param original The original multi-line log entry.
+ */
+ private String prepareMultiline(String original) {
+ int i, last = 0;
+
+ //NT: \r\n, unix: \n
+ while ((i = original.indexOf("\n", last)) != -1) {
+ last = i + 1;
+ original = original.substring(0, i + 1) + " " + original.substring(i + 1);
+ }
+ return original;
+ }
+
+ /**
+ * Read all entries whose logLevel>=lowLevel && log source = source
+ * to at most maxLine entries(from end)
+ * If the parameter is -1, it's ignored and return all entries
+ *
+ * @param maxLine The maximum lines to be returned
+ * @param lowLevel The lowest log level to be returned
+ * @param source The particular log source to be returned
+ * @param fName The log file name to be read. If it's null, read the current
+ * log file
+ */
+ public Vector readEntry(int maxLine, int lowLevel, int source, String fName) {
+ Vector mEntries = new Vector();
+ String fileName = mFileName;
+ BufferedReader fBuffer;
+ int lineNo = 0; // lineNo of the current entry in the log file
+ int line = 0; // line of readed valid entries
+ String firstLine = null; // line buffer
+ String nextLine = null;
+ String entry = null;
+ LogEntry logEntry = null;
+
+ /*
+ this variable is added to accormodate misplaced multiline entries
+ write out buffered log entry when next entry is parsed successfully
+ this implementation is assuming parsing is more time consuming than
+ condition check
+ */
+ LogEntry preLogEntry = null;
+
+ if (fName != null) {
+ fileName = fName;
+ }
+ try {
+ //XXX think about this
+ fBuffer = new BufferedReader(new FileReader(fileName));
+ do {
+ try {
+ nextLine = fBuffer.readLine();
+ if (nextLine != null) {
+ if ((nextLine.length() == 0) || (nextLine.charAt(0) == ' ')) {
+ // It's a continuous line
+ entry = null;
+ if (nextLine.length() > 1)
+ firstLine = firstLine + "\n" + nextLine.substring(1);
+ else
+ firstLine = firstLine + "\n";
+
+ } else {
+ // It's a new entry
+ entry = firstLine;
+ firstLine = nextLine;
+ }
+ // parse the previous entry, the current one is buffered
+ if (entry != null) {
+ try {
+ logEntry = new LogEntry(entry);
+ // if parse succeed, write out previous entry
+ if (preLogEntry != null) {
+ if ((Integer.parseInt(preLogEntry.getLevel()) >= lowLevel) &&
+ ((Integer.parseInt(preLogEntry.getSource()) == source) ||
+ (source == ILogger.S_ALL)
+ )) {
+ mEntries.addElement(preLogEntry);
+ if (maxLine == -1) {
+ line++;
+ } else if (line < maxLine) {
+ line++;
+ } else {
+ mEntries.removeElementAt(0);
+ }
+ }
+ }
+ preLogEntry = logEntry;
+ } catch (ParseException e) {
+ if (preLogEntry != null) {
+ preLogEntry.appendDetail(entry);
+ } else {
+ firstLine = firstLine + "\n" + nextLine;
+ }
+ entry = null;
+ logEntry = null;
+ }
+ }
+ }
+ lineNo++;
+
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("LOGGING_READ_ERROR", fileName,
+ Integer.toString(lineNo)));
+ }
+
+ }
+ while (nextLine != null);
+
+ // need to process the last 2 entries of the file
+ if (firstLine != null) {
+ if (logEntry != null) {
+ preLogEntry = logEntry;
+ }
+ entry = firstLine;
+ try {
+ logEntry = new LogEntry(entry);
+
+ /* System.out.println(
+ Integer.toString(Integer.parseInt(logEntry.getLevel()))
+ +","+Integer.toString(lowLevel)+","+
+ Integer.toString(Integer.parseInt(logEntry.getSource()))
+ +","+Integer.toString(source) );
+ */
+ if (preLogEntry != null) {
+ if ((Integer.parseInt(preLogEntry.getLevel()) >= lowLevel) &&
+ ((Integer.parseInt(preLogEntry.getSource()) == source) ||
+ (source == ILogger.S_ALL)
+ )) {
+ mEntries.addElement(preLogEntry);
+ if (maxLine == -1) {
+ line++;
+ } else if (line < maxLine) {
+ line++;
+ } else {
+ mEntries.removeElementAt(0);
+ }
+ }
+ }
+ preLogEntry = logEntry;
+ } catch (ParseException e) {
+ preLogEntry.appendDetail(entry);
+ }
+
+ if (preLogEntry != null) {
+ if ((Integer.parseInt(preLogEntry.getLevel()) >= lowLevel)
+ &&
+ ((Integer.parseInt(preLogEntry.getSource()) == source)
+ ||
+ (source == ILogger.S_ALL)
+ )) {
+ // parse the entry, pass to UI
+ mEntries.addElement(preLogEntry);
+ if (maxLine == -1) {
+ line++;
+ } else if (line < maxLine) {
+ line++;
+ } else {
+ mEntries.removeElementAt(0);
+ }
+ }
+ }
+
+ }// end: last entry
+
+ try {
+ fBuffer.close();
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, "logging:" + fileName +
+ " failed to close for reading");
+ }
+
+ } catch (FileNotFoundException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("LOGGING_FILE_NOT_FOUND",
+ fileName));
+ }
+ return mEntries;
+ }
+
+ /**
+ * Retrieves the configuration store of this subsystem.
+ * <P>
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieve last "maxLine" number of system log with log lever >"level"
+ * and from source "source". If the parameter is omitted. All entries
+ * are sent back.
+ */
+ public synchronized NameValuePairs retrieveLogContent(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String tmp, fName = null;
+ int maxLine = -1, level = -1, source = -1;
+ Vector entries = null;
+
+ if ((tmp = (String)req.get(Constants.PR_LOG_ENTRY)) != null) {
+ maxLine = Integer.parseInt(tmp);
+ }
+ if ((tmp = (String)req.get(Constants.PR_LOG_LEVEL)) != null) {
+ level = Integer.parseInt(tmp);
+ }
+ if ((tmp = (String)req.get(Constants.PR_LOG_SOURCE)) != null) {
+ source = Integer.parseInt(tmp);
+ }
+ tmp = (String)req.get(Constants.PR_LOG_NAME);
+ if (!(tmp.equals(Constants.PR_CURRENT_LOG))) {
+ fName = tmp;
+ } else {
+ flush();
+ }
+
+ try {
+ entries = readEntry(maxLine, level, source, fName);
+ for (int i = 0; i < entries.size(); i++) {
+ params.add(Integer.toString(i) +
+ ((LogEntry) entries.elementAt(i)).getEntry(), "");
+ }
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_WARN,
+ "System log parse error");
+ }
+ return params;
+ }
+
+ /**
+ * Retrieve log file list.
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "LogFile";
+ }
+
+ public String getDescription() {
+ return "LogFile";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_TYPE + "=");
+ v.addElement(PROP_ON + "=");
+ v.addElement(PROP_LEVEL + "=");
+ v.addElement(PROP_FILE_NAME + "=");
+ v.addElement(PROP_BUFFER_SIZE + "=");
+ v.addElement(PROP_FLUSH_INTERVAL + "=");
+
+ // needs to find a way to determine what type you want. if this
+ // is not for the signed audit type, then we should not show the
+ // following parameters.
+ //if( mType.equals( ILogger.PROP_SIGNED_AUDIT ) ) {
+ v.addElement( PROP_SIGNED_AUDIT_LOG_SIGNING + "=" );
+ v.addElement( PROP_SIGNED_AUDIT_CERT_NICKNAME + "=" );
+ v.addElement( PROP_SIGNED_AUDIT_EVENTS + "=" );
+ //}
+
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ try {
+ String logStatus = null;
+
+ if (mType == null) {
+ v.addElement(PROP_TYPE + "=");
+ }else {
+ v.addElement(PROP_TYPE + "=" +
+ mConfig.getString(PROP_TYPE));
+ }
+ v.addElement(PROP_ON + "=" + logStatus.valueOf( mOn ) );
+ if (mLevel == 0)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_DEBUG_STRING);
+ else if (mLevel == 1)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_INFO_STRING);
+ else if (mLevel == 2)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_WARN_STRING);
+ else if (mLevel == 3)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_FAILURE_STRING);
+ else if (mLevel == 4)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_MISCONF_STRING);
+ else if (mLevel == 5)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_CATASTRPHE_STRING);
+ else if (mLevel == 6)
+ v.addElement(PROP_LEVEL + "=" + ILogger.LL_SECURITY_STRING);
+
+ if (mFileName == null) {
+ v.addElement(PROP_FILE_NAME + "=");
+ }else {
+ v.addElement(PROP_FILE_NAME + "=" +
+ mFileName);
+ }
+ v.addElement(PROP_BUFFER_SIZE + "=" + mBufferSize);
+ v.addElement(PROP_FLUSH_INTERVAL + "=" + mFlushInterval / 1000);
+
+ if( (mType != null) && mType.equals( ILogger.PROP_SIGNED_AUDIT ) ) {
+ String logSigning = null;
+
+ v.addElement( PROP_SIGNED_AUDIT_LOG_SIGNING + "="
+ + logSigning.valueOf( mLogSigning ) );
+
+ if( mSAuditCertNickName == null ) {
+ v.addElement( PROP_SIGNED_AUDIT_CERT_NICKNAME + "=" );
+ } else {
+ v.addElement( PROP_SIGNED_AUDIT_CERT_NICKNAME + "="
+ + mSAuditCertNickName );
+ }
+
+ if( mSelectedEventsList == null ) {
+ v.addElement( PROP_SIGNED_AUDIT_EVENTS + "=" );
+ } else {
+ v.addElement( PROP_SIGNED_AUDIT_EVENTS + "="
+ + mSelectedEventsList );
+ }
+ }
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if( mType.equals( ILogger.PROP_SIGNED_AUDIT ) ) {
+ String[] params = {
+ PROP_TYPE + ";choice(transaction,signedAudit,system);The log event type this instance is listening to",
+ PROP_ON + ";boolean;Turn on the listener",
+ PROP_LEVEL + ";choice(" + ILogger.LL_DEBUG_STRING + "," +
+ ILogger.LL_INFO_STRING + "," +
+ ILogger.LL_WARN_STRING + "," +
+ ILogger.LL_FAILURE_STRING + "," +
+ ILogger.LL_MISCONF_STRING + "," +
+ ILogger.LL_CATASTRPHE_STRING + "," +
+ ILogger.LL_SECURITY_STRING + ");Only log message with level higher than this filter will be written by this listener",
+ PROP_FILE_NAME + ";string;The name of the file the log is written to",
+ PROP_BUFFER_SIZE + ";integer;The size of the buffer to receive log messages in kilobytes(KB)",
+ PROP_FLUSH_INTERVAL + ";integer;The maximum time in seconds before the buffer is flushed to the file",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-logrules-logfile",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Write the log messages to a file",
+ PROP_SIGNED_AUDIT_LOG_SIGNING +
+ ";boolean;Enable audit logs to be signed",
+ PROP_SIGNED_AUDIT_CERT_NICKNAME +
+ ";string;The nickname of the certificate to be used to sign audit logs",
+ PROP_SIGNED_AUDIT_EVENTS +
+ ";string;A comma-separated list of strings used to specify particular signed audit log events",
+ };
+
+ return params;
+ } else {
+ // mType.equals( ILogger.PROP_AUDIT ) ||
+ // mType.equals( ILogger.PROP_SYSTEM )
+ String[] params = {
+ PROP_TYPE + ";choice(transaction,signedAudit,system);The log event type this instance is listening to",
+ PROP_ON + ";boolean;Turn on the listener",
+ PROP_LEVEL + ";choice(" + ILogger.LL_DEBUG_STRING + "," +
+ ILogger.LL_INFO_STRING + "," +
+ ILogger.LL_WARN_STRING + "," +
+ ILogger.LL_FAILURE_STRING + "," +
+ ILogger.LL_MISCONF_STRING + "," +
+ ILogger.LL_CATASTRPHE_STRING + "," +
+ ILogger.LL_SECURITY_STRING + ");Only log message with level higher than this filter will be written by this listener",
+ PROP_FILE_NAME + ";string;The name of the file the log is written to",
+ PROP_BUFFER_SIZE + ";integer;The size of the buffer to receive log messages in kilobytes(KB)",
+ PROP_FLUSH_INTERVAL + ";integer;The maximum time in seconds before the buffer is flushed to the file",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-logrules-logfile",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Write the log messages to a file"
+ };
+
+ return params;
+ }
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all classes that extend this "LogFile"
+ * class, and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit( String msg )
+ {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if( mSignedAuditLogger == null ) {
+ return;
+ }
+
+ mSignedAuditLogger.log( ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg );
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/logging/RollingLogFile.java b/pki/base/common/src/com/netscape/cms/logging/RollingLogFile.java
new file mode 100644
index 000000000..32702d00d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/logging/RollingLogFile.java
@@ -0,0 +1,651 @@
+// --- 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.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * A rotating log file for Certificate log events. This class loosely follows
+ * the Netscape Common Log API implementing rollover interval, size and file
+ * naming conventions. It does not yet implement Disk Usage.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RollingLogFile extends LogFile {
+ public static final String PROP_MAX_FILE_SIZE = "maxFileSize";
+ public static final String PROP_ROLLOVER_INTERVAL = "rolloverInterval";
+ public static final String PROP_EXPIRATION_TIME = "expirationTime";
+
+ /**
+ * The default max file size in bytes
+ */
+ static final int MAX_FILE_SIZE = 100;
+
+ /**
+ * The default rollover interval in seconds
+ */
+ static final String ROLLOVER_INTERVAL = "2592000";
+
+ /**
+ * The default expiration time in seconds
+ */
+ static final String EXPIRATION_TIME = "2592000";
+
+ /**
+ * The maximum file size in bytes
+ */
+ protected int mMaxFileSize = 0;
+
+ /**
+ * The amount of time in miniseconds between log rotations
+ */
+ protected long mRolloverInterval = 0;
+
+ /**
+ * The thread responsible for rotating the log
+ */
+ private Thread mRolloverThread = null;
+
+ /**
+ * The incrementing backup number for the log file names
+ */
+ private int mFileNumber = 1;
+
+ /**
+ * The amount of time before a backed up log is removed in milliseconds
+ */
+ protected long mExpirationTime = 0;
+
+ /**
+ * The thread responsible for removing expired log files
+ */
+ private Thread mExpirationThread = null;
+
+ /**
+ * The object used as a lock for expiration thread synchronization
+ */
+ private Object mExpLock = new Object();
+
+ private final static String LOGGING_SIGNED_AUDIT_LOG_DELETE =
+ "LOGGING_SIGNED_AUDIT_LOG_DELETE_3";
+
+ /**
+ * Construct a RollingLogFile
+ */
+ public RollingLogFile() {
+ }
+
+ /**
+ * Initialize and open a RollingLogFile using the prop config store
+ *
+ * @param config The property config store to find values in
+ */
+ public void init(IConfigStore config) throws IOException,
+ EBaseException {
+ super.init(config);
+
+ rl_init(config.getInteger(PROP_MAX_FILE_SIZE, MAX_FILE_SIZE),
+ config.getString(PROP_ROLLOVER_INTERVAL, ROLLOVER_INTERVAL),
+ config.getString(PROP_EXPIRATION_TIME, EXPIRATION_TIME));
+ }
+
+ /**
+ * Convenience routine to initialized the RollingLogFile specific
+ * attributes.
+ */
+ protected void rl_init(int maxFileSize, String rolloverInterval,
+ String expirationTime) {
+ mMaxFileSize = maxFileSize * 1024;
+ setRolloverTime(rolloverInterval);
+ setExpirationTime(expirationTime);
+ }
+
+ public void startup() throws EBaseException {
+ super.startup();
+ }
+
+ /**
+ * Shutdown this log file.
+ */
+ public synchronized void shutdown() {
+ setRolloverTime("0");
+ setExpirationTime("0");
+ super.shutdown();
+ }
+
+ /**
+ * Set the rollover interval
+ *
+ * @param rolloverSeconds The amount of time in seconds until the log
+ * is rotated. A value of 0 will disable log rollover.
+ **/
+ public synchronized void setRolloverTime(String rolloverSeconds) {
+ mRolloverInterval = Long.valueOf(rolloverSeconds).longValue() * 1000;
+
+ if ((mRolloverThread == null) && (mRolloverInterval > 0)) {
+ mRolloverThread = new RolloverThread();
+ mRolloverThread.setDaemon(true);
+ mRolloverThread.start();
+ }
+
+ this.notify();
+ }
+
+ /**
+ * Get the rollover interval
+ *
+ * @return The interval in seconds in which the log is rotated
+ **/
+ public synchronized int getRolloverTime() {
+ return (int) (mRolloverInterval / 1000);
+ }
+
+ /**
+ * Set the file expiration time
+ *
+ * @param expirationSeconds The amount of time in seconds until log files
+ * are deleted
+ **/
+ public void setExpirationTime(String expirationSeconds) {
+
+ // Need to completely protect changes to mExpiration time
+ // and make sure they only happen while the thread is sleeping
+ synchronized (mExpLock) {
+ mExpirationTime = Long.valueOf(expirationSeconds).longValue() * 1000;
+
+ if (mExpirationThread == null) {
+ if (mExpirationTime > 0) {
+ mExpirationThread = new ExpirationThread();
+ mExpirationThread.setDaemon(true);
+ mExpirationThread.start();
+ }
+ } else {
+ mExpLock.notify();
+ }
+ }
+ }
+
+ /**
+ * Get the expiration time
+ *
+ * @return The age in seconds in which log files are delete
+ **/
+ public int getExpirationTime() {
+ return (int) (mExpirationTime / 1000);
+ }
+
+ /**
+ * Rotate the log file to a backup file with a incrementing integer
+ * extension
+ **/
+ public synchronized void rotate()
+ throws IOException {
+
+ //File backupFile = new File(mFileName + "." + mFileNumber);
+ File backupFile = new File(mFileName + "." + mLogFileDateFormat.format(mDate));
+
+ // close, backup, and reopen the log file zeroizing its contents
+ super.close();
+ try {
+ if( Utils.isNT() ) {
+ // NT is very picky on the path
+ Utils.exec( "copy " +
+ mFile.getCanonicalPath().replace( '/', '\\' ) +
+ " " +
+ backupFile.getCanonicalPath().replace( '/',
+ '\\' ) );
+ } else {
+ // Create a copy of the original file which
+ // preserves the original file permissions.
+ Utils.exec( "cp -p " + mFile.getCanonicalPath() + " " +
+ backupFile.getCanonicalPath() );
+ }
+
+ // Zeroize the original file if and only if
+ // the backup copy was successful.
+ if( backupFile.exists() ) {
+
+ // Make certain that the backup file has
+ // the correct permissions.
+ if( !Utils.isNT() ) {
+ Utils.exec( "chmod 00640 " + backupFile.getCanonicalPath() );
+ }
+
+ try {
+ // Open and close the original file
+ // to zeroize its contents.
+ PrintWriter pw = new PrintWriter( mFile );
+ pw.close();
+
+ // Make certain that the original file retains
+ // the correct permissions.
+ if( !Utils.isNT() ) {
+ Utils.exec( "chmod 00640 " + mFile.getCanonicalPath() );
+ }
+ } catch ( FileNotFoundException e ) {
+ CMS.debug( "Unable to zeroize "
+ + mFile.toString() );
+ }
+ } else {
+ CMS.debug( "Unable to backup "
+ + mFile.toString() + " to "
+ + backupFile.toString() );
+ }
+ } catch( Exception e ) {
+ CMS.debug( "Unable to backup "
+ + mFile.toString() + " to "
+ + backupFile.toString() );
+ }
+ super.open(); // will reset mBytesWritten
+ mFileNumber++;
+ }
+
+ /**
+ * Remove any log files which have not been modified in the specified
+ * time
+ * <P>
+ *
+ * NOTE: automatic removal of log files is currently NOT supported!
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_LOG_DELETE used AFTER audit log
+ * expires (authorization should not allow, but in case authorization gets
+ * compromised make sure it is written AFTER the log expiration happens)
+ * </ul>
+ * @param expirationSeconds The number of seconds since the expired files
+ * have been modified.
+ * @return the time in milliseconds when the next file expires
+ **/
+ public long expire(long expirationSeconds) throws ELogException {
+ String auditMessage = null;
+
+ if (expirationSeconds <= 0)
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_EXPIRATION_TIME_ZERO"));
+
+ long expirationTime = expirationSeconds * 1000;
+ long currentTime = System.currentTimeMillis();
+ long oldestFile = currentTime;
+
+ String dirName = mFile.getParent();
+
+ if (dirName == null)
+ dirName = ".";
+ File dir = new File(dirName);
+
+ // Get just the base name, minus the .date extension
+ //int len = mFile.getName().length() - LogFile.DATE_PATTERN.length() - 1;
+ //String baseName = mFile.getName().substring(0, len);
+ String fileName = mFile.getName();
+ String baseName = null, pathName = null;
+ int index = fileName.lastIndexOf("/");
+
+ if (index != -1) { // "/" exist in fileName
+ pathName = fileName.substring(0, index);
+ baseName = fileName.substring(index + 1);
+ if (dirName == null) {
+ dirName = pathName;
+ } else {
+ dirName = dirName.concat("/" + pathName);
+ }
+ }else { // "/" NOT exist in fileName
+ baseName = fileName;
+ }
+
+ fileFilter ff = new fileFilter(baseName + ".");
+ String[] filelist = dir.list(ff);
+
+ if (filelist == null) { // Crap! Something is wrong.
+ throw new
+ ELogException(CMS.getUserMessage("CMS_LOG_DIRECTORY_LIST_FAILED",
+ dirName, ff.toString()));
+ }
+
+ // Walk through the list of files which match this log file name
+ // and delete the old ones.
+ for (int i = 0; i < filelist.length; i++) {
+ if (pathName != null) {
+ filelist[i] = pathName + "/" + filelist[i];
+ }else {
+ filelist[i] = dirName + "/" + filelist[i];
+ }
+
+ String fullname = dirName + File.separatorChar + filelist[i];
+ File file = new File(fullname);
+ long fileTime = file.lastModified();
+
+ // Java documentation on File says lastModified() should not
+ // be interpeted. The doc is wrong. See JavaSoft bug #4094538
+ if ((currentTime - fileTime) > expirationTime) {
+ file.delete();
+
+ if (file.exists()) {
+ // log failure in deleting an expired signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_DELETE,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ fullname);
+ } else {
+ // log success in deleting an expired signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_DELETE,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS,
+ fullname);
+ }
+
+ audit(auditMessage);
+ } else if (fileTime < oldestFile) {
+ oldestFile = fileTime;
+ }
+ }
+ return oldestFile + expirationTime;
+ }
+
+ //
+ // Rollover and Expiration threads
+ //
+ // At first glance you may think it's a waste of thread resources to have
+ // two threads for every log file, but the truth is that these threads are
+ // sleeping 99% of the time. NxN thread implementations (Solaris, NT,
+ // IRIX 6.4, Unixware, etc...) will handle these in user space.
+ //
+ // You may be able to join these into one thread, and deal with
+ // multiple wakeup times, but the code would sure look ugly, and the race
+ // conditions are numerous as is. Furthermore, this is what user space
+ // threads will do for you anyways.
+ //
+
+ /**
+ * Log rotation thread. Sleep for the rollover interval and rotate the
+ * log. Changing rollover interval to 0 will cause this thread to exit.
+ */
+ final class RolloverThread extends Thread {
+
+ /**
+ * Rollover thread constructor including thread name
+ */
+ public RolloverThread() {
+ super();
+ super.setName(mFileName + ".rollover-" + (Thread.activeCount() + 1));
+ }
+
+ public void run() {
+ while (mRolloverInterval > 0) {
+ // Sleep for the interval and then rotate the log
+ synchronized (RollingLogFile.this) {
+ try {
+ RollingLogFile.this.wait(mRolloverInterval);
+ } catch (InterruptedException e) {
+ // This shouldn't happen very often
+ CMS.getLogger().getLogQueue().log(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_THREAD_INTERRUPT", "rollover")));
+ }
+ }
+
+ if (mRolloverInterval == 0) {
+ break;
+ }
+
+ if (mBytesWritten > 0) {
+ try {
+ rotate();
+ } catch (IOException e) {
+ ConsoleError.send(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_ROTATE_LOG_FAILED", mFile.getName(), e.toString())));
+ break;
+ }
+ }
+ // else
+ // Don't rotate empty logs
+ // flag in log summary file?
+ }
+ mRolloverThread = null;
+ }
+ }
+
+
+ /**
+ * Log expiration thread. Sleep for the expiration interval and
+ * delete any files which are too old.
+ * Changing expiration interval to 0 will cause this thread to exit.
+ */
+ final class ExpirationThread extends Thread {
+
+ /**
+ * ExpirationThread thread constructor including thread name
+ */
+ public ExpirationThread() {
+ super();
+ super.setName(mFileName + ".expiration-" + (Thread.activeCount() + 1));
+ }
+
+ public void run() {
+ synchronized (mExpLock) {
+ while (mExpirationTime > 0) {
+ long wakeupTime = 0;
+ long sleepTime = 0;
+
+ // First, remove any old log files and figure out when the
+ // next one expires
+ try {
+ wakeupTime = expire((long) (mExpirationTime / 1000));
+ } catch (SecurityException e) {
+ ConsoleError.send(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_EXPIRE_LOG_FAILED", e.toString())));
+ break;
+ } catch (ELogException e) {
+ ConsoleError.send(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_EXPIRE_LOG_FAILED", e.toString())));
+ break;
+ }
+
+ sleepTime = wakeupTime - System.currentTimeMillis();
+ //System.out.println("wakeup " + wakeupTime);
+ //System.out.println("current "+System.currentTimeMillis());
+ //System.out.println("sleep " + sleepTime);
+ // Sleep for the interval and then check the directory
+ // Note: mExpirationTime can only change while we're
+ // sleeping
+ if (sleepTime > 0) {
+ try {
+ mExpLock.wait(sleepTime);
+ } catch (InterruptedException e) {
+ // This shouldn't happen very often
+ ConsoleError.send(new
+ SystemEvent(CMS.getUserMessage("CMS_LOG_THREAD_INTERRUPT", "expiration")));
+ }
+ }
+ }
+ }
+ mExpirationThread = null;
+ }
+ }
+
+ /**
+ * Write an event to the log file
+ *
+ * @param ev The event to be logged.
+ **/
+ public synchronized void log(ILogEvent ev) throws ELogException {
+ //xxx, Shall we log first without checking if it exceed the maximum?
+ super.log(ev); // Will increment mBytesWritten
+
+ if ((0 != mMaxFileSize) && (mBytesWritten > mMaxFileSize)) {
+ flush();
+ try {
+ rotate();
+ } catch (IOException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_ROTATE_LOG_FAILED", mFile.getName(), e.toString()));
+ }
+ }
+ }
+
+ /**
+ * Retrieve log file list.
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable req
+ ) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String[] files = null;
+
+ files = fileList();
+ for (int i = 0; i < files.length; i++) {
+ params.add(files[i], "");
+ }
+ return params;
+ }
+
+ /**
+ * Get the log file list in the log directory
+ *
+ * @return an array of filenames with related path to cert server root
+ */
+ protected String[] fileList() {
+ String pathName = null, baseName = null;
+
+ String dirName = mFile.getParent();
+ String fileName = mFile.getName();
+ int index = fileName.lastIndexOf("/");
+
+ if (index != -1) { // "/" exist in fileName
+ pathName = fileName.substring(0, index);
+ baseName = fileName.substring(index + 1);
+ if (dirName == null) {
+ dirName = pathName;
+ } else {
+ dirName = dirName.concat("/" + pathName);
+ }
+ }else { // "/" NOT exist in fileName
+ baseName = fileName;
+ }
+
+ File dir = new File(dirName);
+
+ fileFilter ff = new fileFilter(baseName + ".");
+ //There are some difference here. both should work
+ //error,logs,logs/error jdk115
+ //logs/system,., logs/system jdk116
+ //System.out.println(mFile.getName()+","+dirName+","+mFile.getPath()); //log/system,.
+
+ String[] filelist = dir.list(ff);
+
+ for (int i = 0; i < filelist.length; i++) {
+ if (pathName != null) {
+ filelist[i] = pathName + "/" + filelist[i];
+ }else {
+ filelist[i] = dirName + "/" + filelist[i];
+ }
+ }
+ return filelist;
+ }
+
+ public String getImplName() {
+ return "RollingLogFile";
+ }
+
+ public String getDescription() {
+ return "RollingLogFile";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = super.getDefaultParams();
+
+ v.addElement(PROP_MAX_FILE_SIZE + "=");
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=");
+ //v.addElement(PROP_EXPIRATION_TIME + "=");
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = super.getInstanceParams();
+
+ try {
+ v.addElement(PROP_MAX_FILE_SIZE + "=" + mMaxFileSize / 1024);
+ if (mRolloverInterval / 1000 <= 60 * 60)
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=" + "Hourly");
+ else if (mRolloverInterval / 1000 <= 60 * 60 * 24)
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=" + "Daily");
+ else if (mRolloverInterval / 1000 <= 60 * 60 * 24 * 7)
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=" + "Weekly");
+ else if (mRolloverInterval / 1000 <= 60 * 60 * 24 * 30)
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=" + "Monthly");
+ else if (mRolloverInterval / 1000 <= 60 * 60 * 24 * 366)
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=" + "Yearly");
+
+ //v.addElement(PROP_EXPIRATION_TIME + "=" + mExpirationTime / 1000);
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] p = super.getExtendedPluginInfo(locale);
+ Vector info = new Vector();
+
+ for (int i = 0; i < p.length; i++) {
+ if (!p[i].startsWith(IExtendedPluginInfo.HELP_TOKEN) && !p[i].startsWith(IExtendedPluginInfo.HELP_TEXT))
+ info.addElement(p[i]);
+ }
+ info.addElement(PROP_MAX_FILE_SIZE + ";integer;If the current log file size if bigger than this parameter in kilobytes(KB), the file will be rotated.");
+ info.addElement(PROP_ROLLOVER_INTERVAL + ";choice(Hourly,Daily,Weekly,Monthly,Yearly);The frequency of the log being rotated.");
+ info.addElement(PROP_EXPIRATION_TIME + ";integer;The amount of time before a backed up log is removed in seconds");
+ info.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ //";configuration-logrules-rollinglogfile");
+ ";configuration-adminbasics");
+ info.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Write the log messages to a file which will be rotated automatically.");
+ String[] params = new String[info.size()];
+
+ info.copyInto(params);
+ return params;
+
+ }
+}
+
+
+/**
+ * A file filter to select the file with a given prefix
+ */
+class fileFilter implements FilenameFilter {
+ String patternToMatch = null;
+
+ public fileFilter (String pattern) {
+ patternToMatch = pattern;
+ }
+
+ public boolean accept(File dir, String name) {
+ if (name.startsWith(patternToMatch))
+ return true;
+ else
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/notification/MailNotification.java b/pki/base/common/src/com/netscape/cms/notification/MailNotification.java
new file mode 100644
index 000000000..e85911137
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/notification/MailNotification.java
@@ -0,0 +1,195 @@
+// --- 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.notification;
+
+
+import java.util.*;
+import java.io.*;
+import java.lang.String;
+import netscape.net.smtp.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This class handles mail notification via SMTP.
+ * This class uses <b>smtp.host</b> in the configuration for smtp
+ * host. The port default (25) is used. If no smtp specified, local
+ * host is used
+ *
+ * @version $Revision$, $Date$
+ */
+public class MailNotification implements IMailNotification {
+ private ILogger mLogger = CMS.getLogger();
+ protected final static String PROP_SMTP_SUBSTORE = "smtp";
+ protected final static String PROP_HOST = "host";
+
+ private String mHost = null;
+
+ private String mFrom = null;
+ private String mTo = null;
+ private String mSubject = null;
+ private String mContent = null;
+ private String mContentType = null;
+
+ public MailNotification() {
+ if (mHost == null) {
+ try {
+ IConfigStore mConfig =
+ CMS.getConfigStore();
+
+ IConfigStore c =
+ mConfig.getSubStore(PROP_SMTP_SUBSTORE);
+
+ if (c == null) {
+ return;
+ }
+ mHost = c.getString(PROP_HOST);
+
+ // log it
+ // if (mHost !=null) {
+ // String msg =" using external SMTP host: "+mHost;
+ // CMS.debug("MailNotification: " + msg);
+ //}
+ } catch (Exception e) {
+ // don't care
+ }
+ }
+ }
+
+ /**
+ * send one message to one or more addressees
+ */
+ public void sendNotification() throws IOException, ENotificationException {
+ // create smtp client
+ SmtpClient sc = null;
+
+ if (!mHost.equals("")) {
+ sc = new SmtpClient(mHost);
+ } else {
+ sc = new SmtpClient();
+ }
+
+ // set "from", message subject
+ if ((mFrom != null) && (!mFrom.equals("")))
+ sc.from(mFrom);
+ else {
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_NO_SMTP_SENDER"));
+ }
+
+ // set "to"
+ if ((mTo != null) && (!mTo.equals(""))) {
+ log(ILogger.LL_INFO, "mail to be sent to " + mTo);
+ sc.to(mTo);
+ } else {
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_NO_SMTP_RECEIVER"));
+ }
+
+ // set message content
+ PrintStream msgStream = sc.startMessage();
+
+ if (mContentType != null) {
+ msgStream.print("From: " + mFrom + "\n");
+ msgStream.print("MIME-Version: 1.0\n");
+ msgStream.print("To: " + mTo + "\n");
+ msgStream.print(mSubject + "\n");
+ msgStream.print(mContentType + "\n");
+ } else {
+ msgStream.print("From: " + mFrom + "\n");
+ msgStream.print("To: " + mTo + "\n");
+ msgStream.print(mSubject + "\n");
+ }
+ msgStream.print("\r\n");
+ msgStream.print(mContent + "\r\n");
+
+ // send
+ try {
+ sc.closeServer();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_SMTP_SEND_FAILED", mTo));
+ }
+ }
+
+ /**
+ * sets the "From" field
+ * @param from email address of the sender
+ */
+ public void setFrom(String from) {
+ mFrom = from;
+ }
+
+ /**
+ * sets the "Subject" field
+ * @param subject subject of the email
+ */
+ public void setSubject(String subject) {
+ mSubject = "Subject: " + subject;
+ }
+
+ /**
+ * sets the "Content-Type" field
+ * @param contentType content type of the email
+ */
+ public void setContentType(String contentType) {
+ mContentType = "Content-Type: " + contentType;
+ }
+
+ /**
+ * sets the content of the email
+ * @param content the message content
+ */
+ public void setContent(String content) {
+ mContent = content;
+ }
+
+ /**
+ * sets the recipients' email addresses
+ * @param addresses a list of email addresses of the recipients
+ */
+ public void setTo(Vector addresses) {
+ // concatenate addresses into comma separated mTo String
+
+ }
+
+ /**
+ * sets the recipient's email address
+ * @param to address of the recipient email address
+ */
+ public void setTo(String to) {
+ mTo = to;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "MailNotification: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java b/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java
new file mode 100644
index 000000000..7c9c2bb1f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java
@@ -0,0 +1,924 @@
+// --- 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.ocsp;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authority.*;
+
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.cmsutil.ocsp.*;
+import com.netscape.certsrv.apps.*;
+
+import org.mozilla.jss.pkix.cert.Extension;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+
+
+/**
+ * This is the default OCSP store that stores revocation information
+ * as certificate record (CMS internal data structure).
+ *
+ * @version $Revision$, $Date$
+ */
+public class DefStore implements IDefStore, IExtendedPluginInfo {
+
+ // refreshInSec is useful in the master-clone situation.
+ // clone does not know that the CRL has been updated in
+ // the master (by default no refresh)
+ private static final String PROP_USE_CACHE = "useCache";
+
+ private static final String PROP_REFRESH_IN_SEC = "refreshInSec";
+ private static final int DEF_REFRESH_IN_SEC = 0;
+
+ public static final BigInteger BIG_ZERO = new BigInteger("0");
+ public static final Long MINUS_ONE = Long.valueOf(-1);
+
+ private final static String PROP_BY_NAME =
+ "byName";
+ private final static String PROP_WAIT_ON_CRL_UPDATE =
+ "waitOnCRLUpdate";
+ private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood";
+ private final static String PROP_INCLUDE_NEXT_UPDATE =
+ "includeNextUpdate";
+
+ protected Hashtable mReqCounts = new Hashtable();
+ protected boolean mNotFoundGood = true;
+ protected boolean mUseCache = true;
+ protected boolean mByName = true;
+ protected boolean mIncludeNextUpdate = false;
+ protected Hashtable mCacheCRLIssuingPoints = new Hashtable();
+ private IOCSPAuthority mOCSPAuthority = null;
+ private IConfigStore mConfig = null;
+ private String mId = null;
+ private IDBSubsystem mDBService = null;
+ private X509CRLImpl mCRLImpl = null;
+ private CRLNumberExtension mCRLNumberExt = null;
+ private int mStateCount = 0;
+
+ /**
+ * Constructs the default store.
+ */
+ public DefStore() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_NOT_FOUND_GOOD + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_NOT_FOUND_GOOD"));
+ v.addElement(PROP_BY_NAME + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_BY_NAME"));
+ v.addElement(PROP_INCLUDE_NEXT_UPDATE + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_INCLUDE_NEXT_UPDATE"));
+ v.addElement(IExtendedPluginInfo.HELP_TEXT + "; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_DESC"));
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN + ";configuration-ocspstores-defstore");
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOCSPAuthority = (IOCSPAuthority) owner;
+ mConfig = config;
+
+ mDBService = (IDBSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_DBS);
+
+ // Standalone OCSP server only stores information about revoked
+ // certificates. So there is no way for the OCSP server to
+ // tell if a certificate is good (issued) or not.
+ // When an OCSP client asks the status of a certificate,
+ // the OCSP server by default returns GOOD. If the server
+ // returns UNKNOWN, the OCSP client (browser) will display
+ // a error dialog that confuses the end-user.
+ //
+ // OCSP response can return unknown or good when a certificate
+ // is not revoked.
+ mNotFoundGood = mConfig.getBoolean(PROP_NOT_FOUND_GOOD, true);
+
+ mUseCache = mConfig.getBoolean(PROP_USE_CACHE, true);
+
+ mByName = mConfig.getBoolean(PROP_BY_NAME, true);
+
+ // To include next update in the OCSP response. If included,
+ // PSM (client) will check to see if the revoked information
+ // is too old or not
+ mIncludeNextUpdate = mConfig.getBoolean(PROP_INCLUDE_NEXT_UPDATE,
+ false);
+
+ // should move this into DBSubsystem ....
+ IDBRegistry reg = mDBService.getRegistry();
+
+ // init web gateway.
+ initWebGateway();
+
+ /**
+ DeleteOldCRLsThread t = new DeleteOldCRLsThread(this);
+ t.start();
+ **/
+ // deleteOldCRLs();
+ }
+
+ /**
+ * init web gateway - just gets the ee gateway for this CA.
+ */
+ private void initWebGateway()
+ throws EBaseException {
+ }
+
+ public IRepositoryRecord createRepositoryRecord() {
+ return CMS.createRepositoryRecord();
+ }
+
+ /**
+ * Returns to the client once the CRL is received.
+ */
+ public boolean waitOnCRLUpdate() {
+ boolean defaultVal = true;
+
+ try {
+ return mConfig.getBoolean(PROP_WAIT_ON_CRL_UPDATE, defaultVal);
+ } catch (EBaseException e) {
+ return defaultVal;
+ }
+ }
+
+ public boolean includeNextUpdate() {
+ return mIncludeNextUpdate;
+ }
+
+ public boolean isNotFoundGood() {
+ return mNotFoundGood;
+ }
+
+ public long getReqCount(String id) {
+ Long c = (Long) mReqCounts.get(id);
+
+ if (c == null)
+ return 0;
+ else
+ return c.longValue();
+ }
+
+ public void incReqCount(String id) {
+ mReqCounts.put(id, Long.valueOf(getReqCount(id) + 1));
+ }
+
+ /**
+ * This store will not delete the old CRL until the
+ * new one is totally committed.
+ */
+ public void deleteOldCRLs() throws EBaseException {
+ Enumeration recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+ X509CertImpl theCert = null;
+ ICRLIssuingPointRecord theRec = null;
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = (ICRLIssuingPointRecord)
+ recs.nextElement();
+
+ deleteOldCRLsInCA(rec.getId());
+ }
+ }
+
+ public void deleteOldCRLsInCA(String caName) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ ICRLIssuingPointRecord cp = (ICRLIssuingPointRecord)
+ readCRLIssuingPoint(caName);
+
+ if (cp == null)
+ return; // nothing to do
+ if (cp.getThisUpdate() == null)
+ return; // nothing to do
+ String thisUpdate = Long.toString(
+ cp.getThisUpdate().getTime());
+ Enumeration e = searchRepository(
+ caName,
+ "(!" + IRepositoryRecord.ATTR_SERIALNO + "=" +
+ thisUpdate + ")");
+
+ while (e != null && e.hasMoreElements()) {
+ IRepositoryRecord r = (IRepositoryRecord)
+ e.nextElement();
+ Enumeration recs =
+ searchCertRecord(caName,
+ r.getSerialNumber().toString(),
+ ICertRecord.ATTR_ID + "=*");
+
+ log(ILogger.LL_INFO, "remove CRL 0x" +
+ r.getSerialNumber().toString(16) +
+ " of " + caName);
+ String rep_dn = "ou=" +
+ r.getSerialNumber().toString() +
+ ",cn=" + transformDN(caName) + "," +
+ getBaseDN();
+
+ while (recs != null && recs.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) recs.nextElement();
+ String cert_dn = "cn=" +
+ rec.getSerialNumber().toString() + "," + rep_dn;
+
+ s.delete(cert_dn);
+ }
+ s.delete(rep_dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void log(int event, int level, String msg) {
+ mOCSPAuthority.log(event, level, msg);
+ }
+
+ public void log(int level, String msg) {
+ mOCSPAuthority.log(level, msg);
+ }
+
+ public void startup() throws EBaseException {
+ int refresh = mConfig.getInteger(PROP_REFRESH_IN_SEC,
+ DEF_REFRESH_IN_SEC);
+ if (refresh > 0) {
+ DefStoreCRLUpdater updater =
+ new DefStoreCRLUpdater(mCacheCRLIssuingPoints, refresh);
+ updater.start();
+ }
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Validate an OCSP request.
+ */
+ public OCSPResponse validate(OCSPRequest request)
+ throws EBaseException {
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+
+ mOCSPAuthority.incNumOCSPRequest(1);
+ long startTime = CMS.getCurrentDate().getTime();
+ try {
+ mOCSPAuthority.log(ILogger.LL_INFO, "start OCSP request");
+ TBSRequest tbsReq = request.getTBSRequest();
+
+ // (3) look into database to check the
+ // certificate's status
+ Vector singleResponses = new Vector();
+ if (statsSub != null) {
+ statsSub.startTiming("lookup");
+ }
+
+ long lookupStartTime = CMS.getCurrentDate().getTime();
+ for (int i = 0; i < tbsReq.getRequestCount(); i++) {
+ com.netscape.cmsutil.ocsp.Request req =
+ tbsReq.getRequestAt(i);
+ CertID cid = req.getCertID();
+ SingleResponse sr = processRequest(cid);
+
+ singleResponses.addElement(sr);
+ }
+ long lookupEndTime = CMS.getCurrentDate().getTime();
+ if (statsSub != null) {
+ statsSub.endTiming("lookup");
+ }
+ mOCSPAuthority.incLookupTime(lookupEndTime - lookupStartTime);
+
+ if (singleResponses.size() <= 0) {
+ CMS.debug("DefStore: No Request Found");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_REQUEST_FAILURE", "No Request Found"));
+ return null;
+ }
+ if (statsSub != null) {
+ statsSub.startTiming("build_response");
+ }
+ SingleResponse res[] = new SingleResponse[singleResponses.size()];
+
+ singleResponses.copyInto(res);
+
+ ResponderID rid = null;
+
+ if (mByName) {
+ rid = mOCSPAuthority.getResponderIDByName();
+ } else {
+ rid = mOCSPAuthority.getResponderIDByHash();
+ }
+
+ Extension nonce[] = null;
+
+ for (int j = 0; j < tbsReq.getExtensionsCount(); j++) {
+ Extension thisExt = tbsReq.getRequestExtensionAt(j);
+
+ if (thisExt.getExtnId().equals(IOCSPAuthority.OCSP_NONCE)) {
+ nonce = new Extension[1];
+ nonce[0] = thisExt;
+ }
+ }
+
+ ResponseData rd = new ResponseData(rid,
+ new GeneralizedTime(CMS.getCurrentDate()), res, nonce);
+ if (statsSub != null) {
+ statsSub.endTiming("build_response");
+ }
+
+ if (statsSub != null) {
+ statsSub.startTiming("signing");
+ }
+ long signStartTime = CMS.getCurrentDate().getTime();
+ BasicOCSPResponse basicRes = mOCSPAuthority.sign(rd);
+ long signEndTime = CMS.getCurrentDate().getTime();
+ if (statsSub != null) {
+ statsSub.endTiming("signing");
+ }
+ mOCSPAuthority.incSignTime(signEndTime - signStartTime);
+
+ OCSPResponse response = new OCSPResponse(
+ OCSPResponseStatus.SUCCESSFUL,
+ new ResponseBytes(ResponseBytes.OCSP_BASIC,
+ new OCTET_STRING(ASN1Util.encode(basicRes))));
+
+ log(ILogger.LL_INFO, "done OCSP request");
+ long endTime = CMS.getCurrentDate().getTime();
+ mOCSPAuthority.incTotalTime(endTime - startTime);
+ return response;
+ } catch (Exception e) {
+ CMS.debug("DefStore: validation failed " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_REQUEST_FAILURE", e.toString()));
+ return null;
+ }
+ }
+
+ /**
+ * Check against the database for status.
+ */
+ private SingleResponse processRequest(CertID cid) {
+ // need to find the right CA
+
+ CMS.debug("DefStore: process request");
+ try {
+ // cache result to speed up the performance
+ X509CertImpl theCert = null;
+ X509CRLImpl theCRL = null;
+ ICRLIssuingPointRecord theRec = null;
+ byte keyhsh[] = cid.getIssuerKeyHash().toByteArray();
+ CRLIPContainer matched = (CRLIPContainer)
+ mCacheCRLIssuingPoints.get(new String(keyhsh));
+
+ if (matched == null) {
+ Enumeration recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = (ICRLIssuingPointRecord)
+ recs.nextElement();
+ byte certdata[] = rec.getCACert();
+ X509CertImpl cert = null;
+
+ try {
+ cert = new X509CertImpl(certdata);
+ } catch (Exception e) {
+ // error
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_DECODE_CERT", e.toString()));
+ return null;
+ }
+ MessageDigest md = MessageDigest.getInstance(
+ mOCSPAuthority.getDigestName(cid.getHashAlgorithm()));
+ X509Key key = (X509Key) cert.getPublicKey();
+ byte digest[] = md.digest(key.getKey());
+
+ if (mOCSPAuthority.arraysEqual(digest, keyhsh)) {
+ theCert = cert;
+ theRec = rec;
+ incReqCount(theRec.getId());
+ byte crldata[] = rec.getCRL();
+
+ if (rec.getCRLCache() == null) {
+ CMS.debug("DefStore: start building x509 crl impl");
+ try {
+ theCRL = new X509CRLImpl(crldata);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_DECODE_CRL", e.toString()));
+ }
+ CMS.debug("DefStore: done building x509 crl impl");
+ } else {
+ CMS.debug("DefStore: using crl cache");
+ }
+ mCacheCRLIssuingPoints.put(new String(digest), new CRLIPContainer(theRec, theCert, theCRL));
+ break;
+ }
+ }
+ } else {
+ theCert = matched.getX509CertImpl();
+ theRec = matched.getCRLIssuingPointRecord();
+ theCRL = matched.getX509CRLImpl();
+ incReqCount(theRec.getId());
+ }
+
+ // check the serial number
+ if (theCert != null) {
+ INTEGER serialNo = cid.getSerialNumber();
+
+ log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Checked Status of certificate 0x" + serialNo.toString(16));
+ CMS.debug("DefStore: process request 0x" + serialNo.toString(16));
+ CertStatus certStatus = null;
+ GeneralizedTime thisUpdate = null;
+
+ if (theRec == null) {
+ thisUpdate = new GeneralizedTime(CMS.getCurrentDate());
+ } else {
+ thisUpdate = new GeneralizedTime(
+ theRec.getThisUpdate());
+ }
+ GeneralizedTime nextUpdate = null;
+
+ if (includeNextUpdate()) {
+ // this is an optional field
+ if (theRec == null) {
+ nextUpdate = new GeneralizedTime(CMS.getCurrentDate());
+ } else {
+ nextUpdate = new GeneralizedTime(
+ theRec.getNextUpdate());
+ }
+ }
+
+ if (theCRL == null) {
+ certStatus = new UnknownInfo();
+
+ // if crl is not available, we can try crl cache
+ if (theRec != null) {
+ CMS.debug("DefStore: evaluating crl cache");
+ Hashtable cache = theRec.getCRLCacheNoClone();
+ if (cache != null) {
+ RevokedCertificate rc = (RevokedCertificate)
+ cache.get(new BigInteger(serialNo.toString()));
+ if (rc == null) {
+ if (isNotFoundGood()) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } else {
+
+ certStatus = new RevokedInfo(
+ new GeneralizedTime(
+ rc.getRevocationDate()));
+ }
+ }
+ }
+
+ } else {
+ CMS.debug("DefStore: evaluating x509 crl impl");
+ X509CRLEntry crlentry = theCRL.getRevokedCertificate(new BigInteger(serialNo.toString()));
+
+ if (crlentry == null) {
+ // good or unknown
+ if (isNotFoundGood()) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } else {
+ certStatus = new RevokedInfo(new GeneralizedTime(
+ crlentry.getRevocationDate()));
+
+ }
+ }
+ return new SingleResponse(cid, certStatus, thisUpdate,
+ nextUpdate);
+ }
+ } catch (Exception e) {
+ // error log
+ CMS.debug("DefStore: failed processing request e=" + e);
+ }
+ return null;
+ }
+
+ private String transformDN(String dn) {
+ String newdn = dn;
+
+ newdn = newdn.replace(',', '_');
+ newdn = newdn.replace('=', '-');
+ return newdn;
+ }
+
+ public String getBaseDN() {
+ return mDBService.getBaseDN();
+ }
+
+ public Enumeration searchAllCRLIssuingPointRecord(int maxSize)
+ throws EBaseException {
+ return searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ maxSize);
+ }
+
+ public Enumeration searchCRLIssuingPointRecord(String filter,
+ int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getBaseDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public synchronized void modifyCRLIssuingPointRecord(String name,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.modify(dn, mods);
+ } catch (EBaseException e) {
+ CMS.debug("modifyCRLIssuingPointRecord: error=" + e);
+ CMS.debug(e);
+ throw e;
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Returns an issuing point.
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPoint(String name)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ ICRLIssuingPointRecord rec = null;
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ if (s != null) {
+ rec = (ICRLIssuingPointRecord) s.read(dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(
+ String name, BigInteger crlNumber,
+ Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return CMS.createCRLIssuingPointRecord(
+ name, crlNumber, crlSize, thisUpdate, nextUpdate);
+ }
+
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException {
+
+ IDBSSession s = null;
+
+ try {
+ s = mDBService.createSession();
+ String name = "cn=" + transformDN(id) + "," + getBaseDN();
+ CMS.debug("DefStore::deleteCRLIssuingPointRecord: Attempting to delete: " + name);
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addCRLIssuingPoint(String name, ICRLIssuingPointRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, (ICRLIssuingPointRecord) rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public Enumeration searchRepository(String name, String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search("cn=" + transformDN(name) + "," + getBaseDN(),
+ filter);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addRepository(String name, String thisUpdate,
+ IRepositoryRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "ou=" + thisUpdate + ",cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public void modifyCertRecord(String name, String thisUpdate,
+ String sno,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ if (s != null) s.modify(dn, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public Enumeration searchCertRecord(String name, String thisUpdate,
+ String filter) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search("ou=" + thisUpdate + ",cn=" +
+ transformDN(name) + "," + getBaseDN(),
+ filter);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public ICertRecord readCertRecord(String name, String thisUpdate,
+ String sno)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ ICertRecord rec = null;
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ if (s != null) {
+ rec = (ICertRecord) s.read(dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addCertRecord(String name, String thisUpdate,
+ String sno, ICertRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public NameValuePairs getConfigParameters() {
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_OCSPSTORE_IMPL_NAME,
+ mConfig.getString("class"));
+ params.add(PROP_NOT_FOUND_GOOD,
+ mConfig.getString(PROP_NOT_FOUND_GOOD, "true"));
+ params.add(PROP_BY_NAME,
+ mConfig.getString(PROP_BY_NAME, "true"));
+ params.add(PROP_INCLUDE_NEXT_UPDATE,
+ mConfig.getString(PROP_INCLUDE_NEXT_UPDATE, "false"));
+ return params;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void setConfigParameters(NameValuePairs pairs)
+ throws EBaseException {
+ Enumeration k = pairs.getNames();
+
+ while (k.hasMoreElements()) {
+ String key = (String) k.nextElement();
+
+ mConfig.put(key, pairs.getValue(key));
+ }
+ }
+
+ public void updateCRL(X509CRL crl) throws EBaseException {
+ try {
+ mStateCount++;
+
+ CMS.debug("DefStore: Ready to update Issuer");
+
+ try {
+ if (!((X509CRLImpl)crl).areEntriesIncluded())
+ crl = new X509CRLImpl(((X509CRLImpl)crl).getEncoded());
+ } catch (Exception e) {
+ CMS.debug(e);
+ }
+
+ // commit update
+ ModificationSet mods = new ModificationSet();
+
+ if (crl.getThisUpdate() != null)
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, crl.getThisUpdate());
+ if (crl.getNextUpdate() != null)
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, crl.getNextUpdate());
+ if (mUseCache) {
+ if (((X509CRLImpl)crl).getListOfRevokedCertificates() != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_CACHE,
+ Modification.MOD_REPLACE,
+ ((X509CRLImpl)crl).getListOfRevokedCertificates());
+ }
+ }
+ if (((X509CRLImpl) crl).getNumberOfRevokedCertificates() < 0) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, Long.valueOf(0));
+ } else {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, Long.valueOf(((X509CRLImpl) crl).getNumberOfRevokedCertificates()));
+ }
+ BigInteger crlNumber = ((X509CRLImpl)crl).getCRLNumber();
+ if (crlNumber == null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, new BigInteger("-1"));
+ } else {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ }
+ try {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, crl.getEncoded());
+ } catch (Exception e) {
+ // ignore
+ }
+ CMS.debug("DefStore: ready to CRL update " +
+ crl.getIssuerDN().getName());
+ modifyCRLIssuingPointRecord(
+ crl.getIssuerDN().getName(), mods);
+ CMS.debug("DefStore: done CRL update " +
+ crl.getIssuerDN().getName());
+
+ // update cache
+ mCacheCRLIssuingPoints.clear();
+
+ log(ILogger.LL_INFO, "AddCRLServlet: Finish Committing CRL." +
+ " thisUpdate=" + crl.getThisUpdate() +
+ " nextUpdate=" + crl.getNextUpdate());
+
+ } finally {
+ mStateCount--;
+ }
+ }
+
+ public int getStateCount() {
+ return mStateCount;
+ }
+
+}
+
+
+class DeleteOldCRLsThread extends Thread {
+ private DefStore mDefStore = null;
+
+ public DeleteOldCRLsThread(DefStore defStore) {
+ mDefStore = defStore;
+ }
+
+ public void run() {
+ try {
+ mDefStore.deleteOldCRLs();
+ } catch (EBaseException e) {
+ }
+ }
+}
+
+
+class CRLIPContainer {
+ private ICRLIssuingPointRecord mRec = null;
+ private X509CertImpl mCert = null;
+ private X509CRLImpl mCRL = null;
+
+ public CRLIPContainer(ICRLIssuingPointRecord rec, X509CertImpl cert, X509CRLImpl crl) {
+ mRec = rec;
+ mCert = cert;
+ mCRL = crl;
+ }
+
+ public ICRLIssuingPointRecord getCRLIssuingPointRecord() {
+ return mRec;
+ }
+
+ public X509CertImpl getX509CertImpl() {
+ return mCert;
+ }
+
+ public X509CRLImpl getX509CRLImpl() {
+ return mCRL;
+ }
+}
+
+class DefStoreCRLUpdater extends Thread {
+ private Hashtable mCache = null;
+ private int mSec = 0;
+
+ public DefStoreCRLUpdater(Hashtable cache, int sec) {
+ mCache = cache;
+ mSec = sec;
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ CMS.debug("DefStore: CRLUpdater invoked");
+ mCache.clear();
+ sleep(mSec * 1000); // turn sec into millis-sec
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/ocsp/LDAPStore.java b/pki/base/common/src/com/netscape/cms/ocsp/LDAPStore.java
new file mode 100644
index 000000000..f3ffaf3fe
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/ocsp/LDAPStore.java
@@ -0,0 +1,724 @@
+// --- 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.ocsp;
+
+
+import netscape.ldap.*;
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.cmsutil.ocsp.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.cert.Extension;
+
+
+/**
+ * This is the LDAP OCSP store. It reads CA certificate and
+ * revocation list attributes from the CA entry.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LDAPStore implements IDefStore, IExtendedPluginInfo {
+ private static final String PROP_NUM_CONNS = "numConns";
+ private static final String PROP_REFRESH_IN_SEC = "refreshInSec";
+ private static final int DEF_REFRESH_IN_SEC = 60 * 60 * 24;
+ private static final String PROP_BASE_DN = "baseDN";
+ private static final String PROP_BY_NAME = "byName";
+ private static final String PROP_CONN_INFO = "connInfo";
+ private static final String PROP_CRL_ATTR = "crlAttr";
+ private static final String DEF_CRL_ATTR = "certificateRevocationList;binary";
+ private static final String PROP_CA_CERT_ATTR = "caCertAttr";
+ private static final String DEF_CA_CERT_ATTR = "cACertificate;binary";
+ private static final String PROP_HOST = "host";
+ private static final String PROP_PORT = "port";
+
+ private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood";
+ private final static String PROP_INCLUDE_NEXT_UPDATE =
+ "includeNextUpdate";
+
+ private IOCSPAuthority mOCSPAuthority = null;
+ private IConfigStore mConfig = null;
+ private String mId = null;
+ private String mCRLAttr = null;
+ private boolean mByName = true;
+ private String mCACertAttr = null;
+ protected Hashtable mReqCounts = new Hashtable();
+ private Hashtable mCRLs = new Hashtable();
+
+ /**
+ * Constructs the default store.
+ */
+ public LDAPStore() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_NOT_FOUND_GOOD + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_NOT_FOUND_GOOD"));
+ v.addElement(PROP_INCLUDE_NEXT_UPDATE + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_INCLUDE_NEXT_UPDATE"));
+ v.addElement(PROP_NUM_CONNS + ";number; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_NUM_CONNS"));
+ v.addElement(PROP_BY_NAME + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_BY_NAME"));
+ v.addElement(PROP_CRL_ATTR + ";string; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_CRL_ATTR"));
+ v.addElement(PROP_CA_CERT_ATTR + ";string; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_PROP_CA_CERT_ATTR"));
+ v.addElement(IExtendedPluginInfo.HELP_TEXT + "; " + CMS.getUserMessage(locale, "CMS_OCSP_LDAPSTORE_DESC"));
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN + ";configuration-ocspstores-ldapstore");
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ /**
+ * Fetch CA certificate and CRL from LDAP server.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOCSPAuthority = (IOCSPAuthority) owner;
+ mConfig = config;
+
+ mCRLAttr = mConfig.getString(PROP_CRL_ATTR, DEF_CRL_ATTR);
+ mCACertAttr = mConfig.getString(PROP_CA_CERT_ATTR,
+ DEF_CA_CERT_ATTR);
+ mByName = mConfig.getBoolean(PROP_BY_NAME, true);
+
+ }
+
+ /**
+ * Locates the CA certificate.
+ */
+ public X509CertImpl locateCACert(LDAPConnection conn, String baseDN)
+ throws EBaseException {
+ try {
+ LDAPSearchResults results = conn.search(baseDN,
+ LDAPv2.SCOPE_SUB, mCACertAttr + "=*",
+ null, false);
+
+ if (!results.hasMoreElements()) {
+ throw new EBaseException("error - no entry");
+ }
+ LDAPEntry entry = results.next();
+ LDAPAttribute crls = entry.getAttribute(mCACertAttr);
+ Enumeration vals = crls.getByteValues();
+
+ if (!vals.hasMoreElements()) {
+ throw new EBaseException("error - no values");
+ }
+ byte caCertData[] = (byte[]) vals.nextElement();
+ X509CertImpl caCert = new X509CertImpl(caCertData);
+
+ return caCert;
+ } catch (Exception e) {
+ CMS.debug("LDAPStore: locateCACert " + e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("OCSP_LOCATE_CA", e.toString()));
+ }
+ return null;
+ }
+
+ /**
+ * Locates the CRL.
+ */
+ public X509CRLImpl locateCRL(LDAPConnection conn, String baseDN)
+ throws EBaseException {
+ try {
+ LDAPSearchResults results = conn.search(baseDN,
+ LDAPv2.SCOPE_SUB, mCRLAttr + "=*",
+ null, false);
+
+ if (!results.hasMoreElements()) {
+ throw new EBaseException("error - no entry");
+ }
+ LDAPEntry entry = results.next();
+ LDAPAttribute crls = entry.getAttribute(mCRLAttr);
+ Enumeration vals = crls.getByteValues();
+
+ if (!vals.hasMoreElements()) {
+ throw new EBaseException("error - no values");
+ }
+ byte crlData[] = (byte[]) vals.nextElement();
+ X509CRLImpl crl = new X509CRLImpl(crlData);
+
+ return crl;
+ } catch (Exception e) {
+ CMS.debug("LDAPStore: locateCRL " + e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("OCSP_LOCATE_CRL", e.toString()));
+ }
+ return null;
+ }
+
+ public void updateCRLHash(X509CertImpl caCert, X509CRLImpl crl)
+ throws EBaseException {
+ X509CRLImpl oldCRL = (X509CRLImpl) mCRLs.get(caCert);
+
+ if (oldCRL != null) {
+ if (oldCRL.getThisUpdate().getTime() >=
+ crl.getThisUpdate().getTime()) {
+ log(ILogger.LL_INFO,
+ "LDAPStore: no update, received CRL is older than current CRL");
+ return; // no update
+ }
+ }
+ CMS.debug("Added '" + caCert.getSubjectDN().toString() + "' into CRL hash");
+ mCRLs.put(caCert, crl);
+ }
+
+ public void log(int level, String msg) {
+ mOCSPAuthority.log(level, msg);
+ }
+
+ public void startup() throws EBaseException {
+ int num = mConfig.getInteger(PROP_NUM_CONNS, 0);
+
+ for (int i = 0; i < num; i++) {
+ String host = mConfig.getString(PROP_HOST + Integer.toString(i), null);
+ int port = mConfig.getInteger(PROP_PORT + Integer.toString(i), 0);
+ LDAPConnection c = new LDAPConnection();
+
+ try {
+ c.connect(host, port);
+ } catch (LDAPException e) {
+ throw new EBaseException("LDAP " + e);
+ }
+ String baseDN = mConfig.getString(PROP_BASE_DN + Integer.toString(i), null);
+ CRLUpdater updater = new CRLUpdater(
+ this, c, baseDN,
+ mConfig.getInteger(PROP_REFRESH_IN_SEC + Integer.toString(i),
+ DEF_REFRESH_IN_SEC));
+
+ updater.start();
+ }
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Validate an OCSP request.
+ */
+ public OCSPResponse validate(OCSPRequest request)
+ throws EBaseException {
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+
+ mOCSPAuthority.incNumOCSPRequest(1);
+ long startTime = CMS.getCurrentDate().getTime();
+ try {
+ mOCSPAuthority.log(ILogger.LL_INFO, "start OCSP request");
+ TBSRequest tbsReq = request.getTBSRequest();
+
+ Vector singleResponses = new Vector();
+
+ if (statsSub != null) {
+ statsSub.startTiming("lookup");
+ }
+
+ long lookupStartTime = CMS.getCurrentDate().getTime();
+ for (int i = 0; i < tbsReq.getRequestCount(); i++) {
+ com.netscape.cmsutil.ocsp.Request req =
+ tbsReq.getRequestAt(i);
+ CertID cid = req.getCertID();
+ SingleResponse sr = processRequest(cid);
+
+ singleResponses.addElement(sr);
+ }
+ long lookupEndTime = CMS.getCurrentDate().getTime();
+ if (statsSub != null) {
+ statsSub.endTiming("lookup");
+ }
+ mOCSPAuthority.incLookupTime(lookupEndTime - lookupStartTime);
+
+ if (statsSub != null) {
+ statsSub.startTiming("build_response");
+ }
+ SingleResponse res[] = new SingleResponse[singleResponses.size()];
+
+ singleResponses.copyInto(res);
+
+ ResponderID rid = null;
+
+ if (mByName) {
+ rid = mOCSPAuthority.getResponderIDByName();
+ } else {
+ rid = mOCSPAuthority.getResponderIDByHash();
+ }
+
+ Extension nonce[] = null;
+
+ for (int j = 0; j < tbsReq.getExtensionsCount(); j++) {
+ Extension thisExt = tbsReq.getRequestExtensionAt(j);
+
+ if (thisExt.getExtnId().equals(IOCSPAuthority.OCSP_NONCE)) {
+ nonce = new Extension[1];
+ nonce[0] = thisExt;
+ }
+ }
+
+ ResponseData rd = new ResponseData(rid,
+ new GeneralizedTime(CMS.getCurrentDate()), res, nonce);
+ if (statsSub != null) {
+ statsSub.endTiming("build_response");
+ }
+
+ if (statsSub != null) {
+ statsSub.startTiming("signing");
+ }
+
+ long signStartTime = CMS.getCurrentDate().getTime();
+ BasicOCSPResponse basicRes = mOCSPAuthority.sign(rd);
+ long signEndTime = CMS.getCurrentDate().getTime();
+ mOCSPAuthority.incSignTime(signEndTime - signStartTime);
+ if (statsSub != null) {
+ statsSub.endTiming("signing");
+ }
+
+ OCSPResponse response = new OCSPResponse(
+ OCSPResponseStatus.SUCCESSFUL,
+ new ResponseBytes(ResponseBytes.OCSP_BASIC,
+ new OCTET_STRING(ASN1Util.encode(basicRes))));
+
+ log(ILogger.LL_INFO, "done OCSP request");
+ long endTime = CMS.getCurrentDate().getTime();
+ mOCSPAuthority.incTotalTime(endTime - startTime);
+ return response;
+ } catch (Exception e) {
+ CMS.debug("LDAPStore: validation " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_REQUEST_FAILURE", e.toString()));
+ return null;
+ }
+ }
+
+ public int getStateCount() {
+ return 0;
+ }
+
+ public long getReqCount(String id) {
+ Long c = (Long) mReqCounts.get(id);
+
+ if (c == null)
+ return 0;
+ else
+ return c.longValue();
+ }
+
+ public IRepositoryRecord createRepositoryRecord() {
+ return null;
+ }
+
+ public void addRepository(String name, String thisUpdate,
+ IRepositoryRecord rec)
+ throws EBaseException {
+ throw new EBaseException("NOT SUPPORTED");
+ }
+
+ public boolean waitOnCRLUpdate() {
+ return false;
+ }
+
+ public void updateCRL(X509CRL crl) throws EBaseException {
+ throw new EBaseException("NOT SUPPORTED");
+ }
+
+ public ICRLIssuingPointRecord readCRLIssuingPoint(String name)
+ throws EBaseException {
+ throw new EBaseException("NOT SUPPORTED");
+ }
+
+ public Enumeration searchAllCRLIssuingPointRecord(int maxSize)
+ throws EBaseException {
+ Vector recs = new Vector();
+ Enumeration keys = mCRLs.keys();
+
+ while (keys.hasMoreElements()) {
+ X509CertImpl caCert = (X509CertImpl) keys.nextElement();
+ X509CRLImpl crl = (X509CRLImpl) mCRLs.get(caCert);
+
+ recs.addElement(new TempCRLIssuingPointRecord(caCert, crl));
+ }
+ return recs.elements();
+ }
+
+ public Enumeration searchCRLIssuingPointRecord(String filter,
+ int maxSize)
+ throws EBaseException {
+ return null;
+ }
+
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(
+ String name, BigInteger crlNumber,
+ Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return null;
+ }
+
+ public void addCRLIssuingPoint(String name, ICRLIssuingPointRecord rec)
+ throws EBaseException {
+ throw new EBaseException("NOT SUPPORTED");
+ }
+
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException {
+ throw new EBaseException("NOT SUPPORTED");
+ }
+
+ public boolean isNotFoundGood() {
+ try {
+ return isNotFoundGood1();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public boolean includeNextUpdate() throws EBaseException {
+ return mConfig.getBoolean(PROP_INCLUDE_NEXT_UPDATE, false);
+ }
+
+ public boolean isNotFoundGood1() throws EBaseException {
+ return mConfig.getBoolean(PROP_NOT_FOUND_GOOD, true);
+ }
+
+ public void incReqCount(String id) {
+ mReqCounts.put(id, Long.valueOf(getReqCount(id) + 1));
+ }
+
+ /**
+ * Check against the database for status.
+ */
+ private SingleResponse processRequest(CertID cid) throws EBaseException {
+ // locate the right CRL
+ X509CertImpl theCert = null;
+ X509CRLImpl theCRL = null;
+
+ Enumeration caCerts = mCRLs.keys();
+
+ while (caCerts.hasMoreElements()) {
+ X509CertImpl caCert = (X509CertImpl) caCerts.nextElement();
+ MessageDigest md = null;
+
+ try {
+ md = MessageDigest.getInstance(
+ mOCSPAuthority.getDigestName(cid.getHashAlgorithm()));
+ } catch (Exception e) {
+ }
+ X509Key key = (X509Key) caCert.getPublicKey();
+
+ if( key == null ) {
+ System.out.println("LDAPStore::processRequest - key is null!");
+ return null;
+ }
+
+ byte digest[] = md.digest(key.getKey());
+ byte keyhsh[] = cid.getIssuerKeyHash().toByteArray();
+
+ if (mOCSPAuthority.arraysEqual(digest, keyhsh)) {
+ theCert = caCert;
+ incReqCount(caCert.getSubjectDN().toString());
+ theCRL = (X509CRLImpl) mCRLs.get(caCert);
+ break;
+ }
+ }
+
+ if (theCert == null) {
+ return null;
+ }
+
+ if (theCRL == null) {
+ return null;
+ }
+
+ GeneralizedTime thisUpdate = new GeneralizedTime(
+ theCRL.getThisUpdate());
+ GeneralizedTime nextUpdate = null;
+
+ if (includeNextUpdate()) {
+ nextUpdate = new GeneralizedTime(
+ theCRL.getNextUpdate());
+ }
+
+ CertStatus certStatus = null;
+ X509CRLEntry entry = theCRL.getRevokedCertificate(
+ cid.getSerialNumber());
+
+ if (entry == null) {
+ if (isNotFoundGood1()) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } else {
+ certStatus = new RevokedInfo(new GeneralizedTime(
+ entry.getRevocationDate()));
+ }
+
+ return new SingleResponse(cid, certStatus, thisUpdate, nextUpdate);
+ }
+
+ /**
+ * Provides configuration parameters.
+ */
+ public NameValuePairs getConfigParameters() {
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_OCSPSTORE_IMPL_NAME,
+ mConfig.getString("class"));
+ int num = mConfig.getInteger(PROP_NUM_CONNS, 0);
+
+ params.add(PROP_NUM_CONNS, Integer.toString(num));
+ for (int i = 0; i < num; i++) {
+ params.add(PROP_HOST + Integer.toString(i),
+ mConfig.getString(PROP_HOST +
+ Integer.toString(i), ""));
+ params.add(PROP_PORT + Integer.toString(i),
+ mConfig.getString(PROP_PORT +
+ Integer.toString(i), "389"));
+ params.add(PROP_BASE_DN + Integer.toString(i),
+ mConfig.getString(PROP_BASE_DN +
+ Integer.toString(i), ""));
+ params.add(PROP_REFRESH_IN_SEC + Integer.toString(i),
+ mConfig.getString(PROP_REFRESH_IN_SEC +
+ Integer.toString(i), Integer.toString(DEF_REFRESH_IN_SEC)));
+ }
+ params.add(PROP_BY_NAME,
+ mConfig.getString(PROP_BY_NAME, "true"));
+ params.add(PROP_CA_CERT_ATTR,
+ mConfig.getString(PROP_CA_CERT_ATTR, DEF_CA_CERT_ATTR));
+ params.add(PROP_CRL_ATTR,
+ mConfig.getString(PROP_CRL_ATTR, DEF_CRL_ATTR));
+ params.add(PROP_NOT_FOUND_GOOD,
+ mConfig.getString(PROP_NOT_FOUND_GOOD, "true"));
+ params.add(PROP_INCLUDE_NEXT_UPDATE,
+ mConfig.getString(PROP_INCLUDE_NEXT_UPDATE, "false"));
+ return params;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void setConfigParameters(NameValuePairs pairs)
+ throws EBaseException {
+ Enumeration k = pairs.getNames();
+
+ while (k.hasMoreElements()) {
+ String key = (String) k.nextElement();
+
+ mConfig.put(key, pairs.getValue(key));
+ }
+ }
+}
+
+
+class CRLUpdater extends Thread {
+ private LDAPConnection mC = null;
+ private String mBaseDN = null;
+ private int mSec = 0;
+ private LDAPStore mStore = null;
+
+ public CRLUpdater(LDAPStore store, LDAPConnection c,
+ String baseDN, int sec) {
+ mC = c;
+ mSec = sec;
+ mBaseDN = baseDN;
+ mStore = store;
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ LDAPConnection conn = mC;
+ CMS.debug("Started CRL Update '" + mBaseDN);
+ X509CertImpl caCert = mStore.locateCACert(conn, mBaseDN);
+ X509CRLImpl crl = mStore.locateCRL(conn, mBaseDN);
+
+ mStore.updateCRLHash(caCert, crl);
+ CMS.debug("Finished CRL Update - '" + mBaseDN);
+ sleep(mSec * 1000); // turn sec into millis-sec
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
+
+
+class TempCRLIssuingPointRecord implements ICRLIssuingPointRecord {
+ private X509CertImpl mCACert = null;
+ private X509CRLImpl mCRL = null;
+
+ TempCRLIssuingPointRecord(X509CertImpl caCert, X509CRLImpl crl) {
+ mCACert = caCert;
+ mCRL = crl;
+ }
+
+ public String getId() {
+ return mCACert.getSubjectDN().toString();
+ }
+
+ /**
+ * Retrieves CRL serial number.
+ */
+ public BigInteger getCRLNumber() {
+ return null;
+ }
+
+ /**
+ * Retrieves delta CRL serial number.
+ */
+ public BigInteger getDeltaCRLNumber() {
+ return null;
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getCRLSize() {
+ return Long.valueOf(mCRL.getNumberOfRevokedCertificates());
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getDeltaCRLSize() {
+ return Long.valueOf(-1);
+ }
+
+ /**
+ * Retrieves this update time.
+ */
+ public Date getThisUpdate() {
+ return mCRL.getThisUpdate();
+ }
+
+ /**
+ * Retrieves next update time.
+ */
+ public Date getNextUpdate() {
+ return mCRL.getNextUpdate();
+ }
+
+ public String getFirstUnsaved() {
+ return null;
+ }
+
+ public Hashtable getCRLCacheNoClone() {
+ return null;
+ }
+
+ public Hashtable getCRLCache() {
+ return null;
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getCRL() {
+ try {
+ return mCRL.getEncoded();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getDeltaCRL() {
+ return null;
+ }
+
+ public Vector getSplitTimes() {
+ return null;
+ }
+
+ public int isCRLIssuingPointInitialized() {
+ return 1;
+ }
+
+ public byte[] getCACert() {
+ try {
+ return mCACert.getEncoded();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves cache info of revoked certificates.
+ */
+ public Hashtable getRevokedCerts() {
+ return mCRL.getListOfRevokedCertificates();
+ }
+
+ /**
+ * Retrieves cache info of unrevoked certificates.
+ */
+ public Hashtable getUnrevokedCerts() {
+ return null;
+ }
+
+ /**
+ * Retrieves cache info of expired certificates.
+ */
+ public Hashtable getExpiredCerts() {
+ return null;
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return null;
+ }
+
+ public void set(String name, Object obj)throws EBaseException {
+ }
+
+ public Object get(String name) throws EBaseException {
+ return null;
+ }
+
+ public void delete(String name) throws EBaseException {
+
+ }
+
+ public Enumeration getElements() {
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/password/PasswordChecker.java b/pki/base/common/src/com/netscape/cms/password/PasswordChecker.java
new file mode 100644
index 000000000..6901abc34
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/password/PasswordChecker.java
@@ -0,0 +1,116 @@
+// --- 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.password;
+
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This class checks the given password if it meets the specific requirements.
+ * For example, it can also specify the format of the password which has to
+ * be 8 characters long and must be in alphanumeric.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PasswordChecker implements IPasswordCheck, IConfigPasswordCheck {
+
+ public static final int MIN_LEN = 8;
+
+ /**
+ * Default constructor.
+ */
+ public PasswordChecker() {
+ }
+
+ public boolean isGoodConfigPassword(String mPassword) {
+ if (mPassword == null || mPassword.length() == 0) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ "Empty Password");
+
+ return false;
+ } else if (mPassword.length() < MIN_LEN) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ "Minimium Length is " + MIN_LEN);
+
+ return false;
+ }
+ return true;
+ }
+
+ public String getConfigReason(String mPassword) {
+ if (mPassword == null || mPassword.length() == 0) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ "Empty Password");
+
+ return e.toString();
+ } else if (mPassword.length() < MIN_LEN) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ "Minimium Length is " + MIN_LEN);
+
+ return e.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the given password meets the quality requirement;
+ * otherwise returns false.
+ * @param mPassword The given password being checked.
+ * @return true if the password meets the quality requirement; otherwise
+ * returns false.
+ */
+ public boolean isGoodPassword(String mPassword) {
+ if (mPassword == null || mPassword.length() == 0) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ CMS.getUserMessage("CMS_PASSWORD_EMPTY_PASSWORD"));
+
+ return false;
+ } else if (mPassword.length() < MIN_LEN) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ CMS.getUserMessage("CMS_PASSWORD_INVALID_LEN", "" + MIN_LEN));
+
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns a reason if the password doesnt meet the quality requirement.
+ * @return string as a reason if the password quality requirement is not met.
+ */
+ public String getReason(String mPassword) {
+ if (mPassword == null || mPassword.length() == 0) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ CMS.getUserMessage("CMS_PASSWORD_EMPTY_PASSWORD"));
+
+ return e.toString();
+ } else if (mPassword.length() < MIN_LEN) {
+ EPasswordCheckException e = new EPasswordCheckException(
+ CMS.getUserMessage("CMS_PASSWORD_INVALID_LEN", "" + MIN_LEN));
+
+ return e.toString();
+ }
+ return null;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java b/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java
new file mode 100644
index 000000000..d0bd6a6bc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java
@@ -0,0 +1,354 @@
+// --- 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.policy;
+
+
+import java.util.*;
+import java.text.*;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import java.security.*;
+import java.security.cert.*;
+
+
+/**
+ * The abstract policy rule that concrete implementations will
+ * extend.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public abstract class APolicyRule implements IPolicyRule {
+ protected String NAME = null;
+ protected String DESC = null;
+ protected IExpression mFilterExp = null;
+ protected String mInstanceName = null;
+ protected ILogger mLogger = CMS.getLogger();
+
+ public APolicyRule() {
+ }
+
+ /**
+ * Initializes the policy rule.
+ * <P>
+ *
+ * @param config The config store reference
+ */
+ public abstract void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Gets the description for this policy rule.
+ * <P>
+ * @return The Description for this rule.
+ */
+ public String getDescription() {
+ return DESC;
+ }
+
+ /**
+ * Sets a predicate expression for rule matching.
+ * <P>
+ *
+ * @param exp The predicate expression for the rule.
+ */
+ public void setPredicate(IExpression exp) {
+ mFilterExp = exp;
+ }
+
+ /**
+ * Returns the predicate expression for the rule.
+ * <P>
+ *
+ * @return The predicate expression for the rule.
+ */
+ public IExpression getPredicate() {
+ return mFilterExp;
+ }
+
+ /**
+ * Returns the name of the policy rule.
+ * <P>
+ *
+ * @return The name of the policy class.
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Sets the instance name for a policy rule.
+ * <P>
+ *
+ * @param instanceName The name of the rule instance.
+ */
+ public void setInstanceName(String instanceName) {
+ mInstanceName = instanceName;
+ }
+
+ /**
+ * Returns the name of the policy rule instance.
+ * <P>
+ *
+ * @return The name of the policy rule instance if set, else
+ * the name of the rule class.
+ */
+ public String getInstanceName() {
+ return mInstanceName != null ? mInstanceName : NAME;
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public abstract PolicyResult apply(IRequest req);
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public abstract Vector getInstanceParams();
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public abstract Vector getDefaultParams();
+
+ public void setError(IRequest req, String format, Object[] params) {
+ setPolicyException(req, format, params);
+ }
+
+ public void setError(IRequest req, String format, String arg1,
+ String arg2) {
+ Object[] np = new Object[2];
+
+ np[0] = arg1;
+ np[1] = arg2;
+ setPolicyException(req, format, np);
+ }
+
+ public void setError(IRequest req, String format, String arg) {
+ Object[] np = new Object[1];
+
+ np[0] = arg;
+ setPolicyException(req, format, np);
+ }
+
+ public void setPolicyException(IRequest req, EBaseException ex) {
+ Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector();
+ }
+ ev.addElement(ex.toString());
+ req.setExtData(IRequest.ERRORS, ev);
+
+ }
+
+ /**
+ * determines whether a DEFERRED policy result should be returned
+ * by checking the contents of the AgentApprovals attribute. This
+ * call should be used by policy modules instead of returning
+ * PolicyResult.DEFERRED directly.
+ * <p>
+ */
+ protected PolicyResult deferred(IRequest req) {
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ return PolicyResult.DEFERRED;
+ }
+ }
+
+ /**
+ * request has previously been approved by an agent
+ */
+ protected boolean agentApproved(IRequest req) {
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void setPolicyException(IRequest req, String format,
+ Object[] params) {
+ if (format == null)
+ return;
+
+ EPolicyException ex;
+
+ if (params == null)
+ ex = new EPolicyException(format);
+ else
+ ex = new EPolicyException(format, params);
+
+ Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector();
+ }
+ ev.addElement(ex.toString());
+ req.setExtData(IRequest.ERRORS, ev);
+ }
+
+ /**
+ * log a message for this policy rule.
+ */
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level,
+ "APolicyRule " + NAME + ": " + msg);
+ }
+
+ public static KeyIdentifier createKeyIdentifier(X509Key key)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getEncoded());
+ return new KeyIdentifier(md.digest());
+ }
+
+ /**
+ * Form a byte array of octet string key identifier from the sha-1 hash of
+ * the Subject Public Key INFO. (including algorithm ID, etc.)
+ * <p>
+ * @param certInfo cert info of the certificate.
+ * @return A Key identifier with the sha-1 hash of subject public key.
+ */
+ protected KeyIdentifier formSpkiSHA1KeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ keyId = createKeyIdentifier(key);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+
+ /**
+ * Form a byte array of octet string key identifier from the sha-1 hash of
+ * the Subject Public Key BIT STRING.
+ * <p>
+ * @param certInfo cert info of the certificate.
+ * @return A Key identifier with the sha-1 hash of subject public key.
+ */
+ protected KeyIdentifier formSHA1KeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ byte[] rawKey = key.getKey();
+
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(rawKey);
+ keyId = new KeyIdentifier(md.digest());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java b/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java
new file mode 100644
index 000000000..0702ef29c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java
@@ -0,0 +1,165 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * AgentPolicy is an enrollment policy wraps another policy module.
+ * Requests are sent first to the contained module, but if the
+ * policy indicates that the request should be deferred, a check
+ * for agent approvals is done. If any are found, the request
+ * is approved.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AgentPolicy extends APolicyRule
+ implements IEnrollmentPolicy {
+ public AgentPolicy() {
+ NAME = "AgentPolicy";
+ DESC = "Agent Approval Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=AgentPolicy
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ * ra.Policy.rule.<ruleName>.class=xxxx
+ * ra.Policy.rule.<ruleName>.params.*
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Create subordinate object
+ String className = (String) config.get("class");
+
+ System.err.println("Creating agent policy with class " + className);
+ if (className != null) {
+ IConfigStore substore = config.getSubStore("params");
+
+ try {
+ Class c = Class.forName(className);
+
+ Object o = c.newInstance();
+
+ if (!(o instanceof APolicyRule)) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CLASS",
+ getInstanceName(), className));
+ }
+
+ APolicyRule pr = (APolicyRule) o;
+
+ pr.init(owner, substore);
+ mPolicy = pr;
+ } catch (EPolicyException e) {
+ System.err.println("Agent Policy Error: " + e);
+ throw e;
+ } catch (Exception e) {
+ System.err.println("Agent Policy Error: " + e);
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_LOADING_POLICY_ERROR",
+ getInstanceName(), className));
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // The default is to require manual approval for everything
+ PolicyResult result = PolicyResult.DEFERRED;
+
+ // Give the underlying object a chance
+ if (mPolicy != null) {
+ result = mPolicy.apply(req);
+ System.err.println("Subordinate policy returns " + result);
+ }
+
+ if (result == PolicyResult.DEFERRED) {
+ System.err.println("Checking agent approvals");
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ //Object o = req.get("agentApprovals");
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) //if (o != null)
+ {
+ System.err.println("Agent approval found");
+ result = PolicyResult.ACCEPTED;
+ }
+ }
+ System.err.println("Agent policy returns " + result);
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+
+ APolicyRule mPolicy = null;
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
new file mode 100644
index 000000000..3410c7baa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
@@ -0,0 +1,401 @@
+// --- 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.policy.constraints;
+
+
+import java.io.File;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.notification.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.common.*;
+import java.text.DateFormat;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This checks if attribute present.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AttributePresentConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_ENABLED = "enabled";
+ protected static final String PROP_LDAP = "ldap";
+
+ protected String mName = null;
+ protected String mImplName = null;
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private Hashtable mContentParams = new Hashtable();
+
+ private ICertAuthority mSub = null;
+ private IConfigStore mConfig = null;
+ private IConfigStore mLdapConfig = null;
+ private RequestId mReqId = null;
+ private ILdapConnFactory mConnFactory = null;
+ private LDAPConnection mCheckAttrLdapConnection = null;
+
+ public AttributePresentConstraints() {
+ DESC = "Rejects request if ldap attribute is not present in the " +
+ "directory.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ PROP_ATTR + ";string,required;Ldap attribute to check presence of (default " +
+ DEF_ATTR + ")",
+ PROP_VALUE + ";string;if this parameter is non-empty, the attribute must " +
+ "match this value for the request to proceed ",
+ PROP_LDAP_BASE + ";string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here",
+ PROP_LDAP_HOST + ";string,required;" +
+ "LDAP host to connect to",
+ PROP_LDAP_PORT + ";number,required;" +
+ "LDAP port number (use 389, or 636 if SSL)",
+ PROP_LDAP_SSL + ";boolean;" +
+ "Use SSL to connect to directory?",
+ PROP_LDAP_VER + ";choice(3,2),required;" +
+ "LDAP protocol version",
+ PROP_LDAP_BIND + ";string;DN to bind as for attribute checking. " +
+ "For example 'CN=Pincheck User'",
+ PROP_LDAP_PW + ";password;Enter password used to bind as " +
+ "the above user",
+ PROP_LDAP_AUTH + ";choice(BasicAuth,SslClientAuth),required;" +
+ "How to bind to the directory",
+ PROP_LDAP_CERT + ";string;If you want to use " +
+ "SSL client auth to the directory, set the client " +
+ "cert nickname here",
+ PROP_LDAP_BASE + ";string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here",
+ PROP_LDAP_MINC + ";number;number of connections " +
+ "to keep open to directory server. Default " + DEF_LDAP_MINC,
+ PROP_LDAP_MAXC + ";number;when needed, connection " +
+ "pool can grow to this many (multiplexed) connections. Default " + DEF_LDAP_MAXC,
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-pinpresent",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";" + DESC + " This plugin can be used to " +
+ "check the presence (and, optionally, the value) of any LDAP " +
+ "attribute for the user. "
+ };
+
+ return params;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getImplName() {
+ return mImplName;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void shutdown() {
+ }
+
+ // Parameters
+
+ protected static final String PROP_LDAP_HOST = "ldap.ldapconn.host";
+ protected static final String DEF_LDAP_HOST = "localhost";
+
+ protected static final String PROP_LDAP_PORT = "ldap.ldapconn.port";
+ protected static final Integer DEF_LDAP_PORT = Integer.valueOf(389);
+
+ protected static final String PROP_LDAP_SSL = "ldap.ldapconn.secureConn";
+ protected static final Boolean DEF_LDAP_SSL = Boolean.FALSE;
+
+ protected static final String PROP_LDAP_VER = "ldap.ldapconn.version";
+ protected static final Integer DEF_LDAP_VER = Integer.valueOf(3);
+
+ protected static final String PROP_LDAP_BIND = "ldap.ldapauth.bindDN";
+ protected static final String DEF_LDAP_BIND = "CN=Directory Manager";
+
+ protected static final String PROP_LDAP_PW = "ldap.ldapauth.bindPWPrompt";
+ protected static final String DEF_LDAP_PW = "";
+
+ protected static final String PROP_LDAP_CERT = "ldap.ldapauth.clientCertNickname";
+ protected static final String DEF_LDAP_CERT = "";
+
+ protected static final String PROP_LDAP_AUTH = "ldap.ldapauth.authtype";
+ protected static final String DEF_LDAP_AUTH = "BasicAuth";
+
+ protected static final String PROP_LDAP_BASE = "ldap.ldapconn.basedn";
+ protected static final String DEF_LDAP_BASE = "";
+
+ protected static final String PROP_LDAP_MINC = "ldap.ldapconn.minConns";
+ protected static final Integer DEF_LDAP_MINC = Integer.valueOf(1);
+
+ protected static final String PROP_LDAP_MAXC = "ldap.ldapconn.maxConns";
+ protected static final Integer DEF_LDAP_MAXC = Integer.valueOf(5);
+
+ protected static final String PROP_ATTR = "attribute";
+ protected static final String DEF_ATTR = "pin";
+
+ protected static final String PROP_VALUE = "value";
+ protected static final String DEF_VALUE = "";
+
+ protected static Vector mParamNames;
+ protected static Hashtable mParamDefault;
+ protected Hashtable mParamValue = null;
+
+ static {
+ mParamNames = new Vector();
+ mParamDefault = new Hashtable();
+ addParam(PROP_LDAP_HOST, DEF_LDAP_HOST);
+ addParam(PROP_LDAP_PORT, DEF_LDAP_PORT);
+ addParam(PROP_LDAP_SSL, DEF_LDAP_SSL);
+ addParam(PROP_LDAP_VER, DEF_LDAP_VER);
+ addParam(PROP_LDAP_BIND, DEF_LDAP_BIND);
+ addParam(PROP_LDAP_PW, DEF_LDAP_PW);
+ addParam(PROP_LDAP_CERT, DEF_LDAP_CERT);
+ addParam(PROP_LDAP_AUTH, DEF_LDAP_AUTH);
+ addParam(PROP_LDAP_BASE, DEF_LDAP_BASE);
+ addParam(PROP_LDAP_MINC, DEF_LDAP_MINC);
+ addParam(PROP_LDAP_MAXC, DEF_LDAP_MAXC);
+ addParam(PROP_ATTR, DEF_ATTR);
+ addParam(PROP_VALUE, DEF_VALUE);
+ };
+
+ protected static void addParam(String name, Object value) {
+ mParamNames.addElement(name);
+ mParamDefault.put(name, value);
+ }
+
+ protected void getStringConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, config.getString(paramName, (String) mParamDefault.get(paramName))
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ protected void getIntConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, Integer.valueOf(
+ config.getInteger(paramName,
+ ((Integer) mParamDefault.get(paramName)).intValue()
+ )
+ )
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ protected void getBooleanConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, Boolean.valueOf(
+ config.getBoolean(paramName,
+ ((Boolean) mParamDefault.get(paramName)).booleanValue()
+ )
+ )
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mParamValue = new Hashtable();
+
+ getStringConfigParam(mConfig, PROP_LDAP_HOST);
+ getIntConfigParam(mConfig, PROP_LDAP_PORT);
+ getBooleanConfigParam(mConfig, PROP_LDAP_SSL);
+ getIntConfigParam(mConfig, PROP_LDAP_VER);
+ getStringConfigParam(mConfig, PROP_LDAP_BIND);
+ getStringConfigParam(mConfig, PROP_LDAP_PW);
+ getStringConfigParam(mConfig, PROP_LDAP_CERT);
+ getStringConfigParam(mConfig, PROP_LDAP_AUTH);
+ getStringConfigParam(mConfig, PROP_LDAP_BASE);
+ getIntConfigParam(mConfig, PROP_LDAP_MINC);
+ getIntConfigParam(mConfig, PROP_LDAP_MAXC);
+ getStringConfigParam(mConfig, PROP_ATTR);
+ getStringConfigParam(mConfig, PROP_VALUE);
+
+ mLdapConfig = mConfig.getSubStore(PROP_LDAP);
+
+ mConnFactory = CMS.getLdapBoundConnFactory();
+ mConnFactory.init(mLdapConfig);
+ mCheckAttrLdapConnection = mConnFactory.getConn();
+
+ }
+
+ public PolicyResult apply(IRequest r) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ mReqId = r.getRequestId();
+
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.ENROLLMENT_REQUEST) ||
+ requestType.equals(IRequest.RENEWAL_REQUEST)) {
+
+ String uid = r.getExtDataInString(IRequest.HTTP_PARAMS, "uid");
+
+ if (uid == null) {
+ log(ILogger.LL_INFO, "did not find UID parameter in request " + r.getRequestId());
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ String userdn = null;
+
+ try {
+ String[] attrs = { (String) mParamValue.get(PROP_ATTR) };
+ LDAPSearchResults searchResult =
+ mCheckAttrLdapConnection.search((String) mParamValue.get(PROP_LDAP_BASE),
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", attrs, false);
+
+ if (!searchResult.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", uid));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ LDAPEntry entry = (LDAPEntry) searchResult.nextElement();
+
+ userdn = entry.getDN();
+
+ LDAPAttribute attr = entry.getAttribute((String) mParamValue.get(PROP_ATTR));
+
+ /* if attribute not present, reject the request */
+ if (attr == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", userdn));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+ String acceptedValue = ((String) mParamValue.get(PROP_VALUE));
+
+ if (!acceptedValue.equals("")) {
+ int matches = 0;
+
+ String[] values = attr.getStringValueArray();
+
+ for (int i = 0; i < values.length; i++) {
+ if (values[i].equals(acceptedValue)) {
+ matches++;
+ }
+ }
+ if (matches == 0) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", userdn));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ CMS.debug("AttributePresentConstraints: Attribute is present for user: \"" + userdn + "\"");
+
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_PIN_UNAUTHORIZED"));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ }
+ return res;
+ }
+
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ Enumeration e = mParamNames.elements();
+
+ while (e.hasMoreElements()) {
+ try {
+ String paramName = (String) e.nextElement();
+ String paramValue = mParamValue.get(paramName).toString();
+ String temp = paramName + "=" + paramValue;
+
+ params.addElement(temp);
+ } catch (Exception ex) {
+ }
+ }
+
+ return params;
+ }
+
+ public Vector getDefaultParams() {
+ Vector params = new Vector();
+
+ Enumeration e = mParamNames.elements();
+
+ while (e.hasMoreElements()) {
+ try {
+ String paramName = (String) e.nextElement();
+ String paramValue = mParamDefault.get(paramName).toString();
+ String temp = paramName + "=" + paramValue;
+
+ params.addElement(temp);
+ } catch (Exception ex) {
+ }
+ }
+
+ return params;
+
+ /*
+ params.addElement("ldap.ldapconn.host=localhost");
+ params.addElement("ldap.ldapconn.port=389");
+ params.addElement("ldap.ldapconn.secureConn=false");
+ params.addElement("ldap.ldapconn.version=3");
+ params.addElement("ldap.ldapauth.bindDN=CN=Directory Manager");
+ params.addElement("ldap.ldapauth.bindPWPrompt=");
+ params.addElement("ldap.ldapauth.clientCertNickname=");
+ params.addElement("ldap.ldapauth.authtype=BasicAuth");
+ params.addElement("ldap.basedn=");
+ params.addElement("ldap.minConns=1");
+ params.addElement("ldap.maxConns=5");
+ */
+ }
+
+ protected void log(int level, String msg) {
+ if (mLogger == null) return;
+
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "AttributePresentConstraints: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java
new file mode 100644
index 000000000..4623826f0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java
@@ -0,0 +1,249 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.provider.DSAPublicKey;
+import java.security.interfaces.DSAParams;
+import java.math.BigInteger;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * DSAKeyConstraints policy enforces min and max size of the key.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class DSAKeyConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private int mMinSize;
+ private int mMaxSize;
+
+ private final static int INCREMENT = 64;
+ private final static int DEF_MIN_SIZE = 512;
+ private final static int DEF_MAX_SIZE = 1024;
+
+ private final static String DSA = "DSA";
+ private final static String PROP_MIN_SIZE = "minSize";
+ private final static String PROP_MAX_SIZE = "maxSize";
+
+ private final static Vector defConfParams = new Vector();
+
+ private IConfigStore mConfig = null;
+
+ static {
+ defConfParams.addElement(PROP_MIN_SIZE + "=" + DEF_MIN_SIZE);
+ defConfParams.addElement(PROP_MAX_SIZE + "=" + DEF_MAX_SIZE);
+ }
+
+ public DSAKeyConstraints() {
+ NAME = "DSAKeyConstraints";
+ DESC = "Enforces DSA Key Constraints.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_SIZE + ";number;Minimum key size",
+ PROP_MAX_SIZE + ";number;Maximum key size",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-dsakeyconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects request if DSA key size is out of range"
+ };
+
+ return params;
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=DSAKeyConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minSize=512
+ * ra.Policy.rule.<ruleName>.maxSize=1024
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get Min and Max sizes
+ mConfig = config;
+
+ try {
+ mMinSize = config.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE);
+ mMaxSize = config.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE);
+
+ if (mMaxSize > DEF_MAX_SIZE) {
+ String msg = "cannot be more than " + DEF_MAX_SIZE;
+
+ log(ILogger.LL_FAILURE, PROP_MAX_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MAX_SIZE, msg));
+ }
+ if (mMinSize < DEF_MIN_SIZE) {
+ String msg = "cannot be less than " + DEF_MIN_SIZE;
+
+ log(ILogger.LL_FAILURE, PROP_MIN_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+ if (mMaxSize % INCREMENT != 0) {
+ String msg = "must be in increments of " + INCREMENT;
+
+ log(ILogger.LL_FAILURE, PROP_MAX_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+ if (mMaxSize % INCREMENT != 0) {
+ String msg = "must be in increments of " + INCREMENT;
+
+ log(ILogger.LL_FAILURE, PROP_MIN_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+
+ config.putInteger(PROP_MIN_SIZE, mMinSize);
+ config.putInteger(PROP_MAX_SIZE, mMaxSize);
+
+ } catch (Exception e) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", getInstanceName(), e.toString()));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo ci[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key size(s) are within the limit.
+ for (int i = 0; i < ci.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ ci[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().toString();
+
+ if (!alg.equalsIgnoreCase(DSA))
+ continue;
+
+ // Check DSAKey parameters.
+ // size refers to the p parameter.
+ DSAPublicKey dsaKey = new DSAPublicKey(key.getEncoded());
+ DSAParams keyParams = dsaKey.getParams();
+
+ if (keyParams == null) {
+ // key parameters could not be parsed.
+ Object[] params = new Object[] {
+ getInstanceName(), String.valueOf(i + 1) };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_KEY_PARAMS", getInstanceName(), String.valueOf(i + 1)), "");
+ return PolicyResult.REJECTED;
+ }
+ BigInteger p = keyParams.getP();
+ int len = p.bitLength();
+
+ if (len < mMinSize || len > mMaxSize ||
+ (len % INCREMENT) != 0) {
+ String[] parms = new String[] {
+ getInstanceName(),
+ String.valueOf(len),
+ String.valueOf(mMinSize),
+ String.valueOf(mMaxSize),
+ String.valueOf(INCREMENT) };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_SIZE_VIOLATION_1", parms), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = { getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ try {
+ confParams.addElement(PROP_MIN_SIZE + "=" + mConfig.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE));
+ confParams.addElement(PROP_MAX_SIZE + "=" + mConfig.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE));
+ } catch (EBaseException e) {;
+ }
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java b/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java
new file mode 100644
index 000000000..8fca9a2fa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java
@@ -0,0 +1,105 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This is the default revocation policy. Currently this does
+ * nothing. We can later add checks like whether or not to
+ * revoke expired certs ..etc here.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class DefaultRevocation extends APolicyRule
+ implements IRevocationPolicy, IExtendedPluginInfo {
+ public DefaultRevocation() {
+ NAME = "DefaultRevocation";
+ DESC = "Default Revocation Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=DefaultRevocation
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-defaultrevocation"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java
new file mode 100644
index 000000000..5746a3b21
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java
@@ -0,0 +1,207 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * IssuerConstraints is a rule for restricting the issuers of the
+ * certificates used for certificate-based enrollments.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class IssuerConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private final static String PROP_ISSUER_DN = "issuerDN";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+ private X500Name mIssuerDN = null;
+ private String mIssuerDNString;
+
+ /**
+ * checks the issuer of the ssl client-auth cert. Only one issuer
+ * is allowed for now
+ */
+ public IssuerConstraints() {
+ NAME = "IssuerConstraints";
+ DESC = "Checks to see if the Issuer is one allowed";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ISSUER_DN + ";string;Subject DN of the Issuer. The IssuerDN of the authenticating cert must match what's specified here",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-issuerconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects the request if the issuer in the certificate is" +
+ "not of the one specified"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ try {
+ mIssuerDNString = config.getString(PROP_ISSUER_DN, null);
+ if ((mIssuerDNString != null) &&
+ !mIssuerDNString.equals("")) {
+ mIssuerDN = new X500Name(mIssuerDNString);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ NAME + CMS.getLogMessage("CA_GET_ISSUER_NAME_FAILED"));
+
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ CMS.debug(
+ NAME + ": init() done");
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ if (mIssuerDN == null)
+ return result;
+
+ try {
+ String clientIssuerDN = req.getExtDataInString(CLIENT_ISSUER);
+
+ if (clientIssuerDN != null) {
+ X500Name ci_name = new X500Name(clientIssuerDN);
+
+ if (!ci_name.equals(mIssuerDN)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_INVALID_ISSUER",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_GET_ISSUER_NAME_FAILED"));
+ CMS.debug(
+ NAME + ": apply() - issuerDN mismatch: client issuerDN = " + clientIssuerDN + "; expected issuerDN = " + mIssuerDNString);
+ }
+ } else {
+
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - missing certInfo");
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < certInfo.length; i++) {
+ String oldIssuer = (String)
+ certInfo[i].get(X509CertInfo.ISSUER).toString();
+
+ if (oldIssuer == null) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CLIENT_ISSUER_NOT_FOUND",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - client issuerDN not found");
+ }
+ X500Name oi_name = new X500Name(oldIssuer);
+
+ if (!oi_name.equals(mIssuerDN)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_INVALID_ISSUER",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - cert issuerDN mismatch: client issuerDN = " + oldIssuer + "; expected issuerDN = " + mIssuerDNString);
+ }
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+
+ if (result.equals(PolicyResult.ACCEPTED)) {
+ log(ILogger.LL_INFO,
+ NAME + ": apply() - accepted");
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_ISSUER_DN + "=" +
+ mIssuerDNString);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_ISSUER_DN + "=");
+ return defParams;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
new file mode 100644
index 000000000..181752b01
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
@@ -0,0 +1,221 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * KeyAlgorithmConstraints enforces a constraint that the RA or a CA
+ * honor only the keys generated using one of the permitted algorithms
+ * such as RSA, DSA or DH.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class KeyAlgorithmConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private Vector mAlgorithms;
+ private final static String DEF_KEY_ALGORITHM = "RSA,DSA";
+ private final static String PROP_ALGORITHMS = "algorithms";
+ private final static String[] supportedAlgorithms =
+ {"RSA", "DSA", "DH" };
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_ALGORITHMS + "=" +
+ DEF_KEY_ALGORITHM);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ "algorithms;choice(RSA\\,DSA,RSA,DSA);Certificate's key can be one of these algorithms",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-keyalgorithmconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects the request if the key in the certificate is " +
+ "not of the type specified"
+ };
+
+ return params;
+ }
+
+ public KeyAlgorithmConstraints() {
+ NAME = "KeyAlgorithmConstraints";
+ DESC = "Enforces Key Algorithm Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=KeyAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=RSA,DSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ mAlgorithms = new Vector();
+
+ if (config == null || config.size() == 0) {
+ mAlgorithms.addElement(DEF_KEY_ALGORITHM);
+ return;
+ }
+
+ // Get Algorithm names
+ String algNames = null;
+
+ try {
+ algNames = config.getString(PROP_ALGORITHMS, null);
+ } catch (Exception e) {
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+
+ if (algNames == null) {
+ mAlgorithms.addElement(DEF_KEY_ALGORITHM);
+ return;
+ }
+ StringTokenizer tok = new StringTokenizer(algNames, ",");
+
+ while (tok.hasMoreTokens()) {
+ String alg = tok.nextToken().trim().toUpperCase();
+
+ if (alg.length() == 0)
+ continue;
+ mAlgorithms.addElement(alg);
+ }
+
+ // Check if configured algorithms are supported.
+ for (Enumeration e = mAlgorithms.elements();
+ e.hasMoreElements();) {
+ int i;
+ String configuredAlg = (String) e.nextElement();
+
+ // See if it is a supported algorithm.
+ for (i = 0; i < supportedAlgorithms.length; i++) {
+ if (configuredAlg.equals(supportedAlgorithms[i]))
+ break;
+ }
+
+ // Did we not find it?
+ if (i == supportedAlgorithms.length)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_UNSUPPORTED_KEY_ALG",
+ getInstanceName(), configuredAlg));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ // X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // We need to have a certificate info set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key algorithm is supported.
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ certInfo[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().getName().toUpperCase();
+
+ if (!mAlgorithms.contains(alg)) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_ALG_VIOLATION",
+ getInstanceName(), alg), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mAlgorithms.elements(); e.hasMoreElements();) {
+ sb.append((String) e.nextElement());
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ v.addElement(PROP_ALGORITHMS + "=" + sb.toString());
+ return v;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java b/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java
new file mode 100644
index 000000000..d88bb3c02
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java
@@ -0,0 +1,103 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * ManualAuthentication is an enrollment policy that queues
+ * all requests for issuing agent's approval if no authentication
+ * is present. The policy rejects a request if any of the auth tokens
+ * indicates authentication failure.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ManualAuthentication extends APolicyRule
+ implements IEnrollmentPolicy {
+ public ManualAuthentication() {
+ NAME = "ManualAuthentication";
+ DESC = "Manual Authentication Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ManualAuthentication
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ IAuthToken authToken = req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+
+ if (authToken == null)
+ return deferred(req);
+
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
new file mode 100644
index 000000000..b30e27901
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
@@ -0,0 +1,274 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * RSAKeyConstraints policy enforces min and max size of the key.
+ * Optionally checks the exponents.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RSAKeyConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private Vector mExponents;
+ private int mMinSize;
+ private int mMaxSize;
+
+ private final static int DEF_MIN_SIZE = 512;
+ private final static int DEF_MAX_SIZE = 2048;
+ private final static String PROP_MIN_SIZE = "minSize";
+ private final static String PROP_MAX_SIZE = "maxSize";
+ private final static String PROP_EXPONENTS = "exponents";
+ private final static String RSA = "RSA";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_SIZE + "=" + DEF_MIN_SIZE);
+ defConfParams.addElement(PROP_MAX_SIZE + "=" + DEF_MAX_SIZE);
+ defConfParams.addElement(PROP_EXPONENTS + "=" + " ");
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_SIZE + ";number;Minimum size of user's RSA key (bits)",
+ PROP_MAX_SIZE + ";number;Maximum size of user's RSA key (bits)",
+ PROP_EXPONENTS + ";string;Comma-separated list of permissible exponents",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-rsakeyconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Reject request if RSA key length is not within the " +
+ "specified constraints"
+ };
+
+ return params;
+ }
+
+ public RSAKeyConstraints() {
+ NAME = "RSAKeyConstraints";
+ DESC = "Enforces RSA Key Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=RSAKeyConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minSize=512
+ * ra.Policy.rule.<ruleName>.maxSize=2048
+ * ra.Policy.rule.<ruleName>.predicate=ou==Marketing
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ if (config == null || config.size() == 0)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_MISSING_POLICY_CONFIG",
+ getInstanceName()));
+ String exponents = null;
+
+ // Get Min and Max sizes
+ mMinSize = config.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE);
+ mMaxSize = config.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE);
+
+ if (mMinSize <= 0)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_MIN_SIZE));
+ if (mMaxSize <= 0)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_MAX_SIZE));
+
+ if (mMinSize > mMaxSize)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_A_GREATER_THAN_EQUAL_B", PROP_MIN_SIZE, PROP_MAX_SIZE));
+
+ mExponents = new Vector();
+
+ // Get exponents
+ exponents = config.getString(PROP_EXPONENTS, null);
+
+ if (exponents != null) {
+ StringTokenizer tok = new StringTokenizer(exponents, ",");
+
+ try {
+ while (tok.hasMoreTokens()) {
+ String exp = tok.nextToken().trim();
+
+ mExponents.addElement(new BigInt(Integer.parseInt(exp)));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), exponents,
+ PROP_EXPONENTS};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_CONFIG_PARAM", params));
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key size(s) are within the limit.
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ certInfo[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().toString();
+
+ if (!alg.equalsIgnoreCase(RSA))
+ continue;
+ X509Key newkey = null;
+
+ try {
+ newkey = new X509Key(AlgorithmId.get("RSA"),
+ key.getKey());
+ } catch (Exception e) {
+ CMS.debug( "RSAKeyConstraints::apply() - "
+ + "Exception="+e.toString() );
+ setError( req,
+ CMS.getUserMessage( "CMS_POLICY_KEY_SIZE_VIOLATION",
+ getInstanceName() ),
+ "" );
+ return PolicyResult.REJECTED;
+ }
+ RSAPublicKey rsaKey = new RSAPublicKey(newkey.getEncoded());
+ int keySize = rsaKey.getKeySize();
+
+ if (keySize < mMinSize || keySize > mMaxSize) {
+ String[] params = {getInstanceName(),
+ String.valueOf(keySize),
+ String.valueOf(mMinSize),
+ String.valueOf(mMaxSize)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_SIZE_VIOLATION",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+
+ // If the exponents are configured, see if the key's
+ // exponent is a configured one.
+ if (mExponents.size() > 0) {
+ BigInt exp = rsaKey.getPublicExponent();
+
+ if (!mExponents.contains(exp)) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mExponents.elements();
+ e.hasMoreElements();) {
+ BigInt bi = (BigInt) e.nextElement();
+
+ sb.append(bi.toBigInteger().toString());
+ sb.append(" ");
+ }
+ String[] params = {getInstanceName(),
+ exp.toBigInteger().toString(), new String(sb)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_EXPONENT_VIOLATION", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_SIZE + "=" + mMinSize);
+ confParams.addElement(PROP_MAX_SIZE + "=" + mMaxSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mExponents.elements(); e.hasMoreElements();) {
+ sb.append(((BigInt) e.nextElement()).toInt());
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ confParams.addElement(PROP_EXPONENTS + "=" + sb.toString());
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java
new file mode 100644
index 000000000..5cadafa17
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java
@@ -0,0 +1,235 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Whether to allow renewal of an expired cert.
+ * @version $Revision$, $Date$
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RenewalConstraints extends APolicyRule
+ implements IRenewalPolicy, IExtendedPluginInfo {
+
+ private static final String PROP_ALLOW_EXPIRED_CERTS = "allowExpiredCerts";
+ private static final String PROP_RENEWAL_NOT_AFTER = "renewalNotAfter";
+
+ private boolean mAllowExpiredCerts = true;
+ private long mRenewalNotAfter = 0;
+
+ public final static int DEF_RENEWAL_NOT_AFTER = 30;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+
+ private final static Vector defConfParams = new Vector();
+ static {
+ defConfParams.addElement(PROP_ALLOW_EXPIRED_CERTS + "=" + true);
+ defConfParams.addElement(PROP_RENEWAL_NOT_AFTER + "=" +
+ DEF_RENEWAL_NOT_AFTER);
+ }
+
+ public RenewalConstraints() {
+ NAME = "RenewalConstraints";
+ DESC = "Whether to allow renewal of expired certs.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ALLOW_EXPIRED_CERTS + ";boolean;Allow a user to renew an already-expired certificate",
+ PROP_RENEWAL_NOT_AFTER + ";number;Number of days since certificate expiry after which renewal request would be rejected",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-renewalconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Permit administrator to decide policy on whether to " +
+ "permit renewals for already-expired certificates"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.allowExpiredCerts=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ // Get min and max validity in days and configure them.
+ try {
+ mAllowExpiredCerts =
+ config.getBoolean(PROP_ALLOW_EXPIRED_CERTS, true);
+ String val = config.getString(PROP_RENEWAL_NOT_AFTER, null);
+
+ if (val == null)
+ mRenewalNotAfter = DEF_RENEWAL_NOT_AFTER * DAYS_TO_MS_FACTOR;
+ else {
+ mRenewalNotAfter = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+
+ } catch (EBaseException e) {
+ // never happen.
+ }
+
+ CMS.debug("RenewalConstraints: allow expired certs " + mAllowExpiredCerts);
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificates being renwed.
+ X509CertImpl[] oldCerts =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ if (mAllowExpiredCerts) {
+ CMS.debug("checking validity of each cert");
+ // check if each cert to be renewed is expired for more than // allowed days.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(X509CertImpl.NAME + "." +
+ X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate eligible for renewal ?
+
+ Date now = CMS.getCurrentDate();
+
+ Date renewedNotAfter = new Date(notAfter.getTime() +
+ mRenewalNotAfter);
+
+ CMS.debug("RenewalConstraints: cert " + i + " renewedNotAfter " + renewedNotAfter + " now=" + now);
+
+ if (renewedNotAfter.before(now)) {
+ CMS.debug(
+ "One or more certificates is expired for more than " + (mRenewalNotAfter / DAYS_TO_MS_FACTOR) + " days");
+ String params[] = { getInstanceName(), Long.toString(mRenewalNotAfter / DAYS_TO_MS_FACTOR) };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS_AFTER_ALLOWED_PERIOD",
+ params), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ CMS.debug("RenewalConstraints: checking validity of each cert");
+ // check if each cert to be renewed is expired.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ CMS.debug("RenewalConstraints: cert " + i + " notAfter " + notAfter + " now=" + now);
+ if (notAfter.before(now)) {
+ CMS.debug(
+ "RenewalConstraints: One or more certificates is expired.");
+ String params[] = { getInstanceName() };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS",
+ params), "");
+ result = PolicyResult.REJECTED;
+ break;
+ }
+ }
+
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(
+ PROP_ALLOW_EXPIRED_CERTS + "=" + mAllowExpiredCerts);
+ confParams.addElement(PROP_RENEWAL_NOT_AFTER + "=" +
+ mRenewalNotAfter / DAYS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
new file mode 100644
index 000000000..60f294e36
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
@@ -0,0 +1,342 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * RenewalValidityConstraints is a default rule for Certificate
+ * Renewal. This policy enforces the no of days before which a
+ * currently active certificate can be renewed and sets new validity
+ * period for the renewed certificate starting from the the ending
+ * period in the old certificate.
+ *
+ * The main parameters are:
+ *
+ * The renewal leadtime in days: - i.e how many days before the
+ * expiry of the current certificate can one request the renewal.
+ * min and max validity duration.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RenewalValidityConstraints extends APolicyRule
+ implements IRenewalPolicy, IExtendedPluginInfo {
+ private long mMinValidity;
+ private long mMaxValidity;
+ private long mRenewalInterval;
+
+ private final static String PROP_MIN_VALIDITY = "minValidity";
+ private final static String PROP_MAX_VALIDITY = "maxValidity";
+ private final static String PROP_RENEWAL_INTERVAL = "renewalInterval";
+ public final static int DEF_MIN_VALIDITY = 180;
+ public final static int DEF_MAX_VALIDITY = 730;
+ public final static long DEF_RENEWAL_INTERVAL = 15;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+ public static final String CERT_HEADER = "-----BEGIN CERTIFICATE-----\n";
+ public static final String CERT_TRAILER = "-----END CERTIFICATE-----\n";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_VALIDITY + "=" +
+ DEF_MIN_VALIDITY);
+ defConfParams.addElement(PROP_MAX_VALIDITY + "=" +
+ DEF_MAX_VALIDITY);
+ defConfParams.addElement(PROP_RENEWAL_INTERVAL + "=" +
+ DEF_RENEWAL_INTERVAL);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_VALIDITY + ";number;Specifies the minimum validity period, in days, for renewed certificates.",
+ PROP_MAX_VALIDITY + ";number;Specifies the maximum validity period, in days, for renewed certificates.",
+ PROP_RENEWAL_INTERVAL + ";number;Specifies how many days before its expiration that a certificate can be renewed.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-renewalvalidityconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Reject renewal request if the certificate is too far " +
+ "before it's expiry date"
+ };
+
+ return params;
+
+ }
+
+ public RenewalValidityConstraints() {
+ NAME = "RenewalValidityConstraints";
+ DESC = "Enforces minimum and maximum validity and renewal interval for certificate renewal.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minValidity=30
+ * ra.Policy.rule.<ruleName>.maxValidity=180
+ * ra.Policy.rule.<ruleName>.renewalInterval=15
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get min and max validity in days and onfigure them.
+ try {
+ String val = config.getString(PROP_MIN_VALIDITY, null);
+
+ if (val == null)
+ mMinValidity = DEF_MIN_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMinValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_MAX_VALIDITY, null);
+ if (val == null)
+ mMaxValidity = DEF_MAX_VALIDITY * DAYS_TO_MS_FACTOR;
+ else {
+ mMaxValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+ val = config.getString(PROP_RENEWAL_INTERVAL, null);
+ if (val == null)
+ mRenewalInterval = DEF_RENEWAL_INTERVAL * DAYS_TO_MS_FACTOR;
+ else {
+ mRenewalInterval = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+
+ // minValidity can't be bigger than maxValidity.
+ if (mMinValidity > mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(mMinValidity / DAYS_TO_MS_FACTOR),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR) };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_RENEWAL_MIN_MAX", params));
+ }
+
+ // Renewal interval can't be more than maxValidity.
+ if (mRenewalInterval > mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(mRenewalInterval / DAYS_TO_MS_FACTOR),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR) };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_RENEWAL_INTERVAL", params));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ if (agentApproved(req))
+ return result;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // Get the certificates being renwed.
+ X509CertImpl currentCerts[] =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ // Both certificate info and current certs should be set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ if (currentCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ if (certInfo.length != currentCerts.length) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_MISMATCHED_CERTINFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the renewal interval is okay and then
+ // set the validity.
+ for (int i = 0; i < certInfo.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ currentCerts[i].get(X509CertImpl.NAME +
+ "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ if (notAfter.after(now)) {
+ // Check if the renewal interval is alright.
+ long interval = notAfter.getTime() - now.getTime();
+
+ if (interval > mRenewalInterval) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_LONG_RENEWAL_LEAD_TIME",
+ getInstanceName(),
+ String.valueOf(mRenewalInterval / DAYS_TO_MS_FACTOR)), "");
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_EXISTING_CERT_DETAILS",
+ getInstanceName(),
+ getCertDetails(req, currentCerts[i])), "");
+
+ result = PolicyResult.REJECTED;
+ setDummyValidity(certInfo[i]);
+ continue;
+ }
+ }
+
+ // Else compute new validity.
+ Date renewedNotBef = notAfter;
+ Date renewedNotAfter = new Date(notAfter.getTime() +
+ mMaxValidity);
+
+ // If the new notAfter is within renewal interval days from
+ // today or already expired, set the notBefore to today.
+ if (renewedNotAfter.before(now) ||
+ (renewedNotAfter.getTime() - now.getTime()) <=
+ mRenewalInterval) {
+ renewedNotBef = now;
+ renewedNotAfter = new Date(now.getTime() +
+ mMaxValidity);
+ }
+ CertificateValidity newValidity =
+ new CertificateValidity(renewedNotBef, renewedNotAfter);
+
+ certInfo[i].set(X509CertInfo.VALIDITY, newValidity);
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_VALIDITY + "=" +
+ mMinValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_MAX_VALIDITY + "=" +
+ mMaxValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_RENEWAL_INTERVAL + "=" +
+ mRenewalInterval / DAYS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+
+ // Set dummy validity field so the request will serialize properly
+ private void setDummyValidity(X509CertInfo certInfo) {
+ try {
+ certInfo.set(X509CertInfo.VALIDITY,
+ new CertificateValidity(CMS.getCurrentDate(), new Date()));
+ } catch (Exception e) {
+ }
+ }
+
+ private String getCertDetails(IRequest req, X509CertImpl cert) {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("\n");
+ sb.append("Serial No: " + cert.getSerialNumber().toString(16));
+ sb.append("\n");
+ sb.append("Validity: " + cert.getNotBefore().toString() +
+ " - " + cert.getNotAfter().toString());
+ sb.append("\n");
+ String certType = req.getExtDataInString(IRequest.CERT_TYPE);
+
+ if (certType == null)
+ certType = IRequest.SERVER_CERT;
+ if (certType.equals(IRequest.CLIENT_CERT)) {
+
+ /*** Take this our - URL formulation hard to do here.
+ sb.append("Use the following url with your CA/RA gateway spec to download the certificate.");
+ sb.append("\n");
+ sb.append("/query/certImport?op=displayByserial&serialNumber=");
+ sb.append(cert.getSerialNumber().toString(16));
+ ***/
+ sb.append("\n");
+ } else {
+ sb.append("Certificate Content is as follows:");
+ sb.append("\n");
+ try {
+ byte[] ba = cert.getEncoded();
+ String encodedCert = com.netscape.osutil.OSUtil.BtoA(ba);
+
+ sb.append(CERT_HEADER + encodedCert + CERT_TRAILER);
+ } catch (Exception e) {
+ //throw new AssertionException(e.toString());
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
new file mode 100644
index 000000000..1afb9cbba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
@@ -0,0 +1,208 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Whether to allow revocation of an expired cert.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RevocationConstraints extends APolicyRule
+ implements IRevocationPolicy, IExtendedPluginInfo {
+ private static final String PROP_ALLOW_EXPIRED_CERTS = "allowExpiredCerts";
+ private static final String PROP_ALLOW_ON_HOLD = "allowOnHold";
+
+ private boolean mAllowExpiredCerts = true;
+ private boolean mAllowOnHold = true;
+
+ private final static Vector defConfParams = new Vector();
+ static {
+ defConfParams.addElement(PROP_ALLOW_EXPIRED_CERTS + "=" + true);
+ defConfParams.addElement(PROP_ALLOW_ON_HOLD + "=" + true);
+ }
+
+ public RevocationConstraints() {
+ NAME = "RevocationConstraints";
+ DESC = "Whether to allow revocation of expired certs and on-hold.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ALLOW_EXPIRED_CERTS + ";boolean;Allow a user to revoke an already-expired certificate",
+ PROP_ALLOW_ON_HOLD + ";boolean;Allow a user to set reason to On-Hold",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-revocationconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Allow administrator to decide policy on whether to allow " +
+ "recovation of expired certificates" +
+ "and set reason to On-Hold"
+
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.allowExpiredCerts=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ // Get min and max validity in days and onfigure them.
+ try {
+ mAllowExpiredCerts =
+ config.getBoolean(PROP_ALLOW_EXPIRED_CERTS, true);
+ mAllowOnHold =
+ config.getBoolean(PROP_ALLOW_ON_HOLD, true);
+ } catch (EBaseException e) {
+ // never happen.
+ }
+
+ CMS.debug("RevocationConstraints: allow expired certs " + mAllowExpiredCerts);
+ CMS.debug("RevocationConstraints: allow on hold " + mAllowOnHold);
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ CMS.debug("RevocationConstraints: apply begins");
+ if (req.getExtDataInInteger(IRequest.REVOKED_REASON) == null) {
+ CMS.debug("RevocationConstraints: apply: no revocationReason found in request");
+ return PolicyResult.REJECTED;
+ }
+ RevocationReason rr = RevocationReason.fromInt(
+ req.getExtDataInInteger(IRequest.REVOKED_REASON).intValue());
+
+ if (!mAllowOnHold && (rr != null)) {
+ int reason = rr.toInt();
+
+ if (reason == RevocationReason.CERTIFICATE_HOLD.toInt()) {
+ String params[] = { getInstanceName() };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_ON_HOLD_ALLOWED", params), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ if (mAllowExpiredCerts)
+ // nothing to check.
+ return PolicyResult.ACCEPTED;
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificates being renwed.
+ X509CertImpl[] oldCerts =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT"),
+ getInstanceName());
+ return PolicyResult.REJECTED;
+ }
+
+ // check if each cert to be renewed is expired.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ if (notAfter.before(now)) {
+ String params[] = { getInstanceName() };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_REVOKE_EXPIRED_CERTS",
+ params), "");
+ result = PolicyResult.REJECTED;
+ break;
+ }
+ }
+
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(
+ PROP_ALLOW_EXPIRED_CERTS + "=" + mAllowExpiredCerts);
+ confParams.addElement(
+ PROP_ALLOW_ON_HOLD + "=" + mAllowOnHold);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
new file mode 100644
index 000000000..be9870935
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
@@ -0,0 +1,442 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * SigningAlgorithmConstraints enforces that only a supported
+ * signing algorithm be requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SigningAlgorithmConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private String[] mAllowedAlgs = null; // algs allowed by this policy
+ static String[] mDefaultAllowedAlgs = null; // default algs allowed by this policy based on CA's key
+ private String[] mConfigAlgs = null; // algs listed in config file
+ private boolean winnowedByKey = false;
+ IAuthority mAuthority = null;
+ private final static String PROP_ALGORITHMS = "algorithms";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ StringBuffer sb = new StringBuffer();
+ sb.append(PROP_ALGORITHMS);
+ sb.append("=");
+ int i = 0;
+ boolean first = true;
+
+ mDefaultAllowedAlgs = new String[AlgorithmId.ALL_SIGNING_ALGORITHMS.length];
+ for (i = 0; i < AlgorithmId.ALL_SIGNING_ALGORITHMS.length; i++) {
+ mDefaultAllowedAlgs[i] = AlgorithmId.ALL_SIGNING_ALGORITHMS[i];
+ if (first == true) {
+ sb.append(AlgorithmId.ALL_SIGNING_ALGORITHMS[i]);
+ first = false;
+ } else {
+ sb.append(",");
+ sb.append(AlgorithmId.ALL_SIGNING_ALGORITHMS[i]);
+ }
+ }
+ defConfParams.addElement(sb.toString());
+ }
+
+ public SigningAlgorithmConstraints() {
+ NAME = "SigningAlgorithmConstraints";
+ DESC = "Enforces Signing Algorithm Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=SigningAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=SHA-1WithRSA, SHA-1WithDSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mAuthority = (IAuthority) ((IPolicyProcessor) owner).getAuthority();
+
+ // Get allowed algorithms from config file
+ if (config != null) {
+ String algNames = null;
+
+ try {
+ algNames = config.getString(PROP_ALGORITHMS, null);
+ } catch (Exception e) {
+ String[] params = {getInstanceName(), e.toString(), PROP_ALGORITHMS};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PARAM_CONFIG_ERROR", params));
+ }
+
+ if (algNames != null) {
+ // parse alg names into Vector
+ StringTokenizer tok = new StringTokenizer(algNames, ",");
+ Vector algs = new Vector();
+
+ while (tok.hasMoreTokens()) {
+ algs.addElement(tok.nextToken().trim());
+ }
+
+ // convert to array for speedy traversals during apply()
+ int itemCount = algs.size();
+
+ mAllowedAlgs = new String[itemCount];
+ for (int i = 0; i < itemCount; i++) {
+ mAllowedAlgs[i] = (String) algs.elementAt(i);
+ }
+
+ }
+
+ }
+
+ // these are the algorithms from the config file
+ mConfigAlgs = mAllowedAlgs;
+ if (mConfigAlgs == null) {
+ mConfigAlgs = new String[0];
+ }
+
+ if (mAllowedAlgs != null) {
+ // winnow out unknown algorithms
+ winnowAlgs(AlgorithmId.ALL_SIGNING_ALGORITHMS,
+ "CMS_POLICY_UNKNOWN_SIGNING_ALG", true);
+ } else {
+ // if nothing was in the config file, allow all known algs
+ mAllowedAlgs = AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+
+ // winnow out algorithms that don't make sense for the key
+ winnowByKey();
+
+ if (mAllowedAlgs.length == 0) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY", NAME));
+ }
+
+ }
+
+ /**
+ * winnow out algorithms that don't make sense for the CA's key
+ */
+ private synchronized void winnowByKey() throws EBaseException {
+ // only do this successfully once
+ if (winnowedByKey) {
+ return;
+ }
+
+ // don't do this ever for DRM
+ if (!(mAuthority instanceof ICertAuthority)) {
+ winnowedByKey = true;
+ return;
+ }
+
+ // get list of algorithms allowed for the key
+ String[] allowedByKey =
+ ((ICertAuthority) mAuthority).getCASigningAlgorithms();
+
+ if (allowedByKey != null) {
+ // don't show algorithms that don't match CA's key in UI.
+ mDefaultAllowedAlgs = new String[allowedByKey.length];
+ for (int i = 0; i < allowedByKey.length; i++)
+ mDefaultAllowedAlgs[i] = allowedByKey[i];
+ // winnow out algorithms that don't match CA's signing key
+ winnowAlgs(allowedByKey,
+ "CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY_1", false);
+ winnowedByKey = true;
+ } else {
+ // We don't know the CA's signing algorithms. Maybe we're
+ // an RA that hasn't talked to the CA yet? Try again later.
+ }
+ }
+
+ /**
+ * Winnows out of mAllowedAlgorithms those algorithms that aren't allowed
+ * for some reason.
+ *
+ * @param allowed An array of allowed algorithms. Only algorithms in this
+ * list will survive the winnowing process.
+ * @param reason A string describing the problem with an algorithm
+ * that is not allowed by this list. Must be a predefined string in PolicyResources.
+ */
+ private void winnowAlgs(String[] allowed, String reason, boolean isError)
+ throws EBaseException {
+ int i, j, goodSize;
+
+ // validate the currently-allowed algorithms
+ Vector goodAlgs = new Vector();
+
+ for (i = 0; i < mAllowedAlgs.length; i++) {
+ for (j = 0; j < allowed.length; j++) {
+ if (mAllowedAlgs[i].equals(allowed[j])) {
+ goodAlgs.addElement(mAllowedAlgs[i]);
+ break;
+ }
+ }
+ // if algorithm is not allowed, log a warning
+ if (j == allowed.length) {
+ EPolicyException e = new EPolicyException(CMS.getUserMessage(reason, NAME, mAllowedAlgs[i]));
+
+ if (isError) {
+ log(ILogger.LL_FAILURE, e.toString());
+ throw new EPolicyException(CMS.getUserMessage(reason,
+ NAME, mAllowedAlgs[i]));
+ } else {
+ log(ILogger.LL_WARN, e.toString());
+ }
+ }
+ }
+
+ // convert back into an array
+ goodSize = goodAlgs.size();
+ if (mAllowedAlgs.length != goodSize) {
+ mAllowedAlgs = new String[ goodSize ];
+ for (i = 0; i < goodSize; i++) {
+ mAllowedAlgs[i] = (String) goodAlgs.elementAt(i);
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ int i, j;
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate info from the request
+ //X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // We need to have a certificate info set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key algorithm is supported.
+ for (i = 0; i < certInfo.length; i++) {
+ // make sure our list of allowed algorithms makes
+ // sense for our key. Do this each time.
+ if (!winnowedByKey) {
+ winnowByKey();
+ }
+
+ CertificateAlgorithmId certAlgId = (CertificateAlgorithmId)
+ certInfo[i].get(X509CertInfo.ALGORITHM_ID);
+
+ AlgorithmId algId = (AlgorithmId)
+ certAlgId.get(CertificateAlgorithmId.ALGORITHM);
+ String alg = algId.getName();
+
+ // test against the list of allowed algorithms
+ for (j = 0; j < mAllowedAlgs.length; j++) {
+ if (mAllowedAlgs[j].equals(alg)) {
+ break;
+ }
+ }
+ if (j == mAllowedAlgs.length) {
+ // if the algor doesn't match the CA's key replace
+ // it with one that does.
+ if (mAllowedAlgs[0].equals("SHA1withDSA") ||
+ alg.equals("SHA1withDSA")) {
+ certInfo[i].set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(
+ AlgorithmId.get(mAllowedAlgs[0])));
+ return PolicyResult.ACCEPTED;
+ }
+
+ // didn't find a match, alg not allowed
+ setError(req, CMS.getUserMessage("CMS_POLICY_SIGNING_ALG_VIOLATION",
+ getInstanceName(), alg), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < mConfigAlgs.length; i++) {
+ sb.append(mConfigAlgs[i]);
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ confParams.addElement(PROP_ALGORITHMS + "=" + sb.toString());
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(PROP_ALGORITHMS);
+ sb.append("=");
+ boolean first = true;
+
+ defConfParams.removeAllElements();
+
+ for (int i = 0; i < mDefaultAllowedAlgs.length; i++) {
+ if (first == true) {
+ sb.append(mDefaultAllowedAlgs[i]);
+ first = false;
+ } else {
+ sb.append(",");
+ sb.append(mDefaultAllowedAlgs[i]);
+ }
+ }
+ defConfParams.addElement(sb.toString());
+
+ return defConfParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (!winnowedByKey) {
+ try {
+ winnowByKey();
+ } catch (Exception e) {
+ }
+ }
+
+ String[] params = null;
+
+ String[] params_BOTH = {
+ PROP_ALGORITHMS + ";" + "choice(MD2withRSA\\,MD5withRSA\\,SHA1withRSA\\,SHA256withRSA\\,SHA512withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA\\,SHA1withRSA\\,SHA1withDSA,"+
+ "MD2withRSA\\,MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,SHA1withRSA\\,SHA1withDSA," +
+ "MD5withRSA\\,SHA1withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA," +
+ "MD2withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,SHA1withDSA," +
+ "MD5withRSA\\,SHA1withRSA," +
+ "MD5withRSA\\,SHA1withDSA," +
+ "SHA1withRSA\\,SHA1withDSA," +
+ "MD2withRSA," +
+ "MD5withRSA," +
+ "SHA1withRSA," +
+ "SHA1withDSA);List of algorithms to restrict the requested signing algorithm " +
+ "to be one of the algorithms supported by Certificate System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ String[] params_RSA = {
+ PROP_ALGORITHMS + ";" + "choice(MD2withRSA\\,MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,MD5withRSA," +
+ "MD2withRSA\\,SHA1withRSA," +
+ "MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA," +
+ "MD5withRSA," +
+ "SHA1withRSA);Restrict the requested signing algorithm to be " +
+ "one of the algorithms supported by Certificate System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ String[] params_DSA = {
+ PROP_ALGORITHMS + ";" + "choice(SHA1withDSA);Restrict the requested signing " +
+ "algorithm to be one of the algorithms supported by Certificate " +
+ "System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ switch (mDefaultAllowedAlgs.length) {
+ case 1:
+ params = params_DSA;
+ break;
+
+ case 3:
+ params = params_RSA;
+ break;
+
+ case 4:
+ default:
+ params = params_BOTH;
+ break;
+
+ }
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java
new file mode 100644
index 000000000..dffde5806
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java
@@ -0,0 +1,189 @@
+// --- 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.policy.constraints;
+
+
+import org.mozilla.jss.crypto.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This simple policy checks the subordinate CA CSR to see
+ * if it is the same as the local CA.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubCANameConstraints extends APolicyRule implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public ICertificateAuthority mCA = null;
+ public String mIssuerNameStr = null;
+
+ public SubCANameConstraints() {
+ NAME = "SubCANameConstraints";
+ DESC = "Enforces Subordinate CA name.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subcanamecheck",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Checks if subordinate CA request matches the local CA. There are no parameters to change"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=KeyAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=RSA,DSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // get CA's public key to create authority key id.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager"));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager"));
+ }
+ mCA = (ICertificateAuthority) certAuthority;
+ ISigningUnit su = mCA.getSigningUnit();
+ if( su == null || CMS.isPreOpMode() ) {
+ return;
+ }
+
+ X509CertImpl cert = su.getCertImpl();
+
+ if (cert == null)
+ return;
+ X500Name issuerName = (X500Name) cert.getSubjectDN();
+
+ if (issuerName == null)
+ return;
+ mIssuerNameStr = issuerName.toString();
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate templates
+ X509CertInfo[] certInfos = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (certInfos == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_CERT_INFO", getInstanceName()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME + ":" + getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // retrieve the subject name and check its unqiueness
+ for (int i = 0; i < certInfos.length; i++) {
+ CertificateSubjectName subName = (CertificateSubjectName) certInfos[i].get(X509CertInfo.SUBJECT);
+
+ // if there is no name set, set one here.
+ if (subName == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_SUBJECT_NAME_1", getInstanceName()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUBJECT_NAME", NAME + ":" + getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ String certSubjectName = subName.toString();
+
+ if (certSubjectName.equalsIgnoreCase(mIssuerNameStr)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_SUBJECT_NAME_EXIST_1", mIssuerNameStr));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_NAME_EXIST", NAME + ":" + "Same As Issuer Name " + mIssuerNameStr), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_SUBJECT_NAME_1", getInstanceName()));
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java
new file mode 100644
index 000000000..a2aeef09d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java
@@ -0,0 +1,47 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This class is used to help migrate CMS4.1 to CMS4.2.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class UniqueSubjectName extends UniqueSubjectNameConstraints {
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
new file mode 100644
index 000000000..040b5e205
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
@@ -0,0 +1,299 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.policy.APolicyRule;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Checks the uniqueness of the subject name. This policy
+ * can only be used (installed) in Certificate Authority
+ * subsystem.
+ *
+ * This policy can perform pre-agent-approval checking or
+ * post-agent-approval checking based on configuration
+ * setting.
+ *
+ * In some situations, user may want to have 2 certificates with
+ * the same subject name. For example, one key for encryption,
+ * and one for signing. This policy does not deal with this case
+ * directly. But it can be easily extended to do that.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class UniqueSubjectNameConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_PRE_AGENT_APPROVAL_CHECKING =
+ "enablePreAgentApprovalChecking";
+ protected static final String PROP_KEY_USAGE_EXTENSION_CHECKING =
+ "enableKeyUsageExtensionChecking";
+
+ public ICertificateAuthority mCA = null;
+
+ public boolean mPreAgentApprovalChecking = false;
+ public boolean mKeyUsageExtensionChecking = true;
+
+ public UniqueSubjectNameConstraints() {
+ NAME = "UniqueSubjectName";
+ DESC = "Ensure the uniqueness of the subject name.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_PRE_AGENT_APPROVAL_CHECKING + ";boolean;If checked, check subject name uniqueness BEFORE agent approves, (else checks AFTER approval)",
+ PROP_KEY_USAGE_EXTENSION_CHECKING + ";boolean;If checked, allow non-unique subject names if Key Usage Extension differs",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-uniquesubjectname",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects a request if there exists an unrevoked, unexpired " +
+ "certificate with the same subject name"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=UniqueSubjectName
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.enablePreAgentApprovalChecking=true
+ * ca.Policy.rule.<ruleName>.enableKeyUsageExtensionChecking=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // get CA's public key to create authority key id.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", "Cannot find the Certificate Manager or Registration Manager"));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", "Cannot find the Certificate Manager"));
+ }
+
+ mCA = (ICertificateAuthority) certAuthority;
+ try {
+ mPreAgentApprovalChecking =
+ config.getBoolean(PROP_PRE_AGENT_APPROVAL_CHECKING, false);
+ } catch (EBaseException e) {
+ }
+ try {
+ mKeyUsageExtensionChecking =
+ config.getBoolean(PROP_KEY_USAGE_EXTENSION_CHECKING, true);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ if (!mPreAgentApprovalChecking) {
+ // post agent approval checking
+ if (!agentApproved(req))
+ return PolicyResult.ACCEPTED;
+ }
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate templates
+ X509CertInfo[] certInfos = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (certInfos == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // retrieve the subject name and check its unqiueness
+ for (int i = 0; i < certInfos.length; i++) {
+ CertificateSubjectName subName = (CertificateSubjectName)
+ certInfos[i].get(X509CertInfo.SUBJECT);
+
+ // if there is no name set, set one here.
+ if (subName == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUBJECT_NAME",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ String certSubjectName = subName.toString();
+ String filter = "x509Cert.subject=" + certSubjectName;
+ // subject name is indexed, so we only use subject name
+ // in the filter
+ Enumeration matched =
+ mCA.getCertificateRepository().findCertRecords(filter);
+
+ while (matched.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) matched.nextElement();
+ String status = rec.getStatus();
+
+ if (status.equals(ICertRecord.STATUS_REVOKED) || status.equals(ICertRecord.STATUS_EXPIRED) || status.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ // accept this only if we have a REVOKED,
+ // EXPIRED or REVOKED_EXPIRED certificate
+ continue;
+
+ }
+ // you already have an VALID or INVALID (not yet valid) certificate
+ if (mKeyUsageExtensionChecking && agentApproved(req)) {
+ // This request is agent approved which
+ // means all requested extensions are finalized
+ // to the request,
+ // We will accept duplicated subject name with
+ // different keyUsage extension if
+ // keyUsageExtension is different.
+ if (!sameKeyUsageExtension(rec, certInfos[i])) {
+ continue;
+ }
+ }
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_NAME_EXIST",
+ getInstanceName() + " " + certSubjectName), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the key extension in the issued certificate
+ * is the same as the one in the certificate template.
+ */
+ private boolean sameKeyUsageExtension(ICertRecord rec,
+ X509CertInfo certInfo) {
+ X509CertImpl impl = rec.getCertificate();
+ boolean bits[] = impl.getKeyUsage();
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (java.security.cert.CertificateException e) {
+ }
+ KeyUsageExtension ext = null;
+
+ if (extensions == null) {
+ if (bits != null)
+ return false;
+ } else {
+ try {
+ ext = (KeyUsageExtension) extensions.get(
+ KeyUsageExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (ext == null) {
+ if (bits != null)
+ return false;
+ } else {
+ boolean[] InfoBits = ext.getBits();
+
+ if (InfoBits == null) {
+ if (bits != null)
+ return false;
+ } else {
+ if (bits == null)
+ return false;
+ if (InfoBits.length != bits.length) {
+ return false;
+ }
+ for (int i = 0; i < InfoBits.length; i++) {
+ if (InfoBits[i] != bits[i])
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_PRE_AGENT_APPROVAL_CHECKING +
+ "=" + mPreAgentApprovalChecking);
+ confParams.addElement(PROP_KEY_USAGE_EXTENSION_CHECKING +
+ "=" + mKeyUsageExtensionChecking);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_PRE_AGENT_APPROVAL_CHECKING + "=");
+ defParams.addElement(PROP_KEY_USAGE_EXTENSION_CHECKING + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
new file mode 100644
index 000000000..832d77746
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
@@ -0,0 +1,316 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * ValidityConstraints is a default rule for Enrollment and
+ * Renewal that enforces minimum and maximum validity periods
+ * and changes them if not met.
+ *
+ * Optionally the lead and lag times - i.e how far back into the
+ * front or back the notBefore date could go in minutes can also
+ * be specified.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ValidityConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected long mMinValidity;
+ protected long mMaxValidity;
+ protected long mLeadTime;
+ protected long mLagTime;
+ protected long mNotBeforeSkew;
+
+ private final static String PROP_MIN_VALIDITY = "minValidity";
+ private final static String PROP_MAX_VALIDITY = "maxValidity";
+ private final static String PROP_LEAD_TIME = "leadTime";
+ private final static String PROP_LAG_TIME = "lagTime";
+ private final static String PROP_NOT_BEFORE_SKEW = "notBeforeSkew";
+ public final static int DEF_MIN_VALIDITY = 180;
+ public final static int DEF_MAX_VALIDITY = 730;
+ public final static int DEF_LEAD_TIME = 10;
+ public final static int DEF_LAG_TIME = 10;
+ public final static int DEF_NOT_BEFORE_SKEW = 5;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+ public final static long MINS_TO_MS_FACTOR = 60L * 1000;
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_VALIDITY + "=" +
+ DEF_MIN_VALIDITY);
+ defConfParams.addElement(PROP_MAX_VALIDITY + "=" +
+ DEF_MAX_VALIDITY);
+ defConfParams.addElement(PROP_LEAD_TIME + "=" +
+ DEF_LEAD_TIME);
+ defConfParams.addElement(PROP_LAG_TIME + "=" +
+ DEF_LAG_TIME);
+ defConfParams.addElement(PROP_NOT_BEFORE_SKEW + "=" +
+ DEF_NOT_BEFORE_SKEW);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_VALIDITY + ";number;Minimum Validity time, in days",
+ PROP_MAX_VALIDITY + ";number;Maximum Validity time, in days",
+ PROP_LEAD_TIME + ";number;Number of minutes in the future a request's notBefore can be",
+ PROP_LAG_TIME + ";number;NOT CURRENTLY IN USE",
+ PROP_NOT_BEFORE_SKEW + ";number;Number of minutes a cert's notBefore should be in the past",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-validityconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Ensures that the user's requested validity period is " +
+ "acceptable. If not specified, as is usually the case, " +
+ "this policy will set the validity. See RFC 2459."
+ };
+
+ return params;
+
+ }
+
+ public ValidityConstraints() {
+ NAME = "ValidityConstraints";
+ DESC = "Enforces minimum and maximum validity constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minValidity=30
+ * ra.Policy.rule.<ruleName>.maxValidity=180
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get min and max validity in days and configure them.
+ try {
+ String val = config.getString(PROP_MIN_VALIDITY, null);
+
+ if (val == null)
+ mMinValidity = DEF_MIN_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMinValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_MAX_VALIDITY, null);
+ if (val == null)
+ mMaxValidity = DEF_MAX_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMaxValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_LEAD_TIME, null);
+ if (val != null)
+ mLeadTime = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mLeadTime = DEF_LEAD_TIME * MINS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_LAG_TIME, null);
+ if (val != null)
+ mLagTime = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mLagTime = DEF_LAG_TIME * MINS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_NOT_BEFORE_SKEW, null);
+ if (val != null)
+ mNotBeforeSkew = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mNotBeforeSkew = DEF_NOT_BEFORE_SKEW * MINS_TO_MS_FACTOR;
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ //X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if validity is within the limit
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateValidity validity = (CertificateValidity)
+ certInfo[i].get(X509CertInfo.VALIDITY);
+
+ Date notBefore = null, notAfter = null;
+
+ if (validity != null) {
+ notBefore = (Date)
+ validity.get(CertificateValidity.NOT_BEFORE);
+ notAfter = (Date)
+ validity.get(CertificateValidity.NOT_AFTER);
+ }
+
+ // If no validity is supplied yet, make one. The default
+ // validity is supposed to pass the following checks, so
+ // bypass further checking.
+ // (date = 0 is hack for serialization)
+
+ if (validity == null ||
+ (notBefore.getTime() == 0 && notAfter.getTime() == 0)) {
+ certInfo[i].set(X509CertInfo.VALIDITY,
+ makeDefaultValidity(req));
+ continue;
+ }
+
+ Date now = CMS.getCurrentDate();
+
+ if (notBefore.getTime() > (now.getTime() + mLeadTime)) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_INVALID_BEGIN_TIME",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ }
+ if ((notAfter.getTime() - notBefore.getTime()) >
+ mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(
+ ((notAfter.getTime() - notBefore.getTime()) / DAYS_TO_MS_FACTOR)),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_MORE_THAN_MAX_VALIDITY", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ if ((notAfter.getTime() - notBefore.getTime()) <
+ mMinValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(
+ ((notAfter.getTime() - notBefore.getTime()) / DAYS_TO_MS_FACTOR)),
+ String.valueOf(mMinValidity / DAYS_TO_MS_FACTOR)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_LESS_THAN_MIN_VALIDITY", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_VALIDITY + "=" +
+ mMinValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_MAX_VALIDITY + "=" +
+ mMaxValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_LEAD_TIME + "="
+ + mLeadTime / MINS_TO_MS_FACTOR);
+ confParams.addElement(PROP_LAG_TIME + "=" +
+ mLagTime / MINS_TO_MS_FACTOR);
+ confParams.addElement(PROP_NOT_BEFORE_SKEW + "=" +
+ mNotBeforeSkew / MINS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+
+ /**
+ * Create a default validity value for a request
+ *
+ * This code can be easily overridden in a derived class, if the
+ * calculations here aren't accepatble.
+ *
+ * TODO: it might be good to base this calculation on the creation
+ * time of the request.
+ */
+ protected CertificateValidity makeDefaultValidity(IRequest req) {
+ long now = roundTimeToSecond((CMS.getCurrentDate()).getTime());
+
+ // We will set the max duration as the default validity.
+ long notBeforeTime = now - mNotBeforeSkew;
+ Date notBefore = new Date(notBeforeTime);
+ Date notAfter = new Date(notBeforeTime + mMaxValidity);
+
+ return new CertificateValidity(notBefore, notAfter);
+ }
+
+ /**
+ * convert a millisecond resolution time into one with 1 second
+ * resolution. Most times in certificates are storage at 1
+ * second resolution, so its better if we deal with things at
+ * that level.
+ */
+ protected long roundTimeToSecond(long input) {
+ return (input / 1000) * 1000;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
new file mode 100644
index 000000000..054379bb5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
@@ -0,0 +1,381 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Authority Information Access extension policy.
+ * If this policy is enabled, it adds an authority
+ * information access extension to the certificate.
+ *
+ * The following listed sample configuration parameters:
+ *
+ * ca.Policy.impl.AuthInfoAccess.class=com.netscape.certsrv.policy.AuthInfoAccessExt
+ * ca.Policy.rule.aia.ad0_location=uriName:http://ocsp1.netscape.com
+ * ca.Policy.rule.aia.ad0_method=ocsp
+ * ca.Policy.rule.aia.ad1_location_type=URI
+ * ca.Policy.rule.aia.ad1_location=http://ocsp2.netscape.com
+ * ca.Policy.rule.aia.ad1_method=ocsp
+ * ca.Policy.rule.aia.ad2_location=
+ * ca.Policy.rule.aia.ad2_method=
+ * ca.Policy.rule.aia.ad3_location=
+ * ca.Policy.rule.aia.ad3_method=
+ * ca.Policy.rule.aia.ad4_location=
+ * ca.Policy.rule.aia.ad4_method=
+ * ca.Policy.rule.aia.critical=true
+ * ca.Policy.rule.aia.enable=true
+ * ca.Policy.rule.aia.implName=AuthInfoAccess
+ * ca.Policy.rule.aia.predicate=
+ *
+ * Currently, this policy only supports the following location:
+ * uriName:[URI], dirName:[DN]
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthInfoAccessExt extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_AD =
+ "ad";
+ protected static final String PROP_METHOD =
+ "method";
+ protected static final String PROP_LOCATION =
+ "location";
+ protected static final String PROP_LOCATION_TYPE =
+ "location_type";
+
+ protected static final String PROP_NUM_ADS =
+ "numADs";
+
+ public static final int MAX_AD = 5;
+
+ public IConfigStore mConfig = null;
+
+ public AuthInfoAccessExt() {
+ NAME = "AuthInfoAccessExt";
+ DESC = "Sets authority information access extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL +
+ ";boolean;RFC 2459 recommendation: This extension MUST be non-critical.");
+ v.addElement(PROP_NUM_ADS +
+ ";number;The total number of access descriptions.");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Authority Info Access Extension. Defined in RFC 2459 " + "(4.2.2.1)");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-authinfoaccess");
+
+ for (int i = 0; i < MAX_AD; i++) {
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_METHOD + ";string;" + "A unique,valid OID specified in dot-separated numeric component notation. e.g. 1.3.6.1.5.5.7.48.1 (ocsp), 1.3.6.1.5.5.7.48.2 (caIssuers), 2.16.840.1.113730.1.16.1 (renewal)");
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_LOCATION_TYPE + ";" + IGeneralNameUtil.GENNAME_CHOICE_INFO);
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_LOCATION + ";" + IGeneralNameUtil.GENNAME_VALUE_INFO);
+ }
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=AuthInfoAccessExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ }
+
+ /**
+ * Returns a sequence of access descriptions.
+ */
+ private Enumeration getAccessDescriptions() throws EBaseException {
+ Vector ads = new Vector();
+
+ //
+ // read until there is *NO* ad<NUM>_method
+ //
+ for (int i = 0;; i++) {
+ ObjectIdentifier methodOID = null;
+ String method = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_METHOD, null);
+
+ if (method == null)
+ break;
+ method = method.trim();
+ if (method.equals(""))
+ break;
+
+ //
+ // method ::= ocsp | caIssuers | <OID>
+ // OID ::= [object identifier]
+ //
+ try {
+ if (method.equalsIgnoreCase("ocsp")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("1.3.6.1.5.5.7.48.1");
+ } else if (method.equalsIgnoreCase("caIssuers")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("1.3.6.1.5.5.7.48.2");
+ } else if (method.equalsIgnoreCase("renewal")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("2.16.840.1.113730.1.16.1");
+ } else {
+ // it could be an object identifier, test it
+ methodOID = ObjectIdentifier.getObjectIdentifier(method);
+ }
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NAME_CAN_NOT_BE_RESOLVED", method));
+ }
+
+ //
+ // location ::= <TAG> : <VALUE>
+ // TAG ::= uriName | dirName
+ // VALUE ::= [value defined by TAG]
+ //
+ String location_type = mConfig.getString(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE, null);
+ String location = mConfig.getString(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION, null);
+
+ if (location == null)
+ break;
+ GeneralName gn = CMS.form_GeneralName(location_type, location);
+ Vector e = new Vector();
+
+ e.addElement(methodOID);
+ e.addElement(gn);
+ ads.addElement(e);
+ }
+ return ads.elements();
+ }
+
+ /**
+ * If this policy is enabled, add the authority information
+ * access extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, ""));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Configuration Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // add access descriptions
+ Enumeration e = getAccessDescriptions();
+
+ if (!e.hasMoreElements()) {
+ return res;
+ }
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // check to see if AIA is already exist
+ try {
+ extensions.delete(AuthInfoAccessExtension.NAME);
+ log(ILogger.LL_WARN, "Previous extension deleted: " + AuthInfoAccessExtension.NAME);
+ } catch (IOException ex) {
+ }
+ }
+
+ // Create the extension
+ AuthInfoAccessExtension aiaExt = new
+ AuthInfoAccessExtension(mConfig.getBoolean(
+ PROP_CRITICAL, false));
+
+ while (e.hasMoreElements()) {
+ Vector ad = (Vector) e.nextElement();
+ ObjectIdentifier oid = (ObjectIdentifier) ad.elementAt(0);
+ GeneralName gn = (GeneralName) ad.elementAt(1);
+
+ aiaExt.addAccessDescription(oid, gn);
+ }
+ extensions.set(AuthInfoAccessExtension.NAME, aiaExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, e.getMessage()), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Configuration Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Certificate Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" +
+ mConfig.getBoolean(PROP_CRITICAL, false));
+ } catch (EBaseException e) {
+ params.addElement(PROP_CRITICAL + "=false");
+ }
+
+ int numADs = MAX_AD;
+
+ try {
+ numADs = mConfig.getInteger(PROP_NUM_ADS, MAX_AD);
+ params.addElement(PROP_NUM_ADS + "=" + numADs);
+ } catch (EBaseException e) {
+ params.addElement(PROP_NUM_ADS + "=" + MAX_AD);
+ }
+
+ for (int i = 0; i < numADs; i++) {
+ String method = null;
+
+ try {
+ method = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_METHOD,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_METHOD + "=" + method);
+ String location_type = null;
+
+ try {
+ location_type = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_LOCATION_TYPE,
+ IGeneralNameUtil.GENNAME_CHOICE_URL);
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE + "=" + location_type);
+ String location = null;
+
+ try {
+ location = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_LOCATION,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION + "=" + location);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NUM_ADS + "=" + MAX_AD);
+
+ //
+ // By default, we create MAX_AD access descriptions.
+ // If this is not enough, admin can manually edit
+ // the CMS.cfg
+ //
+ for (int i = 0; i < MAX_AD; i++) {
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_METHOD + "=");
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE + "=" + IGeneralNameUtil.GENNAME_CHOICE_URL);
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_LOCATION + "=");
+ }
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
new file mode 100644
index 000000000..b170925c4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
@@ -0,0 +1,418 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidKeyException;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Authority Public Key Extension Policy
+ * Adds the subject public key id extension to certificates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthorityKeyIdentifierExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_ALT_KEYID_TYPE = "AltKeyIdType";
+
+ protected static final String ALT_KEYID_TYPE_SPKISHA1 = "SpkiSHA1";
+ protected static final String ALT_KEYID_TYPE_NONE = "None";
+ protected static final String ALT_KEYID_TYPE_EMPTY = "Empty";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final String DEF_ALT_KEYID_TYPE = ALT_KEYID_TYPE_SPKISHA1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ // config params.
+ protected boolean mCritical = DEF_CRITICAL;
+ protected String mAltKeyIdType = DEF_ALT_KEYID_TYPE;
+
+ // the extension to add to certs.
+ protected AuthorityKeyIdentifierExtension mTheExtension = null;
+
+ // instance params for console
+ protected Vector mInstanceParams = new Vector();
+
+ // default params for console.
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ // form static default params.
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(PROP_ALT_KEYID_TYPE + "=" + DEF_ALT_KEYID_TYPE);
+ }
+
+ public AuthorityKeyIdentifierExt() {
+ NAME = "AuthorityKeyIdentifierExt";
+ DESC = "Adds Authority Key Idenifier Extension to certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * Reads configuration file and creates a authority key identifier
+ * extension to add. Key identifier inside the extension is constructed as
+ * the CA's subject key identifier extension if it exists.
+ * If it does not exist this can be configured to use:
+ * (1) sha-1 hash of the CA's subject public key info
+ * (what communicator expects if the CA does not have a subject key
+ * identifier extension) or (2) No extension set (3) Empty sequence
+ * in Authority Key Identifier extension.
+ *
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mAltKeyIdType = mConfig.getString(
+ PROP_ALT_KEYID_TYPE, DEF_ALT_KEYID_TYPE);
+
+ if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_SPKISHA1))
+ mAltKeyIdType = ALT_KEYID_TYPE_SPKISHA1;
+
+ /*
+ else if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_EMPTY))
+ mAltKeyIdType = ALT_KEYID_TYPE_EMPTY;
+ */
+ else if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_NONE))
+ mAltKeyIdType = ALT_KEYID_TYPE_NONE;
+ else {
+ log(ILogger.LL_FAILURE, NAME +
+ CMS.getLogMessage("CA_UNKNOWN_ALT_KEY_ID_TYPE", mAltKeyIdType));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", PROP_ALT_KEYID_TYPE,
+ "value must be one of " + ALT_KEYID_TYPE_SPKISHA1 + ", " + ALT_KEYID_TYPE_NONE));
+ }
+
+ // create authority key id extension.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ String msg = NAME + ": " +
+ "Cannot find the Certificate Manager or Registration Manager";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, NAME +
+ CMS.getLogMessage("POLICY_INVALID_POLICY", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ NAME + " policy can only be used in a Certificate Authority."));
+ }
+ //CertificateChain caChain = certAuthority.getCACertChain();
+ //X509Certificate caCert = caChain.getFirstCertificate();
+ X509CertImpl caCert = certAuthority.getCACert();
+ if( caCert == null || CMS.isPreOpMode() ) {
+ return;
+ }
+ KeyIdentifier keyId = formKeyIdentifier(caCert);
+
+ if (keyId != null) {
+ try {
+ mTheExtension = new AuthorityKeyIdentifierExtension(
+ mCritical, keyId, null, null);
+ } catch (IOException e) {
+ String msg = NAME + ": " +
+ "Error forming Authority Key Identifier extension: " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_AUTHORITY_KEY_ID_1", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ } else {
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(PROP_ALT_KEYID_TYPE + "=" + mAltKeyIdType);
+ }
+
+ /**
+ * Adds Authority Key Identifier Extension to a certificate.
+ * If the extension is already there, accept it if it's from the agent,
+ * else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, ci[i]);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // if authority key id extension already exists, leave it if
+ // from agent. else replace it.
+ AuthorityKeyIdentifierExtension authorityKeyIdExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ authorityKeyIdExt = (AuthorityKeyIdentifierExtension)
+ extensions.get(AuthorityKeyIdentifierExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+ if (authorityKeyIdExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: agent approved request id " + req.getRequestId() +
+ " already has authority key id extension with value " +
+ authorityKeyIdExt);
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: request id from user " + req.getRequestId() +
+ " had authority key identifier - deleted");
+ extensions.delete(AuthorityKeyIdentifierExtension.NAME);
+ }
+ }
+
+ // if no authority key identifier should be set b/c CA does not
+ // have a subject key identifier, return here.
+ if (mTheExtension == null)
+ return PolicyResult.ACCEPTED;
+
+ // add authority key id extension.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ AuthorityKeyIdentifierExtension.NAME, mTheExtension);
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: added authority key id ext to request " + req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, e.getMessage()), "");
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INVALID_CERT", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Certificate Info Error"), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Form the Key Identifier in the Authority Key Identifier extension.
+ * from the CA's cert.
+ * <p>
+ * @param caCertImpl Certificate Info
+ * @return A Key Identifier.
+ * @throws com.netscape.certsrv.base.EBaseException on error
+ */
+ protected KeyIdentifier formKeyIdentifier(X509CertImpl caCertImpl)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ // get CA's certInfo.
+ X509CertInfo certInfo = null;
+
+ try {
+ certInfo = (X509CertInfo) caCertImpl.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ if (certInfo == null) {
+ String msg = "Bad CA certificate encountered. " +
+ "TBS Certificate missing.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_CERT_FORMAT"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", NAME + ": " + msg));
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("BASE_DECODE_CERT_FAILED_1", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ NAME + " Error decoding the CA Certificate: " + e));
+ }
+
+ // get Key Id from CA's Subject Key Id extension in CA's CertInfo.
+ keyId = getKeyIdentifier(certInfo);
+ if (keyId != null)
+ return keyId;
+
+ // if none exists use the configured alternate.
+ if (mAltKeyIdType == ALT_KEYID_TYPE_SPKISHA1) {
+ keyId = formSpkiSHA1KeyId(certInfo);
+ } /*
+ else if (mAltKeyIdType == ALT_KEYID_TYPE_EMPTY) {
+ keyId = formEmptyKeyId(certInfo);
+ }
+ */ else if (mAltKeyIdType == ALT_KEYID_TYPE_NONE) {
+ keyId = null;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mAltKeyIdType,
+ "Unknown Alternate Key Identifier type."));
+ }
+ return keyId;
+ }
+
+ /**
+ * Get the Key Identifier in a subject key identifier extension from a
+ * CertInfo.
+ * @param certInfo the CertInfo structure.
+ * @return Key Identifier in a Subject Key Identifier extension if any.
+ */
+ protected KeyIdentifier getKeyIdentifier(X509CertInfo certInfo)
+ throws EBaseException {
+ CertificateExtensions exts = null;
+ SubjectKeyIdentifierExtension subjKeyIdExt = null;
+ KeyIdentifier keyId = null;
+
+ try {
+ exts = (CertificateExtensions) certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // extension isn't there.
+ CMS.debug(NAME + ": " + "No extensions found. Error " + e);
+ return null;
+ } catch (CertificateException e) {
+ // extension isn't there.
+ CMS.debug(NAME + ": " + "No extensions found. Error " + e);
+ return null;
+ }
+ if (exts == null)
+ return null;
+
+ try {
+ subjKeyIdExt = (SubjectKeyIdentifierExtension)
+ exts.get(SubjectKeyIdentifierExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: No Subject Key Identifier Extension found. Error: " + e);
+ return null;
+ }
+ if (subjKeyIdExt == null)
+ return null;
+
+ try {
+ keyId = (KeyIdentifier) subjKeyIdExt.get(
+ SubjectKeyIdentifierExtension.KEY_ID);
+ } catch (IOException e) {
+ // no key identifier in subject key id extension.
+ String msg = NAME + ": " +
+ "Bad Subject Key Identifier Extension found. Error: " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_AUTHORITY_KEY_ID_1", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ return keyId;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST NOT be marked critical.",
+ PROP_ALT_KEYID_TYPE + ";" +
+ "choice(" + ALT_KEYID_TYPE_SPKISHA1 + "," + ALT_KEYID_TYPE_NONE + ");" +
+ "Specifies whether to use a SHA1 hash of the CA's subject " +
+ "public key info for key identifier or leave out the " +
+ "authority key identifier extension if the CA certificate " +
+ "does not have a Subject Key Identifier extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-authkeyid",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Authority Key Identifier Extension. " +
+ "See RFC 2459 (4.2.1.1)"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
new file mode 100644
index 000000000..73a6b58af
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
@@ -0,0 +1,498 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Basic Constraints policy.
+ * Adds the Basic constraints extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class BasicConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_MAXPATHLEN = "maxPathLen";
+ protected static final String PROP_IS_CA = "isCA";
+ protected static final String PROP_IS_CRITICAL = "critical";
+
+ protected static final String ARG_PATHLEN = "BasicConstraintsPathLen";
+
+ protected int mMaxPathLen = 0; // < 0 means unlimited
+ protected String mOrigMaxPathLen = ""; // for UI display only
+ protected boolean mCritical = true;
+ protected int mDefaultMaxPathLen = 0; // depends on the CA's path length.
+ protected int mCAPathLen = 0;
+ protected boolean mRemoveExt = true;
+ protected boolean mIsCA = true;
+
+ public static final boolean DEFAULT_CRITICALITY = true;
+
+ /**
+ * Adds the basic constraints extension as a critical extension in
+ * CA certificates i.e. certype is ca, with either a requested
+ * or configured path len.
+ * The requested or configured path length cannot be greater than
+ * or equal to the CA's basic constraints path length.
+ * If the CA path length is 0, all requests for CA certs are rejected.
+ */
+ public BasicConstraintsExt() {
+ NAME = "BasicConstraintsExt";
+ DESC =
+ "Sets critical basic constraints extension in subordinate CA certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <p>
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=BasicConstraintsExtImpl
+ * ca.Policy.rule.<ruleName>.pathLen=<n>, -1 for undefined.
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ // get the CA's path len to check against configured max path len.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager or Registration Manager"));
+ }
+ if (certAuthority instanceof IRegistrationAuthority) {
+ log(ILogger.LL_WARN,
+ "default basic constraints extension path len to -1.");
+ mCAPathLen = -1;
+ } else {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ if( caChain == null || CMS.isPreOpMode() ) {
+ return;
+ }
+ X509Certificate caCert = caChain.getFirstCertificate();
+
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ // set default to one less than the CA's pathlen or 0 if CA's
+ // pathlen is 0.
+ // If it's unlimited default the max pathlen also to unlimited.
+ if (mCAPathLen < 0)
+ mDefaultMaxPathLen = -1;
+ else if (mCAPathLen > 0)
+ mDefaultMaxPathLen = mCAPathLen - 1;
+ else // (mCAPathLen == 0)
+ {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("POLICY_PATHLEN_ZERO"));
+ //return;
+ }
+
+ // get configured max path len, use defaults if not configured.
+ boolean pathLenConfigured = true;
+
+ try {
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, true);
+ mIsCA = config.getBoolean(PROP_IS_CA, true);
+ mMaxPathLen = config.getInteger(PROP_MAXPATHLEN);
+ if (mMaxPathLen < 0) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN_4", "",
+ String.valueOf(mMaxPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_MAXPATHLEN_1",
+ NAME, String.valueOf(mMaxPathLen)));
+ }
+ mOrigMaxPathLen = Integer.toString(mMaxPathLen);
+ } catch (EBaseException e) {
+ if (!(e instanceof EPropertyNotFound) &&
+ !(e instanceof EPropertyNotDefined)) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN"));
+ throw e;
+ }
+
+ // Set the max path len to default if not configured.
+ pathLenConfigured = false;
+ mMaxPathLen = mDefaultMaxPathLen;
+ mOrigMaxPathLen = "";
+ }
+
+ // check if configured path len is valid.
+ if (pathLenConfigured) {
+ // if CA's pathlen is unlimited, any max pathlen is ok.
+ // else maxPathlen must be at most one less than the CA's
+ // pathlen or 0 if CA's pathlen is 0.
+
+ if (mCAPathLen > 0 &&
+ (mMaxPathLen >= mCAPathLen || mMaxPathLen < 0)) {
+ String maxStr = (mMaxPathLen < 0) ?
+ String.valueOf(mMaxPathLen) + "(unlimited)" :
+ String.valueOf(mMaxPathLen);
+
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_MAXPATHLEN_TOO_BIG_3", "",
+ maxStr,
+ String.valueOf(mCAPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG_1",
+ NAME, maxStr, Integer.toString(mCAPathLen)));
+ } else if (mCAPathLen == 0 && mMaxPathLen != 0) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN_2", "", String.valueOf(mMaxPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_MAXPATHLEN",
+ NAME, String.valueOf(mMaxPathLen)));
+ }
+ }
+
+ }
+
+ /**
+ * Checks if the basic contraints extension in certInfo is valid and
+ * add the basic constraints extension for CA certs if none exists.
+ * Non-CA certs do not get a basic constraints extension.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ // get cert type
+ boolean isCA = mIsCA;
+
+ /**
+ boolean isCA = false;
+ String type = (String)req.get(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+ if (type != null && type.equalsIgnoreCase(IRequest.CA_CERT)) {
+ isCA = true;
+ }
+ **/
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, isCA, certInfo);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(
+ IRequest req, boolean isCA, X509CertInfo certInfo) {
+
+ // get basic constraints extension from cert info if any.
+ CertificateExtensions extensions = null;
+ BasicConstraintsExtension basicExt = null;
+
+ try {
+ // get basic constraints extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions != null) {
+ basicExt = (BasicConstraintsExtension)
+ extensions.get(BasicConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // no extensions or basic constraints extension.
+ } catch (CertificateException e) {
+ // no extensions or basic constraints extension.
+ }
+
+ // for non-CA certs, pkix says it SHOULD NOT have the extension
+ // so remove it.
+ if (!isCA) {
+ if (extensions == null) {
+ try {
+ // create extensions set if none.
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ } catch (IOException e) {
+ // not possible
+ }
+ }
+ if (basicExt != null) {
+ try {
+ extensions.delete(BasicConstraintsExtension.NAME);
+ } catch (IOException e) {
+ }
+ }
+
+ BasicConstraintsExtension critExt;
+
+ try {
+ critExt = new BasicConstraintsExtension(isCA, mCritical, mMaxPathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_2",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ extensions.set(BasicConstraintsExtension.NAME, critExt);
+ } catch (IOException e) {
+ }
+ CMS.debug(
+ "BasicConstraintsExt: PolicyRule BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ // For CA certs, check if existing extension is valid, and adjust.
+ // Extension must be marked critial and pathlen must be < CA's pathlen.
+ // if CA's pathlen is 0 all ca certs are rejected.
+
+ if (mCAPathLen == 0) {
+ // reject all subordinate CA cert requests because CA's
+ // path length is 0.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_NO_SUB_CA_CERTS_ALLOWED_1", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ if (basicExt != null) {
+ try {
+ boolean extIsCA =
+ ((Boolean) basicExt.get(BasicConstraintsExtension.IS_CA)).booleanValue();
+ int pathLen =
+ ((Integer) basicExt.get(BasicConstraintsExtension.PATH_LEN)).intValue();
+
+ if (mMaxPathLen > -1) {
+ if (pathLen > mMaxPathLen || pathLen < 0) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_MAXPATHLEN_TOO_BIG_3", NAME, "unlimited", String.valueOf(pathLen)));
+ if (pathLen < 0)
+ setError(req, CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG",
+ NAME, "unlimited", Integer.toString(mMaxPathLen)), "");
+ else
+ setError(req, CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG",
+ NAME, Integer.toString(pathLen),
+ Integer.toString(mMaxPathLen)), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ // adjust isCA field
+ if (!extIsCA) {
+ basicExt.set(BasicConstraintsExtension.IS_CA,
+ Boolean.valueOf(true));
+ }
+
+ // adjust path length field.
+ if (mMaxPathLen == 0) {
+ if (pathLen != 0) {
+ basicExt.set(BasicConstraintsExtension.PATH_LEN,
+ Integer.valueOf(0));
+ pathLen = 0;
+ }
+ } else if (mMaxPathLen > 0 && pathLen > mMaxPathLen) {
+ basicExt.set(BasicConstraintsExtension.PATH_LEN,
+ Integer.valueOf(mMaxPathLen));
+ pathLen = mMaxPathLen;
+ }
+
+ // adjust critical field.
+ if (!basicExt.isCritical()) {
+ BasicConstraintsExtension critExt;
+
+ try {
+ critExt = new BasicConstraintsExtension(isCA, mCritical, pathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ extensions.delete(BasicConstraintsExtension.NAME);
+ extensions.set(BasicConstraintsExtension.NAME, critExt);
+ }
+ } catch (IOException e) {
+ // not possible in these cases.
+ }
+ CMS.debug(
+ "BasicConstraintsExt: PolicyRule BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ // add the extension for the CA cert.
+ if (extensions == null) {
+ try {
+ // create extensions set if none.
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ // not possible
+ } catch (IOException e) {
+ // not possible
+ }
+ }
+
+ // set path len to requested path len if it's valid.
+ // if no path len requested set path len to max allowed path len.
+ String reqPathLenStr = req.getExtDataInString(ARG_PATHLEN);
+ int reqPathLen;
+
+ if (reqPathLenStr == null) {
+ reqPathLen = mMaxPathLen;
+ } else {
+ try {
+ reqPathLen = Integer.parseInt(reqPathLenStr);
+ if ((mMaxPathLen == 0 && reqPathLen != 0) ||
+ (mMaxPathLen > 0 &&
+ (reqPathLen > mMaxPathLen || reqPathLen < 0))) {
+ String plenStr =
+ ((reqPathLen < 0) ?
+ reqPathLenStr + "(unlimited)" : reqPathLenStr);
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_PATHLEN_TOO_BIG_3", plenStr,
+ String.valueOf(mMaxPathLen)));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_PATHLEN_TOO_BIG",
+ NAME, plenStr, String.valueOf(mMaxPathLen)), "");
+ return PolicyResult.REJECTED;
+ }
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_INVALID_PATHLEN_FORMAT_2", NAME, reqPathLenStr));
+ setError(req, CMS.getUserMessage("CMS_POLICY_INVALID_PATHLEN_FORMAT",
+ NAME, reqPathLenStr), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ BasicConstraintsExtension newExt;
+
+ try {
+ newExt = new BasicConstraintsExtension(isCA, mCritical, reqPathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_2", e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ try {
+ extensions.set(BasicConstraintsExtension.NAME, newExt);
+ }catch (IOException e) {
+ // doesn't happen.
+ }
+ CMS.debug(
+ "BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ // Because of one of the UI bugs 385273, we should leave the empty space
+ // as is. Do not convert the space to some definite numbers.
+ params.addElement(PROP_MAXPATHLEN + "=" + mOrigMaxPathLen);
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_IS_CA + "=" + mIsCA);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_IS_CRITICAL + "=true");
+ defParams.addElement(PROP_MAXPATHLEN + "=");
+ defParams.addElement(PROP_IS_CA + "=true");
+ return defParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MAXPATHLEN + ";number;'0' means : no subordinates allowed, 'n' means : at most n subordinates allowed.",
+ PROP_IS_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST be critical in CA certs, SHOULD NOT appear in EE certs.",
+ PROP_IS_CA + ";boolean;" +
+ "Identifies the subject of the certificate is a CA or not.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-basicconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds the Basic Constraints extension. See RFC 2459 (4.2.1.10)"
+ };
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
new file mode 100644
index 000000000..84664b09d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
@@ -0,0 +1,464 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.util.BitArray;
+import netscape.security.x509.*;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * The type of the distribution point or issuer name. The name is expressed
+ * as a simple string in the configuration file, so this attribute is needed
+ * to tell whether the simple string should be stored in an X.500 Name,
+ * a URL, or an RDN.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+class NameType {
+ private NameType() {
+ } // no default constructor
+
+ private String stringRep; // string representation of this type
+
+ private NameType(String s) {
+ map.put(s, this);
+ stringRep = s;
+ }
+
+ private static Hashtable map = new Hashtable();
+
+ /**
+ * Looks up a NameType from its string representation. Returns null
+ * if no matching NameType was found.
+ */
+ public static NameType fromString(String s) {
+ return (NameType) map.get(s);
+ }
+
+ public String toString() {
+ return stringRep;
+ }
+
+ public static final NameType DIRECTORY_NAME = new NameType("DirectoryName");
+ public static final NameType URI = new NameType("URI");
+ public static final NameType RELATIVE_TO_ISSUER =
+ new NameType("RelativeToIssuer");
+}
+
+
+/**
+ * These are the parameters that may be given in the configuration file
+ * for each distribution point. They are parsed by DPParamsToDP().
+ * Any of them may be null.
+ */
+class DistPointParams {
+ public String pointName;
+ public String pointType;
+
+ public String reasons;
+
+ public String issuerName;
+ public String issuerType;
+
+ public DistPointParams() {
+ }
+
+ public DistPointParams(DistPointParams old) {
+ pointName = old.pointName;
+ pointType = old.pointType;
+ reasons = old.reasons;
+ issuerName = old.issuerName;
+ issuerType = old.issuerType;
+ }
+
+}
+
+
+/**
+ * CRL Distribution Points policy.
+ * Adds the CRL Distribution Points extension to the certificate.
+ */
+public class CRLDistributionPointsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ public static final String PROP_IS_CRITICAL = "critical";
+ public static final String PROP_NUM_POINTS = "numPoints";
+ public static final String PROP_POINT_TYPE = "pointType";
+ public static final String PROP_POINT_NAME = "pointName";
+ public static final String PROP_REASONS = "reasons";
+ public static final String PROP_ISSUER_NAME = "issuerName";
+ public static final String PROP_ISSUER_TYPE = "issuerType";
+
+ private static final int MAX_POINTS = 10;
+ private static final int DEFAULT_NUM_BLANK_POINTS = 3;
+ private int mNumPoints = DEFAULT_NUM_BLANK_POINTS;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private Vector defaultParams = new Vector();
+
+ private Vector mParams = new Vector();
+ private String mExtParams[] = null;
+ private CRLDistributionPointsExtension mCrldpExt = null;
+
+ public CRLDistributionPointsExt() {
+ NAME = "CRLDistributionPointsExt";
+ DESC = "Sets CRL distribution points extension";
+ defaultParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defaultParams.addElement(PROP_NUM_POINTS + "=0");
+ for (int i = 0; i < DEFAULT_NUM_BLANK_POINTS; i++) {
+ defaultParams.addElement(PROP_POINT_NAME + i + "=");
+ defaultParams.addElement(PROP_POINT_TYPE + i + "=");
+ defaultParams.addElement(PROP_REASONS + i + "=");
+ defaultParams.addElement(PROP_ISSUER_NAME + i + "=");
+ defaultParams.addElement(PROP_ISSUER_TYPE + i + "=");
+ }
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+
+ // should replace MAX_POINTS with mNumPoints if bug 385118 is fixed
+ for (int i = 0; i < MAX_POINTS; i++) {
+ v.addElement(PROP_POINT_TYPE + Integer.toString(i) + ";choice(" +
+ "DirectoryName,URI,RelativeToIssuer);" +
+ "The type of the CRL distribution point.");
+ v.addElement(PROP_POINT_NAME + Integer.toString(i) + ";string;" +
+ "The name of the CRL distribution point depending on the CRLDP type.");
+ v.addElement(PROP_REASONS + Integer.toString(i) + ";string;" +
+ "The revocation reasons for the CRL maintained at this distribution point. It's a comma-seperated list of the following constants: unused, keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold.");
+ v.addElement(PROP_ISSUER_TYPE + Integer.toString(i) + ";choice(" +
+ "DirectoryName,URI);" +
+ "The type of the issuer that has signed the CRL maintained at this distribution point.");
+ v.addElement(PROP_ISSUER_NAME + Integer.toString(i) + ";string;" +
+ "The name of the issuer that has signed the CRL maintained at this distribution point. The value depends on the issuer type.");
+ }
+
+ v.addElement(PROP_NUM_POINTS +
+ ";number;The total number of CRL distribution points to be contained or allowed in the extension.");
+ v.addElement(PROP_IS_CRITICAL +
+ ";boolean;RFC 2459 recommendation: SHOULD be non-critical. But recommends support for this extension by CAs and applications.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-crldistributionpoints");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the CRL Distribution Points " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.14). "
+ );
+
+ mExtParams = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (mExtParams == null) {
+ setExtendedPluginInfo();
+ }
+ return mExtParams;
+
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // Register the CRL Distribution Points extension.
+ try {
+ netscape.security.x509.OIDMap.addAttribute(
+ CRLDistributionPointsExtension.class.getName(),
+ CRLDistributionPointsExtension.OID,
+ CRLDistributionPointsExtension.NAME);
+ } catch (CertificateException e) {
+ // ignore, just means it has already been added
+ }
+
+ // assemble the list of Distribution Points from the config file
+ int numPoints = config.getInteger(PROP_NUM_POINTS, 0);
+
+ mParams.addElement(PROP_NUM_POINTS + "=" + numPoints);
+ mNumPoints = numPoints;
+
+ for (int i = 0; i < numPoints; i++) {
+ // construct a distribution point from the parameters
+ DistPointParams params = new DistPointParams();
+
+ params.pointType = config.getString(PROP_POINT_TYPE + i, "");
+ params.pointName = config.getString(PROP_POINT_NAME + i, "");
+ params.reasons = config.getString(PROP_REASONS + i, "");
+ params.issuerType = config.getString(PROP_ISSUER_TYPE + i, "");
+ params.issuerName = config.getString(PROP_ISSUER_NAME + i, "");
+
+ DistPointParams configparams = new DistPointParams(params);
+ CRLDistributionPoint crldp = DPParamsToDP(params);
+
+ mParams.addElement(PROP_POINT_TYPE + i + "=" + configparams.pointType);
+ mParams.addElement(PROP_POINT_NAME + i + "=" + configparams.pointName);
+ mParams.addElement(PROP_REASONS + i + "=" + configparams.reasons);
+ mParams.addElement(PROP_ISSUER_TYPE + i + "=" + configparams.issuerType);
+ mParams.addElement(PROP_ISSUER_NAME + i + "=" + configparams.issuerName);
+
+ // add the distribution point to the extension
+ if (mCrldpExt == null) {
+ mCrldpExt = new CRLDistributionPointsExtension(crldp);
+ } else {
+ mCrldpExt.addPoint(crldp);
+ }
+ }
+
+ boolean crit = config.getBoolean(PROP_IS_CRITICAL,
+ DEFAULT_CRITICALITY);
+
+ mParams.addElement(PROP_IS_CRITICAL + "=" + crit);
+ if (mCrldpExt != null) {
+ // configure the extension itself
+ mCrldpExt.setCritical(crit);
+ }
+ setExtendedPluginInfo();
+
+ }
+
+ /**
+ * Parses the parameters in the config file to create an
+ * actual CRL Distribution Point object.
+ */
+ private CRLDistributionPoint DPParamsToDP(DistPointParams params)
+ throws EBaseException {
+ CRLDistributionPoint crlDP = new CRLDistributionPoint();
+
+ try {
+
+ if (params.pointName != null && params.pointName.length() == 0) {
+ params.pointName = null;
+ }
+ if (params.pointType != null && params.pointType.length() == 0) {
+ params.pointType = null;
+ }
+ if (params.reasons != null && params.reasons.length() == 0) {
+ params.reasons = null;
+ }
+ if (params.issuerName != null && params.issuerName.length() == 0) {
+ params.issuerName = null;
+ }
+ if (params.issuerType != null && params.issuerType.length() == 0) {
+ params.issuerType = null;
+ }
+
+ // deal with the distribution point name
+ if (params.pointName != null && params.pointType != null) {
+ // decode the type of the name
+ NameType nType = NameType.fromString(params.pointType);
+
+ if (nType == null) {
+ String err = "Unknown name type: " + params.pointType;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", params.pointType));
+ throw new EBaseException(err);
+ }
+
+ if (nType == NameType.DIRECTORY_NAME) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new X500Name(params.pointName)));
+ crlDP.setFullName(gen);
+ } else if (nType == NameType.URI) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new URIName(params.pointName)));
+ crlDP.setFullName(gen);
+ } else if (nType == NameType.RELATIVE_TO_ISSUER) {
+ crlDP.setRelativeName(new RDN(params.pointName));
+ } else {
+ String err = "Unknown name type: " + nType.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", nType.toString()));
+ throw new EBaseException(err);
+ }
+ }
+
+ // deal with the reasons
+ if (params.reasons != null) {
+ StringTokenizer tok = new StringTokenizer(params.reasons, ", \t");
+ byte reasonBits = 0;
+
+ while (tok.hasMoreTokens()) {
+ String s = tok.nextToken();
+ Reason r = Reason.fromString(s);
+
+ if (r == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_REASON", s));
+ throw new EBaseException("Unknown reason: " + s);
+ } else {
+ reasonBits |= r.getBitMask();
+ }
+ }
+ if (reasonBits != 0) {
+ BitArray ba = new BitArray(8, new byte[] { reasonBits }
+ );
+
+ crlDP.setReasons(ba);
+ }
+ }
+
+ // deal with the issuer name
+ if (params.issuerName != null && params.issuerType != null) {
+ // decode the type of the name
+ NameType nType = NameType.fromString(params.issuerType);
+
+ if (nType == null) {
+ String err = "Unknown name type: " + params.issuerType;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", params.issuerType));
+ throw new EBaseException(err);
+ }
+
+ if (nType == NameType.DIRECTORY_NAME) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new X500Name(params.issuerName)));
+ crlDP.setCRLIssuer(gen);
+ } else if (nType == NameType.URI) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new URIName(params.issuerName)));
+ crlDP.setCRLIssuer(gen);
+ } else {
+ String err = "Unknown name type: " + nType.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", nType.toString()));
+ throw new EBaseException(err);
+ }
+ }
+
+ } catch (GeneralNamesException e) {
+ throw new EBaseException(e.getMessage());
+ } catch (IOException e) {
+ throw new EBaseException(e.getMessage());
+ }
+
+ // done, return this distribution point
+ return crlDP;
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mCrldpExt == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CRLDistributionPointsExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+ extensions.set(CRLDistributionPointsExtension.NAME, mCrldpExt);
+
+ return PolicyResult.ACCEPTED;
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR",
+ e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ // parameters must be entered in the config file
+ public Vector getDefaultParams() {
+ for (int i = DEFAULT_NUM_BLANK_POINTS; i < mNumPoints; i++) {
+ defaultParams.addElement(PROP_POINT_NAME + i + "=");
+ defaultParams.addElement(PROP_POINT_TYPE + i + "=");
+ defaultParams.addElement(PROP_REASONS + i + "=");
+ defaultParams.addElement(PROP_ISSUER_NAME + i + "=");
+ defaultParams.addElement(PROP_ISSUER_TYPE + i + "=");
+ }
+ return defaultParams;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
new file mode 100644
index 000000000..bcf9d11cb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
@@ -0,0 +1,521 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.x509.PolicyQualifierInfo;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Policies.
+ * Adds certificate policies extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificatePoliciesExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_CERTPOLICIES = "numCertPolicies";
+
+ protected static final String PROP_CERTPOLICY = "certPolicy";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_CERTPOLICIES = 1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumCertPolicies = DEF_NUM_CERTPOLICIES;
+ protected CertPolicy[] mCertPolicies = null;
+
+ protected Vector mInstanceParams = new Vector();
+ protected CertificatePoliciesExtension mCertificatePoliciesExtension = null;
+
+ public CertificatePoliciesExt() {
+ NAME = "CertificatePoliciesExt";
+ DESC = "Sets non-critical certificate policies extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mNumCertPolicies = mConfig.getInteger(
+ PROP_NUM_CERTPOLICIES, DEF_NUM_CERTPOLICIES);
+ if (mNumCertPolicies < 1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_ATTR_VALUE_2", NAME, ""));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_CERTPOLICIES,
+ "value must be greater than or equal to 1"));
+ }
+
+ // init Policy Mappings, check values if enabled.
+ mCertPolicies = new CertPolicy[mNumCertPolicies];
+ for (int i = 0; i < mNumCertPolicies; i++) {
+ String subtreeName = PROP_CERTPOLICY + i;
+
+ try {
+ mCertPolicies[i] = new CertPolicy(subtreeName, mConfig, mEnabled);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("POLICY_ERROR_CREATE_CERT_POLICY", e.toString()));
+ throw e;
+ }
+ }
+
+ // create instance of certificate policy extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector CertPolicies = new Vector();
+
+ for (int j = 0; j < mNumCertPolicies; j++) {
+ CertPolicies.addElement(
+ mCertPolicies[j].mCertificatePolicyInfo);
+ }
+ mCertificatePoliciesExtension =
+ new CertificatePoliciesExtension(mCritical, CertPolicies);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing " + NAME + " Error: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_CERTPOLICIES + "=" + mNumCertPolicies);
+ for (int i = 0; i < mNumCertPolicies; i++) {
+ mCertPolicies[i].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CertificatePoliciesExtension.NAME);
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.5.29.32");
+ } catch (IOException ee) {
+ }
+ }
+ }
+ extensions.set(CertificatePoliciesExtension.NAME,
+ mCertificatePoliciesExtension);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_CERTPOLICIES + "=" + DEF_NUM_CERTPOLICIES);
+ String certPolicy0Dot = PROP_CERTPOLICY + "0.";
+
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_POLICY_IDENTIFIER + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_NOTICE_REF_ORG + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_NOTICE_REF_NUMS + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_USER_NOTICE_TEXT + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_CPS_URI + "=" + "");
+
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 3280 recommendation: MUST be non-critical.");
+ theparams.addElement(PROP_NUM_CERTPOLICIES + ";number; Number of certificate policies. The value must be greater than or equal to 1");
+
+ for (int k = 0; k < 5; k++) {
+ String certPolicykDot = PROP_CERTPOLICY + k + ".";
+
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_POLICY_IDENTIFIER + ";string,required;An object identifier in the form n.n.n.n");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_NOTICE_REF_ORG + ";string;See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_NOTICE_REF_NUMS +
+ ";string;comma-separated list of numbers. See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_USER_NOTICE_TEXT + ";string;See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_CPS_URI + ";string;See RFC 3280 sec 4.2.1.5");
+ }
+
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificatepolicies");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Certificate Policies Extension. See RFC 3280 (4.2.1.5)");
+
+ String[] params = new String[theparams.size()];
+
+ theparams.copyInto(params);
+ return params;
+ }
+}
+
+
+class CertPolicy {
+
+ protected static final String PROP_POLICY_IDENTIFIER = "policyId";
+ protected static final String PROP_NOTICE_REF_ORG = "noticeRefOrganization";
+ protected static final String PROP_NOTICE_REF_NUMS = "noticeRefNumbers";
+ protected static final String PROP_USER_NOTICE_TEXT = "userNoticeExplicitText";
+ protected static final String PROP_CPS_URI = "cpsURI";
+
+ protected String mName = null;
+ protected String mNameDot = null;
+ protected IConfigStore mConfig = null;
+
+ protected String mPolicyId = null;
+ protected String mNoticeRefOrg = null;
+ protected String mNoticeRefNums = null;
+ protected String mNoticeRefExplicitText = null;
+ protected String mCpsUri = null;
+
+ protected CertificatePolicyInfo mCertificatePolicyInfo = null;
+
+ /**
+ * forms policy map parameters.
+ * @param name name of this policy map, for example certPolicy0
+ * @param config parent's config from where we find this configuration.
+ * @param enabled whether policy was enabled.
+ */
+ protected CertPolicy(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ mName = name;
+ mConfig = config.getSubStore(mName);
+ mNameDot = mName + ".";
+
+ if( mConfig == null ) {
+ CMS.debug( "CertificatePoliciesExt::CertPolicy - mConfig is " +
+ "null!" );
+ throw new EBaseException( "mConfig is null" );
+ }
+
+ // if there's no configuration for this policy put it there.
+ if (mConfig.size() == 0) {
+ config.putString(mNameDot + PROP_POLICY_IDENTIFIER, "");
+ config.putString(mNameDot + PROP_NOTICE_REF_ORG, "");
+ config.putString(mNameDot + PROP_NOTICE_REF_NUMS, "");
+ config.putString(mNameDot + PROP_USER_NOTICE_TEXT, "");
+ config.putString(mNameDot + PROP_CPS_URI, "");
+ mConfig = config.getSubStore(mName);
+ if(mConfig == null || mConfig.size() == 0) {
+ CMS.debug( "CertificatePoliciesExt::CertPolicy - mConfig " +
+ "is null or empty!" );
+ throw new EBaseException( "mConfig is null or empty" );
+ }
+ }
+
+ // get policy ids from configuration.
+ mPolicyId = mConfig.getString(PROP_POLICY_IDENTIFIER, null);
+ mNoticeRefOrg = mConfig.getString(PROP_NOTICE_REF_ORG, null);
+ mNoticeRefNums = mConfig.getString(PROP_NOTICE_REF_NUMS, null);
+ mNoticeRefExplicitText = mConfig.getString(PROP_USER_NOTICE_TEXT, null);
+ mCpsUri = mConfig.getString(PROP_CPS_URI, null);
+
+ // adjust for "" and console returning "null"
+ if (mPolicyId != null &&
+ (mPolicyId.length() == 0 ||
+ mPolicyId.equals("null"))) {
+ mPolicyId = null;
+ }
+ if (mNoticeRefOrg != null &&
+ (mNoticeRefOrg.length() == 0 ||
+ mNoticeRefOrg.equals("null"))) {
+ mNoticeRefOrg = null;
+ }
+ if (mNoticeRefNums != null &&
+ (mNoticeRefNums.length() == 0 ||
+ mNoticeRefNums.equals("null"))) {
+ mNoticeRefNums = null;
+ }
+ if (mNoticeRefExplicitText != null &&
+ (mNoticeRefExplicitText.length() == 0 ||
+ mNoticeRefExplicitText.equals("null"))) {
+ mNoticeRefExplicitText = null;
+ }
+ if (mCpsUri != null &&
+ (mCpsUri.length() == 0 ||
+ mCpsUri.equals("null"))) {
+ mCpsUri = null;
+ }
+
+ // policy ids cannot be null if policy is enabled.
+ String msg = "value cannot be null.";
+
+ if (mPolicyId == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_POLICY_IDENTIFIER, msg));
+ msg = "NoticeReference is optional; If chosen to include, NoticeReference must at least has 'organization'";
+ if (mNoticeRefOrg == null && mNoticeRefNums != null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_NOTICE_REF_ORG, msg));
+
+ // if a policy id is not null check that it is a valid OID.
+ ObjectIdentifier policyId = null;
+
+ if (mPolicyId != null)
+ policyId = CMS.checkOID(
+ mNameDot + PROP_POLICY_IDENTIFIER, mPolicyId);
+
+ // if enabled, form CertificatePolicyInfo to be encoded in
+ // extension. Policy ids should be all set.
+ if (enabled) {
+ CMS.debug("CertPolicy: in CertPolicy");
+ DisplayText displayText = null;
+
+ if (mNoticeRefExplicitText != null &&
+ !mNoticeRefExplicitText.equals(""))
+ displayText = new DisplayText(DisplayText.tag_VisibleString, mNoticeRefExplicitText);
+ // new DisplayText(DisplayText.tag_IA5String, mNoticeRefExplicitText);
+ DisplayText orgName = null;
+
+ if (mNoticeRefOrg != null &&
+ !mNoticeRefOrg.equals(""))
+ orgName =
+ new DisplayText(DisplayText.tag_VisibleString, mNoticeRefOrg);
+ // new DisplayText(DisplayText.tag_VisibleString, mNoticeRefOrg);
+
+ int[] nums = new int[0];;
+ if (mNoticeRefNums != null &&
+ !mNoticeRefNums.equals("")) {
+
+ // should add a method to NoticeReference to take a
+ // Vector...but let's do this for now
+
+ Vector numsVector = new Vector();
+ StringTokenizer tokens = new StringTokenizer(mNoticeRefNums,
+ ",");
+
+ while (tokens.hasMoreTokens()) {
+ String num = tokens.nextToken().trim();
+
+ numsVector.addElement(num);
+ }
+
+ nums = new int[numsVector.size()];
+
+ for (int i = 0; i < numsVector.size(); i++) {
+ Integer ii = new Integer((String) numsVector.elementAt(i));
+
+ nums[i] = ii.intValue();
+ }
+ }
+ CertificatePolicyId cpolicyId = null;
+
+ try {
+ cpolicyId = new CertificatePolicyId(ObjectIdentifier.getObjectIdentifier(mPolicyId));
+ } catch (Exception e) {
+ throw new
+ EBaseException(CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR", mPolicyId));
+ }
+
+ PolicyQualifiers policyQualifiers = new PolicyQualifiers();
+
+ NoticeReference noticeReference = null;
+
+ if (orgName != null)
+ noticeReference = new NoticeReference(orgName, nums);
+
+ UserNotice userNotice = null;
+
+ if (displayText != null || noticeReference != null) {
+ userNotice = new UserNotice (noticeReference, displayText);
+
+ PolicyQualifierInfo policyQualifierInfo1 =
+ new PolicyQualifierInfo(PolicyQualifierInfo.QT_UNOTICE, userNotice);
+
+ policyQualifiers.add(policyQualifierInfo1);
+ }
+
+ CPSuri cpsUri = null;
+
+ if (mCpsUri != null && mCpsUri.length() > 0) {
+ cpsUri = new CPSuri (mCpsUri);
+ PolicyQualifierInfo policyQualifierInfo2 =
+ new PolicyQualifierInfo(PolicyQualifierInfo.QT_CPS, cpsUri);
+
+ policyQualifiers.add(policyQualifierInfo2);
+ }
+
+ if ((mNoticeRefOrg == null || mNoticeRefOrg.equals("")) &&
+ (mNoticeRefExplicitText == null || mNoticeRefExplicitText.equals("")) &&
+ (mCpsUri == null || mCpsUri.equals(""))) {
+ CMS.debug("CertPolicy mNoticeRefOrg = "+mNoticeRefOrg);
+ CMS.debug("CertPolicy mNoticeRefExplicitText = "+mNoticeRefExplicitText);
+ CMS.debug("CertPolicy mCpsUri = "+mCpsUri);
+
+ mCertificatePolicyInfo = new CertificatePolicyInfo(cpolicyId);
+ } else {
+ CMS.debug("CertPolicy mNoticeRefOrg = "+mNoticeRefOrg);
+ CMS.debug("CertPolicy mNoticeRefExplicitText = "+mNoticeRefExplicitText);
+ CMS.debug("CertPolicy mCpsUri = "+mCpsUri);
+ mCertificatePolicyInfo = new CertificatePolicyInfo(cpolicyId, policyQualifiers);
+ }
+ }
+ }
+
+ protected void getInstanceParams(Vector instanceParams) {
+ instanceParams.addElement(
+ mNameDot + PROP_POLICY_IDENTIFIER + "=" + (mPolicyId == null ? "" :
+ mPolicyId));
+ instanceParams.addElement(
+ mNameDot + PROP_NOTICE_REF_ORG + "=" + (mNoticeRefOrg == null ? "" :
+ mNoticeRefOrg));
+ instanceParams.addElement(
+ mNameDot + PROP_NOTICE_REF_NUMS + "=" + (mNoticeRefNums == null ? "" :
+ mNoticeRefNums));
+ instanceParams.addElement(
+ mNameDot + PROP_USER_NOTICE_TEXT + "=" + (mNoticeRefExplicitText == null ? "" :
+ mNoticeRefExplicitText));
+ instanceParams.addElement(
+ mNameDot + PROP_CPS_URI + "=" + (mCpsUri == null ? "" :
+ mCpsUri));
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
new file mode 100644
index 000000000..e761ecfab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
@@ -0,0 +1,247 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Renewal Window Extension Policy
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificateRenewalWindowExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ protected static final String PROP_END_TIME = "relativeEndTime";
+ protected static final String PROP_BEGIN_TIME = "relativeBeginTime";
+ protected static final String PROP_CRITICAL = "critical";
+
+ protected boolean mCritical;
+ protected String mBeginTime;
+ protected String mEndTime;
+
+ /**
+ * Adds the Netscape comment in the end-entity certificates or
+ * CA certificates. The policy is set to be non-critical with the
+ * provided OID.
+ */
+ public CertificateRenewalWindowExt() {
+ NAME = "CertificateRenewalWindowExt";
+ DESC = "Sets non-critical Certificate Renewal Window extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ mBeginTime = config.getString(PROP_BEGIN_TIME, null);
+ mEndTime = config.getString(PROP_END_TIME, null);
+
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CertificateRenewalWindowExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.16.840.1.113730.1.15");
+ } catch (IOException ee) {
+ }
+ }
+ }
+
+ try {
+ Date now = CMS.getCurrentDate();
+ CertificateRenewalWindowExtension crwExt = null;
+
+ if (mEndTime == null || mEndTime.equals("")) {
+ crwExt = new CertificateRenewalWindowExtension(
+ mCritical,
+ getDateValue(now, mBeginTime),
+ null);
+ } else {
+ crwExt = new CertificateRenewalWindowExtension(
+ mCritical,
+ getDateValue(now, mBeginTime),
+ getDateValue(now, mEndTime));
+ }
+ extensions.set(CertificateRenewalWindowExtension.NAME,
+ crwExt);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public Date getDateValue(Date relativeFrom, String s) {
+ long time;
+
+ if (s.endsWith("s")) {
+ time = 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("m")) {
+ time = 60 * 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("h")) {
+ time = 60 * 60 * 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("D")) {
+ time = 24 * 60 * 60 * 1000 * Long.parseLong(
+ s.substring(0, s.length() - 1));
+ } else if (s.endsWith("M")) {
+ time = 30 * 60 * 60 * 1000 * Long.parseLong(
+ s.substring(0, s.length() - 1));
+ } else {
+ time = 1000 * Long.parseLong(s);
+ }
+
+ return new Date(relativeFrom.getTime() + time);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_BEGIN_TIME + ";string;Start Time in seconds (Relative to the time of issuance). Optionally, time unit (s - seconds, m - minutes, h - hours, D - days, M - months) can be specified right after the value. For example, 5 days can be expressed as 5D.",
+ PROP_END_TIME + ";string;End Time in seconds (Optional, Relative to the time of issuance). Optionally, time unit (s - seconds, m - minutes, h - hours, D - days, M - months) can be specified right after the value. For example, 5 days can be expressed as 5D.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificaterenewalwindow",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds 'Certificate Renewal Window' extension. See manual"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ if (mBeginTime == null) {
+ params.addElement(PROP_BEGIN_TIME + "=");
+ } else {
+ params.addElement(PROP_BEGIN_TIME + "=" + mBeginTime);
+ }
+ if (mEndTime == null) {
+ params.addElement(PROP_END_TIME + "=");
+ } else {
+ params.addElement(PROP_END_TIME + "=" + mEndTime);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_BEGIN_TIME + "=");
+ defParams.addElement(PROP_END_TIME + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
new file mode 100644
index 000000000..a8d5f8a0c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
@@ -0,0 +1,320 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Scope Of Use extension policy. This extension
+ * is defined in draft-thayes-cert-scope-00.txt
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificateScopeOfUseExt extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_ENTRY =
+ "entry";
+ protected static final String PROP_NAME =
+ "name";
+ protected static final String PROP_NAME_TYPE =
+ "name_type";
+ protected static final String PROP_PORT_NUMBER =
+ "port_number";
+
+ public static final int MAX_ENTRY = 5;
+
+ public IConfigStore mConfig = null;
+
+ public CertificateScopeOfUseExt() {
+ NAME = "CertificateScopeOfUseExt";
+ DESC = "Sets scope of use extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL +
+ ";boolean; This extension may be either critical or non-critical.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificatescopeofuse");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Certificate Scope of Use Extension.");
+
+ for (int i = 0; i < MAX_ENTRY; i++) {
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_NAME + ";" + IGeneralNameUtil.GENNAME_VALUE_INFO);
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_NAME_TYPE + ";" + IGeneralNameUtil.GENNAME_CHOICE_INFO);
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_PORT_NUMBER + ";string;" + "The port number (optional).");
+ }
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=AuthInfoAccessExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ }
+
+ /**
+ * Returns a sequence of scope entry.
+ */
+ private Vector getScopeEntries() throws EBaseException {
+ Vector entries = new Vector();
+
+ //
+ // read until there is *NO* ad<NUM>_method
+ //
+ for (int i = 0;; i++) {
+ // get port number (optional)
+ String port = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_PORT_NUMBER, null);
+ BigInt portNumber = null;
+
+ if (port != null && !port.equals("")) {
+ portNumber = new BigInt(Integer.parseInt(port));
+ }
+
+ //
+ // location ::= <TAG> : <VALUE>
+ // TAG ::= uriName | dirName
+ // VALUE ::= [value defined by TAG]
+ //
+ String name_type = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME_TYPE, null);
+ String name = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME, null);
+
+ if (name == null || name.equals(""))
+ break;
+ GeneralName gn = CMS.form_GeneralNameAsConstraints(name_type, name);
+
+ entries.addElement(new CertificateScopeEntry(gn, portNumber));
+ }
+ return entries;
+ }
+
+ /**
+ * If this policy is enabled, add the authority information
+ * access extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_INFO_ERROR", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // add access descriptions
+ Vector entries = getScopeEntries();
+
+ if (entries.size() == 0) {
+ return res;
+ }
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // check to see if AIA is already exist
+ try {
+ extensions.delete(CertificateScopeOfUseExtension.NAME);
+ log(ILogger.LL_INFO, "Previous extension deleted: " + CertificateScopeOfUseExtension.NAME);
+ } catch (IOException ex) {
+ }
+ }
+
+ // Create the extension
+ CertificateScopeOfUseExtension suExt = new
+ CertificateScopeOfUseExtension(mConfig.getBoolean(
+ PROP_CRITICAL, false), entries);
+
+ extensions.set(CertificateScopeOfUseExtension.NAME, suExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ "Configuration Info Error encountered: " +
+ e.getMessage());
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" +
+ mConfig.getBoolean(PROP_CRITICAL, false));
+ } catch (EBaseException e) {
+ }
+
+ for (int i = 0;; i++) {
+ String name_type = null;
+
+ try {
+ name_type = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_NAME_TYPE,
+ null);
+ } catch (EBaseException e) {
+ }
+ if (name_type == null)
+ break;
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME_TYPE + "=" + name_type);
+ String name = null;
+
+ try {
+ name = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_NAME,
+ null);
+ } catch (EBaseException e) {
+ }
+ if (name == null)
+ break;
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME + "=" + name);
+ String port = null;
+
+ try {
+ port = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_PORT_NUMBER,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_PORT_NUMBER + "=" + port);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+
+ //
+ // By default, we create MAX_AD access descriptions.
+ // If this is not enough, admin can manually edit
+ // the CMS.cfg
+ //
+ for (int i = 0; i < MAX_ENTRY; i++) {
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_NAME_TYPE + "=");
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_NAME + "=");
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_PORT_NUMBER + "=");
+ }
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
new file mode 100644
index 000000000..783ab2b6e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
@@ -0,0 +1,271 @@
+// --- 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.policy.extensions;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This implements the extended key usage extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ExtendedKeyUsageExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_PURPOSE_ID = "id";
+ protected static final String PROP_NUM_IDS = "numIds";
+ protected static int MAX_PURPOSE_ID = 10;
+ private boolean mCritical = false;
+ private IConfigStore mConfig = null;
+ private Vector mUsages = null;
+
+ private String[] mParams = null;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private ExtendedKeyUsageExtension mExtendedKeyUsage = null;
+
+ /**
+ * Constructs extended Key Usage extension.
+ */
+ public ExtendedKeyUsageExt() {
+ NAME = "ExtendedKeyUsageExt";
+ DESC = "Sets ExtendedKeyUsage extension for certificates";
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ setExtendedPluginInfo();
+ setupParams();
+ mExtendedKeyUsage = new ExtendedKeyUsageExtension(mCritical, mUsages);
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mExtendedKeyUsage == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(ExtendedKeyUsageExtension.NAME);
+ } catch (IOException ex) {
+ // ExtendedKeyUsage extension is not already there
+ }
+ }
+
+ extensions.set(ExtendedKeyUsageExtension.NAME, mExtendedKeyUsage);
+
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR",
+ e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Returns instance specific parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ int numIds = MAX_PURPOSE_ID;
+
+ try {
+ numIds = mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_NUM_IDS + "=" + numIds);
+ String usage = null;
+
+ for (int i = 0; i < numIds; i++) {
+ if (mUsages.size() <= i) {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=");
+ } else {
+ usage = ((ObjectIdentifier) mUsages.elementAt(i)).toString();
+ if (usage == null) {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=");
+ } else {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=" + usage);
+ }
+ }
+ }
+ return params;
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+ int mNum = MAX_PURPOSE_ID;
+
+ if (mConfig != null) {
+ try {
+ mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+ } catch (EBaseException e) {
+ }
+ }
+ for (int i = 0; i < mNum; i++) {
+ v.addElement(PROP_PURPOSE_ID + Integer.toString(i) + ";string;" +
+ "A unique,valid OID specified in dot-separated numeric component notation. e.g. 2.16.840.1.113730.1.99");
+ }
+
+ v.addElement(PROP_NUM_IDS + ";number;The total number of policy IDs.");
+ v.addElement(PROP_CRITICAL +
+ ";boolean;RFC 2459 recommendation: This extension may, at the option of the certificate issuer, be either critical or non-critical.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-extendedkeyusage");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Extended Key Usage Extension. Defined in RFC 2459 " +
+ "(4.2.1.13)");
+
+ mParams = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (mParams == null) {
+ setExtendedPluginInfo();
+ }
+ return mParams;
+ }
+
+ /**
+ * Returns default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NUM_IDS + "=" + MAX_PURPOSE_ID);
+ for (int i = 0; i < MAX_PURPOSE_ID; i++) {
+ defParams.addElement(PROP_PURPOSE_ID + Integer.toString(i) + "=");
+ }
+ return defParams;
+ }
+
+ /**
+ * Setups parameters.
+ */
+ private void setupParams() throws EBaseException {
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, false);
+ if (mUsages == null) {
+ mUsages = new Vector();
+ }
+
+ int mNum = mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+
+ for (int i = 0; i < mNum; i++) {
+ ObjectIdentifier usageOID = null;
+
+ String usage = mConfig.getString(PROP_PURPOSE_ID +
+ Integer.toString(i), null);
+
+ try {
+
+ if (usage == null) break;
+ usage = usage.trim();
+ if (usage.equals("")) break;
+ if (usage.equalsIgnoreCase("ocspsigning")) {
+ usageOID = ObjectIdentifier.getObjectIdentifier(ExtendedKeyUsageExtension.OID_OCSPSigning);
+ } else if (usage.equalsIgnoreCase("codesigning")) {
+ usageOID = ObjectIdentifier.getObjectIdentifier(ExtendedKeyUsageExtension.OID_CODESigning);
+ } else {
+ // it could be an object identifier, test it
+ usageOID = ObjectIdentifier.getObjectIdentifier(usage);
+ }
+ } catch (IOException ex) {
+ throw new EBaseException(this.getClass().getName() + ":" +
+ ex.getMessage());
+ } catch (NumberFormatException ex) {
+ throw new EBaseException(this.getClass().getName() + ":" +
+ "OID '" + usage + "' format error");
+ }
+ mUsages.addElement(usageOID);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java b/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java
new file mode 100644
index 000000000..9a07cb020
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java
@@ -0,0 +1,471 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.ParseException;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Private Integer extension policy.
+ * If this policy is enabled, it adds an Private Integer
+ * extension to the certificate.
+ *
+ * The following listed sample configuration parameters:
+ *
+ * ca.Policy.impl.privateInteger.class=com.netscape.certsrv.policy.genericASNExt
+ * ca.Policy.rule.genericASNExt.enable=true
+ * ca.Policy.rule.genericASNExt.name=myIntegerExtension
+ * ca.Policy.rule.genericASNExt.pattern={{{12}34}5}
+ * ca.Policy.rule.genericASNExt.oid=280.230.123.1234.1
+ * ca.Policy.rule.genericASNExt.critical=false
+ * ca.Policy.rule.genericASNExt.attribute1.type=integer
+ * ca.Policy.rule.genericASNExt.attribute1.source=value
+ * ca.Policy.rule.genericASNExt.attribute1.value=9999
+ * ca.Policy.rule.genericASNExt.attribute2.type=ia5string
+ * ca.Policy.rule.genericASNExt.attribute2.source=value
+ * ca.Policy.rule.genericASNExt.attribute2.value=hello
+ * ca.Policy.rule.genericASNExt.attribute3.type=octetstring
+ * ca.Policy.rule.genericASNExt.attribute3.source=value
+ * ca.Policy.rule.genericASNExt.attribute3.value=hellohello
+ * ca.Policy.rule.genericASNExt.attribute4.type=octetstring
+ * ca.Policy.rule.genericASNExt.attribute4.source=file
+ * ca.Policy.rule.genericASNExt.attribute4.value=c:/tmp/test.txt
+ * ca.Policy.rule.genericASNExt.attribute5.type=
+ * ca.Policy.rule.genericASNExt.attribute5.source=
+ * ca.Policy.rule.genericASNExt.attribute5.value=
+ * ca.Policy.rule.genericASNExt.implName=genericASNExt
+ * ca.Policy.rule.genericASNExt.predicate=
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class GenericASN1Ext extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final int MAX_ATTR = 10;
+
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_NAME =
+ "name";
+ protected static final String PROP_OID =
+ "oid";
+ protected static final String PROP_PATTERN =
+ "pattern";
+ protected static final String PROP_ATTRIBUTE =
+ "attribute";
+ protected static final String PROP_TYPE =
+ "type";
+ protected static final String PROP_SOURCE =
+ "source";
+ protected static final String PROP_VALUE =
+ "value";
+ protected static final String PROP_PREDICATE =
+ "predicate";
+
+ protected static final String PROP_ENABLE =
+ "enable";
+
+ public IConfigStore mConfig = null;
+
+ private String pattern = null;
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ "enable" + ";boolean;Enable this policy",
+ "predicate" + ";string;",
+ PROP_CRITICAL + ";boolean;",
+ PROP_NAME + ";string;Name for this extension.",
+ PROP_OID + ";string;OID number for this extension. It should be unique.",
+ PROP_PATTERN + ";string;Pattern for extension; {012}34",
+ // Attribute 0
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 1
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 2
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 3
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 4
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 5
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 6
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 7
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 8
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 9
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-genericasn1ext",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Private extension based on ASN1. See manual"
+ };
+
+ return s;
+ }
+
+ public GenericASN1Ext() {
+ NAME = "GenericASN1Ext";
+ DESC = "Sets Generic extension for certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=genericASNExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ if (mConfig == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ boolean enable = mConfig.getBoolean(PROP_ENABLE, false);
+
+ if (enable == false)
+ return;
+
+ String oid = mConfig.getString(PROP_OID, null);
+
+ if ((oid == null) || (oid.length() == 0)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ String name = mConfig.getString(PROP_NAME, null);
+
+ if ((name == null) || (name.length() == 0)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ try {
+ if (File.separatorChar == '\\') {
+ pattern = mConfig.getString(PROP_PATTERN, null);
+ checkFilename(0);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ }
+
+ // Check OID value
+ CMS.checkOID(name, oid);
+ pattern = mConfig.getString(PROP_PATTERN, null);
+ checkOID(0);
+
+ try {
+ ObjectIdentifier tmpid = new ObjectIdentifier(oid);
+
+ if (OIDMap.getName(tmpid) == null)
+ OIDMap.addAttribute("netscape.security.extensions.GenericASN1Extension", oid, name);
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ }
+
+ }
+
+ // Check filename
+ private int checkFilename(int index)
+ throws IOException, EBaseException {
+ String source = null;
+
+ while (index < pattern.length()) {
+ char ch = pattern.charAt(index);
+
+ switch (ch) {
+ case '{':
+ index++;
+ index = checkFilename(index);
+ break;
+
+ case '}':
+ return index;
+
+ default:
+ source = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE, null);
+ if ((source != null) && (source.equalsIgnoreCase("file"))) {
+ String oValue = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, null);
+ String nValue = oValue.replace('\\', '/');
+
+ mConfig.putString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, nValue);
+ FileInputStream fis = new FileInputStream(nValue);
+ fis.close();
+ }
+ }
+ index++;
+ }
+
+ return index;
+ }
+
+ // Check oid
+ private int checkOID(int index)
+ throws EBaseException {
+ String type = null;
+ String oid = null;
+
+ while (index < pattern.length()) {
+ char ch = pattern.charAt(index);
+
+ switch (ch) {
+ case '{':
+ index++;
+ index = checkOID(index);
+ break;
+
+ case '}':
+ return index;
+
+ default:
+ type = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_TYPE, null);
+ if ((type != null) && (type.equalsIgnoreCase("OID"))) {
+ oid = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, null);
+ CMS.checkOID(oid, oid);
+ }
+ }
+ index++;
+ }
+
+ return index;
+ }
+
+ /**
+ * If this policy is enabled, add the private Integer
+ * information extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", ""));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions) certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ //
+ // Remove any previousely computed extension
+ //
+ try {
+ extensions.delete(mConfig.getString(PROP_NAME, ""));
+ } catch (Exception e) {/* extension isn't there */
+ }
+ }
+
+ // Create the extension
+ GenericASN1Extension priExt = mkExtension();
+
+ extensions.set(GenericASN1Extension.NAME, priExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_EXTENSION_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Pattern parsing error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_UNKNOWN_EXCEPTION", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Unknown Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Construct GenericASN1Extension with value from CMS.cfg
+ */
+ protected GenericASN1Extension mkExtension()
+ throws IOException, EBaseException, ParseException {
+ GenericASN1Extension ext;
+
+ Hashtable h = new Hashtable();
+ // This only show one level, not substores!
+ Enumeration e = mConfig.getPropertyNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+
+ h.put(n, mConfig.getString(n));
+ }
+ for (int idx = 0; idx < MAX_ATTR; idx++) {
+ String proptype = PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE;
+ String propsource = PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE;
+ String propvalue = PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE;
+
+ h.put(proptype, mConfig.getString(proptype, null));
+ h.put(propsource, mConfig.getString(propsource, null));
+ h.put(propvalue, mConfig.getString(propvalue, null));
+ }
+ ext = new GenericASN1Extension(h);
+ return ext;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ int idx = 0;
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" + mConfig.getBoolean(PROP_CRITICAL, false));
+ params.addElement(PROP_NAME + "=" + mConfig.getString(PROP_NAME, null));
+ params.addElement(PROP_OID + "=" + mConfig.getString(PROP_OID, null));
+ params.addElement(PROP_PATTERN + "=" + mConfig.getString(PROP_PATTERN, null));
+
+ for (idx = 0; idx < MAX_ATTR; idx++) {
+ String proptype = PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE;
+ String propsource = PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE;
+ String propvalue = PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE;
+
+ params.addElement(proptype + "=" + mConfig.getString(proptype, null));
+ params.addElement(propsource + "=" + mConfig.getString(propsource, null));
+ params.addElement(propvalue + "=" + mConfig.getString(propvalue, null));
+ }
+ params.addElement(PROP_PREDICATE + "=" + mConfig.getString(PROP_PREDICATE, null));
+ } catch (EBaseException e) {;
+ }
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ int idx = 0;
+
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NAME + "=");
+ defParams.addElement(PROP_OID + "=");
+ defParams.addElement(PROP_PATTERN + "=");
+
+ for (idx = 0; idx < MAX_ATTR; idx++) {
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE + "=");
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE + "=");
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE + "=");
+ }
+
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java
new file mode 100644
index 000000000..240076c95
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java
@@ -0,0 +1,252 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import java.util.StringTokenizer;
+import netscape.security.util.DerValue;
+import java.util.Enumeration;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Issuer Alt Name Extension policy.
+ *
+ * This extension is used to associate Internet-style identities
+ * with the Certificate issuer.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class IssuerAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public static final String PROP_CRITICAL = "critical";
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private static Vector defaultParams = new Vector();
+ private static String[] mInfo = null;
+
+ static {
+ defaultParams.addElement(PROP_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ CMS.getGeneralNamesConfigDefaultParams(null, true, defaultParams);
+
+ Vector info = new Vector();
+
+ info.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: SHOULD NOT be marked critical.");
+ info.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-issueraltname");
+ info.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Issuer Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.8). ");
+
+ CMS.getGeneralNamesConfigExtendedPluginInfo(null, true, info);
+
+ mInfo = new String[info.size()];
+ info.copyInto(mInfo);
+ }
+
+ private Vector mParams = new Vector();
+ private IConfigStore mConfig = null;
+ private boolean mCritical = DEFAULT_CRITICALITY;
+ private boolean mEnabled = false;
+ IGeneralNamesConfig mGNs = null;
+ IssuerAlternativeNameExtension mExtension = null;
+
+ /**
+ * Adds the issuer alternate name extension to all certs.
+ */
+ public IssuerAltNameExt() {
+ NAME = "IssuerAltNameExt";
+ DESC = "Associate Internet-style Identities with Issuer";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // get criticality
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEFAULT_CRITICALITY);
+
+ // get enabled.
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+
+ // form general names.
+ mGNs = CMS.createGeneralNamesConfig(null, config, true, mEnabled);
+
+ // form extension
+ try {
+ if (mEnabled &&
+ mGNs.getGeneralNames() != null && !mGNs.getGeneralNames().isEmpty()) {
+ mExtension =
+ new IssuerAlternativeNameExtension(
+ Boolean.valueOf(mCritical), mGNs.getGeneralNames());
+ }
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ // init instance params
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mGNs.getInstanceParams(mParams);
+
+ return;
+ }
+
+ /**
+ * Adds a extension if none exists.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ if (mEnabled == false || mExtension == null)
+ return res;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ // get extension from cert info if any.
+ CertificateExtensions extensions = null;
+
+ try {
+ // get extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // no extensions.
+ } catch (CertificateException e) {
+ // no extension.
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ // not possible
+ } catch (Exception e) {
+ }
+ } else {
+
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(IssuerAlternativeNameExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack
+ // If name is not found, try deleting using the OID
+
+ try {
+ extensions.delete("2.5.29.18");
+ } catch (IOException ee) {
+ }
+ }
+ }
+
+ try {
+ extensions.set(IssuerAlternativeNameExtension.NAME, mExtension);
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CRL_CREATE_ISSUER_ALT_NAME_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return Empty Vector since this policy has no configuration parameters.
+ * for this policy instance.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return Empty Vector since this policy implementation has no
+ * configuration parameters.
+ */
+ public Vector getDefaultParams() {
+ return defaultParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return mInfo;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java
new file mode 100644
index 000000000..d824e452e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java
@@ -0,0 +1,351 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy to add Key Usage Extension.
+ * Adds the key usage extension based on what's requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class KeyUsageExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ private final static String HTTP_INPUT = "HTTP_INPUT";
+ protected static final boolean[] DEF_BITS =
+ new boolean[KeyUsageExtension.NBITS];
+ protected int mCAPathLen = -1;
+ protected IConfigStore mConfig = null;
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_DIGITAL_SIGNATURE = "digitalSignature";
+ protected static final String PROP_NON_REPUDIATION = "nonRepudiation";
+ protected static final String PROP_KEY_ENCIPHERMENT = "keyEncipherment";
+ protected static final String PROP_DATA_ENCIPHERMENT = "dataEncipherment";
+ protected static final String PROP_KEY_AGREEMENT = "keyAgreement";
+ protected static final String PROP_KEY_CERTSIGN = "keyCertsign";
+ protected static final String PROP_CRL_SIGN = "crlSign";
+ protected static final String PROP_ENCIPHER_ONLY = "encipherOnly";
+ protected static final String PROP_DECIPHER_ONLY = "decipherOnly";
+
+ protected boolean mCritical;
+ protected String mDigitalSignature;
+ protected String mNonRepudiation;
+ protected String mKeyEncipherment;
+ protected String mDataEncipherment;
+ protected String mKeyAgreement;
+ protected String mKeyCertsign;
+ protected String mCrlSign;
+ protected String mEncipherOnly;
+ protected String mDecipherOnly;
+
+ protected KeyUsageExtension mKeyUsage;
+
+ public KeyUsageExt() {
+ NAME = "KeyUsageExtPolicy";
+ DESC = "Sets Key Usage Extension in certificates.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=KeyUsageExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager or Registration Manager"));
+ }
+
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, true);
+ mDigitalSignature = mConfig.getString(PROP_DIGITAL_SIGNATURE, HTTP_INPUT);
+ mNonRepudiation = mConfig.getString(PROP_NON_REPUDIATION, HTTP_INPUT);
+ mKeyEncipherment = mConfig.getString(PROP_KEY_ENCIPHERMENT, HTTP_INPUT);
+ mDataEncipherment = mConfig.getString(PROP_DATA_ENCIPHERMENT, HTTP_INPUT);
+ mKeyAgreement = mConfig.getString(PROP_KEY_AGREEMENT, HTTP_INPUT);
+ mKeyCertsign = mConfig.getString(PROP_KEY_CERTSIGN, HTTP_INPUT);
+ mCrlSign = mConfig.getString(PROP_CRL_SIGN, HTTP_INPUT);
+ mEncipherOnly = mConfig.getString(PROP_ENCIPHER_ONLY, HTTP_INPUT);
+ mDecipherOnly = mConfig.getString(PROP_DECIPHER_ONLY, HTTP_INPUT);
+ }
+
+ /**
+ * Adds the key usage extension if not set already.
+ * (CRMF, agent, authentication (currently) or PKCS#10 (future)
+ * or RA could have set the extension.)
+ * If not set, set from http input parameters or use default if
+ * no http input parameters are set.
+ *
+ * Note: this allows any bits requested - does not check if user
+ * authenticated is allowed to have a Key Usage Extension with
+ * those bits. Unless the CA's certificate path length is 0, then
+ * we do not allow CA sign or CRL sign bits in any request.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ KeyUsageExtension ext = null;
+
+ if (extensions != null) {
+ try {
+ ext = (KeyUsageExtension)
+ extensions.get(KeyUsageExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ ext = null;
+ }
+ // check if CA does not allow subordinate CA certs.
+ // otherwise accept existing key usage extension.
+ if (ext != null) {
+ if (mCAPathLen == 0) {
+ boolean[] bits = ext.getBits();
+
+ if ((bits.length > KeyUsageExtension.KEY_CERTSIGN_BIT &&
+ bits[KeyUsageExtension.KEY_CERTSIGN_BIT] == true) ||
+ (bits.length > KeyUsageExtension.CRL_SIGN_BIT &&
+ bits[KeyUsageExtension.CRL_SIGN_BIT] == true)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED"),
+ NAME);
+ return PolicyResult.REJECTED;
+ }
+ }
+ return PolicyResult.ACCEPTED;
+ }
+ } else {
+ // create extensions set if none.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ }
+
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+
+ bits[KeyUsageExtension.DIGITAL_SIGNATURE_BIT] = getBit("digital_signature",
+ mDigitalSignature, req);
+ bits[KeyUsageExtension.NON_REPUDIATION_BIT] = getBit("non_repudiation",
+ mNonRepudiation, req);
+ bits[KeyUsageExtension.KEY_ENCIPHERMENT_BIT] = getBit("key_encipherment",
+ mKeyEncipherment, req);
+ bits[KeyUsageExtension.DATA_ENCIPHERMENT_BIT] = getBit("data_encipherment",
+ mDataEncipherment, req);
+ bits[KeyUsageExtension.KEY_AGREEMENT_BIT] = getBit("key_agreement",
+ mKeyAgreement, req);
+ bits[KeyUsageExtension.KEY_CERTSIGN_BIT] = getBit("key_certsign",
+ mKeyCertsign, req);
+ bits[KeyUsageExtension.CRL_SIGN_BIT] = getBit("crl_sign", mCrlSign, req);
+ bits[KeyUsageExtension.ENCIPHER_ONLY_BIT] = getBit("encipher_only",
+ mEncipherOnly, req);
+ bits[KeyUsageExtension.DECIPHER_ONLY_BIT] = getBit("decipher_only",
+ mDecipherOnly, req);
+
+ // don't allow no bits set or the extension does not
+ // encode/decode properlly.
+ boolean bitset = false;
+
+ for (int i = 0; i < bits.length; i++) {
+ if (bits[i]) {
+ bitset = true;
+ break;
+ }
+ }
+ if (!bitset) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET"),
+ NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ // create the extension.
+ try {
+ mKeyUsage = new KeyUsageExtension(mCritical, bits);
+ } catch (IOException e) {
+ }
+ extensions.set(KeyUsageExtension.NAME, mKeyUsage);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_DIGITAL_SIGNATURE + "=" + mDigitalSignature);
+ params.addElement(PROP_NON_REPUDIATION + "=" + mNonRepudiation);
+ params.addElement(PROP_KEY_ENCIPHERMENT + "=" + mKeyEncipherment);
+ params.addElement(PROP_DATA_ENCIPHERMENT + "=" + mDataEncipherment);
+ params.addElement(PROP_KEY_AGREEMENT + "=" + mKeyAgreement);
+ params.addElement(PROP_KEY_CERTSIGN + "=" + mKeyCertsign);
+ params.addElement(PROP_CRL_SIGN + "=" + mCrlSign);
+ params.addElement(PROP_ENCIPHER_ONLY + "=" + mEncipherOnly);
+ params.addElement(PROP_DECIPHER_ONLY + "=" + mDecipherOnly);
+ return params;
+ }
+
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=true");
+ mDefParams.addElement(PROP_DIGITAL_SIGNATURE + "=");
+ mDefParams.addElement(PROP_NON_REPUDIATION + "=");
+ mDefParams.addElement(PROP_KEY_ENCIPHERMENT + "=");
+ mDefParams.addElement(PROP_DATA_ENCIPHERMENT + "=");
+ mDefParams.addElement(PROP_KEY_AGREEMENT + "=");
+ mDefParams.addElement(PROP_KEY_CERTSIGN + "=");
+ mDefParams.addElement(PROP_CRL_SIGN + "=");
+ mDefParams.addElement(PROP_ENCIPHER_ONLY + "=");
+ mDefParams.addElement(PROP_DECIPHER_ONLY + "=");
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: SHOULD be critical",
+ PROP_DIGITAL_SIGNATURE + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_NON_REPUDIATION + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_ENCIPHERMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_DATA_ENCIPHERMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_AGREEMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_CERTSIGN + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_CRL_SIGN + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_ENCIPHER_ONLY + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_DECIPHER_ONLY + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-keyusage",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Key Usage Extension; See in RFC 2459 (4.2.1.3)"
+
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ private boolean getBit(String usage, String choice, IRequest req) {
+ if (choice.equals(HTTP_INPUT)) {
+ choice = req.getExtDataInString(IRequest.HTTP_PARAMS, usage);
+ if (choice == null)
+ choice = "false";
+ }
+ return Boolean.valueOf(choice).booleanValue();
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java
new file mode 100644
index 000000000..05a17cfcd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java
@@ -0,0 +1,288 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Netscape comment
+ * Adds Netscape comment policy
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NSCCommentExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ protected static final String PROP_USER_NOTICE_DISPLAY_TEXT = "displayText";
+ protected static final String PROP_COMMENT_FILE = "commentFile";
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_INPUT_TYPE = "inputType";
+ protected static final String TEXT = "Text";
+ protected static final String FILE = "File";
+
+ protected String mUserNoticeDisplayText;
+ protected String mCommentFile;
+ protected String mInputType;
+ protected boolean mCritical;
+ private Vector mParams = new Vector();
+
+ protected String tempCommentFile;
+ protected boolean certApplied = false;
+
+ /**
+ * Adds the Netscape comment in the end-entity certificates or
+ * CA certificates. The policy is set to be non-critical with the
+ * provided OID.
+ */
+ public NSCCommentExt() {
+ NAME = "NSCCommentExt";
+ DESC = "Sets non-critical Netscape Comment extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <p>
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=NSCCommentExtImpl
+ * ca.Policy.rule.<ruleName>.displayText=<n>
+ * ca.Policy.rule.<ruleName>.commentFile=<n>
+ * ca.Policy.rule.<ruleName>.enable=false
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ FileInputStream fileStream = null;
+
+ try {
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+
+ mInputType = config.getString(PROP_INPUT_TYPE, null);
+ mParams.addElement(PROP_INPUT_TYPE + "=" + mInputType);
+
+ mUserNoticeDisplayText = config.getString(PROP_USER_NOTICE_DISPLAY_TEXT, "");
+ mParams.addElement(PROP_USER_NOTICE_DISPLAY_TEXT + "=" + mUserNoticeDisplayText);
+
+ tempCommentFile = config.getString(PROP_COMMENT_FILE, "");
+
+ boolean enable = config.getBoolean(PROP_ENABLE, false);
+
+ if ((enable == true)) {
+
+ if (mInputType.equals("File")) {
+ if (tempCommentFile.equals(""))
+ throw new Exception("No file name provided");
+
+ fileStream = new FileInputStream(tempCommentFile);
+ fileStream.close();
+ }
+ }
+
+ if (tempCommentFile.equals(""))
+ mCommentFile = "";
+ else
+ mCommentFile = tempCommentFile.replace('\\', '/');
+
+ config.putString(PROP_COMMENT_FILE, mCommentFile);
+
+ mParams.addElement(PROP_COMMENT_FILE + "=" + mCommentFile);
+ } catch (FileNotFoundException e) {
+ Object[] params = {getInstanceName(), "File not found : " + tempCommentFile};
+
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ } catch (Exception e) {
+ Object[] params = {getInstanceName(), e.getMessage()};
+
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ certApplied = false;
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(NSCCommentExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.16.840.1.113730.1.13");
+ } catch (IOException ee) {
+ }
+ }
+ }
+ if (mInputType.equals("File")) {
+ // if ((mUserNoticeDisplayText.equals("")) && !(mCommentFile.equals(""))) {
+ try {
+ // Read the comments file
+ BufferedReader fis = new BufferedReader(new FileReader(mCommentFile));
+
+ String line = null;
+ StringBuffer buffer = new StringBuffer();
+
+ while ((line = fis.readLine()) != null)
+ buffer.append(line);
+ mUserNoticeDisplayText = new String(buffer);
+ fis.close();
+ } catch (IOException e) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, " Comment Text file not found : " + mCommentFile);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_COMMENT_FILE_NOT_FOUND", e.toString()));
+ return PolicyResult.REJECTED;
+
+ }
+
+ }
+
+ certApplied = true;
+
+ DisplayText displayText =
+ new DisplayText(DisplayText.tag_IA5String, mUserNoticeDisplayText);
+
+ try {
+ NSCCommentExtension cpExt =
+ new NSCCommentExtension(mCritical, mUserNoticeDisplayText);
+
+ extensions.set(NSCCommentExtension.NAME, cpExt);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_INPUT_TYPE + ";choice(Text,File);Whether the comments " +
+ "would be entered in the displayText field or come from " +
+ "a file.",
+ PROP_USER_NOTICE_DISPLAY_TEXT + ";string;The comment that may be " +
+ "displayed to the user when the certificate is viewed.",
+ PROP_COMMENT_FILE + ";string; If data source is 'File', specify " +
+ "the file name with full path.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nsccomment",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds 'netscape comment' extension. See manual"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_INPUT_TYPE + "=" + TEXT);
+ defParams.addElement(PROP_USER_NOTICE_DISPLAY_TEXT + "=");
+ defParams.addElement(PROP_COMMENT_FILE + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
new file mode 100644
index 000000000..5fa6bae9c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
@@ -0,0 +1,541 @@
+// --- 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.policy.extensions;
+
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * NS Cert Type policy.
+ * Adds the ns cert type extension depending on cert type requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NSCertTypeExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_SET_DEFAULT_BITS = "setDefaultBits";
+ protected static final boolean DEF_SET_DEFAULT_BITS = true;
+ protected static final String DEF_SET_DEFAULT_BITS_VAL =
+ Boolean.valueOf(DEF_SET_DEFAULT_BITS).toString();
+
+ protected static final int DEF_PATHLEN = -1;
+
+ protected static final boolean[] DEF_BITS =
+ new boolean[NSCertTypeExtension.NBITS];
+
+ // XXX for future use. currenlty always allow.
+ protected static final String PROP_AGENT_OVERR = "allowAgentOverride";
+ protected static final String PROP_EE_OVERR = "AllowEEOverride";
+
+ // XXX for future use. currently always critical
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+
+ // XXX for future use to allow overrides from forms.
+ // request must be agent approved or authenticated.
+ protected boolean mAllowAgentOverride = false;
+ protected boolean mAllowEEOverride = false;
+
+ // XXX for future use. currently always non-critical
+ protected boolean mCritical = false;
+
+ protected int mCAPathLen = -1;
+
+ protected IConfigStore mConfig = null;
+ protected boolean mSetDefaultBits = false;
+
+ static {
+ // set default bits used when request missing ns cert type info.
+ // default is a client cert
+ DEF_BITS[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.SSL_SERVER_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.EMAIL_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.OBJECT_SIGNING_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.SSL_CA_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.EMAIL_CA_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] = false;
+ }
+
+ public NSCertTypeExt() {
+ NAME = "NSCertType";
+ DESC = "Sets Netscape Cert Type on all certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=nsCertTypeExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX future use.
+ //mAllowAgentOverride = config.getBoolean(PROP_AGENT_OVERR, false);
+ //mAllowEEOverride = config.getBoolean(PROP_EE_OVERR, false);
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+
+ mSetDefaultBits = mConfig.getBoolean(
+ PROP_SET_DEFAULT_BITS, DEF_SET_DEFAULT_BITS);
+ }
+
+ /**
+ * Adds the ns cert type if not set already.
+ * reads ns cert type choices from form. If no choices from form
+ * will defaults to all.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ CMS.debug("NSCertTypeExt: Impl: " + NAME + ", Instance: " + getInstanceName() + "::apply()");
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ NSCertTypeExtension nsCertTypeExt = null;
+
+ if (extensions != null) {
+ // See if extension is already set and contains correct values.
+ try {
+ nsCertTypeExt = (NSCertTypeExtension)
+ extensions.get(NSCertTypeExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ nsCertTypeExt = null;
+ }
+ // XXX agent servlet currently sets this. it should be
+ // delayed to here.
+ if (nsCertTypeExt != null &&
+ extensionIsGood(nsCertTypeExt, req)) {
+ CMS.debug(
+ "NSCertTypeExt: already has correct ns cert type ext");
+ return PolicyResult.ACCEPTED;
+ } else if ((nsCertTypeExt != null) &&
+ (certType.equals("ocspResponder"))) {
+ // Fix for #528732 : Always delete
+ // this extension from OCSP signing cert
+ extensions.delete(NSCertTypeExtension.NAME);
+ return PolicyResult.ACCEPTED;
+ }
+ } else {
+ // create extensions set if none.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ CMS.debug(
+ "NSCertTypeExt: Created extensions for adding ns cert type..");
+ }
+ }
+ // add ns cert type extension if not set or not set correctly.
+ boolean[] bits = null;
+
+ bits = getBitsFromRequest(req, mSetDefaultBits);
+
+ // check if ca doesn't allow any subordinate ca
+ if (mCAPathLen == 0 && bits != null) {
+ if (bits[NSCertTypeExtension.SSL_CA_BIT] ||
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] ||
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT]) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ if (nsCertTypeExt != null) {
+ // replace with correct bits to comply to policy.
+ // take all that are true.
+ extensions.delete(NSCertTypeExtension.NAME);
+ }
+
+ int j;
+
+ for (j = 0; bits != null && j < bits.length; j++)
+ if (bits[j]) break;
+ if (bits == null || j == bits.length) {
+ if (!mSetDefaultBits) {
+ CMS.debug(
+ "NSCertTypeExt: no bits requested, not setting default.");
+ return PolicyResult.ACCEPTED;
+ } else
+ bits = DEF_BITS;
+ }
+
+ nsCertTypeExt = new NSCertTypeExtension(mCritical, bits);
+ extensions.set(NSCertTypeExtension.NAME, nsCertTypeExt);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * check if ns cert type extension is set correctly,
+ * correct bits if not.
+ * if not authorized to set extension, bits will be replaced.
+ */
+ protected boolean extensionIsGood(
+ NSCertTypeExtension nsCertTypeExt, IRequest req)
+ throws IOException, CertificateException {
+ // always return false for now to make sure minimum is set.
+ // agents and ee can add others.
+
+ // must be agent approved or authenticated for allowing extensions
+ // which is always the case if we get to this point.
+ IAuthToken token = req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+
+ if (!agentApproved(req) && token == null) {
+ // don't know where this came from.
+ // set all bits to false to reset.
+ CMS.debug(
+ "NSCertTypeExt: unknown origin: setting ns cert type bits to false");
+ boolean[] bits = new boolean[8];
+
+ for (int i = bits.length - 1; i >= 0; i--) {
+ nsCertTypeExt.set(i, false);
+ }
+ return false;
+ } else {
+ // check for min bits, set default if not there.
+ String certType = req.getExtDataInString(IRequest.HTTP_PARAMS,
+ IRequest.CERT_TYPE);
+
+ if ((certType != null) && certType.equals("ocspResponder")) {
+ return false;
+ }
+ if (certType == null || certType.length() == 0) {
+ // if don't know cert type let agent override anything.
+ return true;
+ }
+ if (certType.equals(IRequest.CA_CERT)) {
+ if (!nsCertTypeExt.isSet(NSCertTypeExtension.SSL_CA_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.EMAIL_CA_BIT) &&
+ !nsCertTypeExt.isSet(
+ NSCertTypeExtension.OBJECT_SIGNING_CA_BIT)) {
+ // min not set so set all.
+ CMS.debug(
+ "NSCertTypeExt: is extension good: no ca bits set. set all");
+
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_CA,
+ Boolean.valueOf(true));
+ nsCertTypeExt.set(NSCertTypeExtension.EMAIL_CA,
+ Boolean.valueOf(true));
+ nsCertTypeExt.set(NSCertTypeExtension.OBJECT_SIGNING_CA,
+ Boolean.valueOf(true));
+ }
+ return true;
+ } else if (certType.equals(IRequest.CLIENT_CERT)) {
+ if (!nsCertTypeExt.isSet(NSCertTypeExtension.SSL_CLIENT_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.EMAIL_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.SSL_SERVER_BIT) &&
+ !nsCertTypeExt.isSet(
+ NSCertTypeExtension.OBJECT_SIGNING_BIT)) {
+ // min not set so set all.
+ CMS.debug(
+ "NSCertTypeExt: is extension good: no cl bits set. set all");
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_CLIENT,
+ new Boolean(true));
+ nsCertTypeExt.set(NSCertTypeExtension.EMAIL,
+ new Boolean(true));
+ nsCertTypeExt.set(NSCertTypeExtension.OBJECT_SIGNING,
+ new Boolean(true));
+ }
+ return true;
+ } else if (certType.equals(IRequest.SERVER_CERT)) {
+ // this bit must be true.
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_SERVER_BIT, true);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets ns cert type bits from request.
+ * If none set, use cert type to determine correct bits.
+ * If no cert type, use default.
+ */
+
+ protected boolean[] getBitsFromRequest(IRequest req, boolean setDefault) {
+ boolean[] bits = null;
+
+ CMS.debug("NSCertTypeExt: ns cert type getting ns cert type vars");
+ bits = getNSCertTypeBits(req);
+ if (bits == null && setDefault) {
+ // no ns cert type bits set in request. go with cert type.
+ CMS.debug("NSCertTypeExt: ns cert type getting cert type vars");
+ bits = getCertTypeBits(req);
+
+ if (bits == null && setDefault) {
+ CMS.debug("NSCertTypeExt: ns cert type getting def bits");
+ bits = DEF_BITS;
+ }
+ }
+ return bits;
+ }
+
+ /**
+ * get ns cert type bits from actual sets in the request
+ */
+ protected boolean[] getNSCertTypeBits(IRequest req) {
+ boolean[] bits = new boolean[NSCertTypeExtension.NBITS];
+
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_CLIENT, false);
+
+ bits[NSCertTypeExtension.SSL_SERVER_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_SERVER, false);
+
+ bits[NSCertTypeExtension.EMAIL_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.EMAIL, false);
+
+ bits[NSCertTypeExtension.OBJECT_SIGNING_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.OBJECT_SIGNING, false);
+
+ bits[NSCertTypeExtension.SSL_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_CA, false);
+
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.EMAIL_CA, false);
+
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.OBJECT_SIGNING_CA, false);
+
+ // if nothing set, return null.
+ int i;
+
+ for (i = bits.length - 1; i >= 0; i--) {
+ if (bits[i] == true) {
+ CMS.debug("NSCertTypeExt: bit " + i + " is set.");
+ break;
+ }
+ }
+ if (i < 0) {
+ // nothing was set.
+ CMS.debug("NSCertTypeExt: No bits were set.");
+ bits = null;
+ }
+ return bits;
+ }
+
+ /**
+ * get cert type bits according to cert type.
+ */
+ protected boolean[] getCertTypeBits(IRequest req) {
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType == null || certType.length() == 0)
+ return null;
+
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+
+ for (int i = bits.length - 1; i >= 0; i--)
+ bits[i] = false;
+
+ if (certType.equals(IRequest.CLIENT_CERT)) {
+ CMS.debug("NSCertTypeExt: setting bits for client cert");
+ // we can only guess here when it's client.
+ // sets all client bit for default.
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ bits[NSCertTypeExtension.EMAIL_BIT] = true;
+ //bits[NSCertTypeExtension.OBJECT_SIGNING_BIT] = true;
+ } else if (certType.equals(IRequest.SERVER_CERT)) {
+ CMS.debug("NSCertTypeExt: setting bits for server cert");
+ bits[NSCertTypeExtension.SSL_SERVER_BIT] = true;
+ } else if (certType.equals(IRequest.CA_CERT)) {
+ CMS.debug("NSCertType: setting bits for ca cert");
+ bits[NSCertTypeExtension.SSL_CA_BIT] = true;
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] = true;
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] = true;
+ } else if (certType.equals(IRequest.RA_CERT)) {
+ CMS.debug("NSCertType: setting bits for ra cert");
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ } else {
+ CMS.debug("NSCertTypeExt: no other cert bits set");
+ // return null to use default.
+ bits = DEF_BITS;
+ }
+ return bits;
+ }
+
+ /**
+ * merge bits with those set from form.
+ * make sure required minimum is set. Agent or auth can set others.
+ * XXX form shouldn't set the extension
+ */
+ public void mergeBits(NSCertTypeExtension nsCertTypeExt, boolean[] bits) {
+ for (int i = bits.length - 1; i >= 0; i--) {
+ if (bits[i] == true) {
+ CMS.debug("NSCertTypeExt: ns cert type merging bit " + i);
+ nsCertTypeExt.set(i, true);
+ }
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_SET_DEFAULT_BITS + "=" + mSetDefaultBits);
+ //new Boolean(mSetDefaultBits).toString());
+ return params;
+ }
+
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(
+ PROP_CRITICAL + "=false");
+ mDefParams.addElement(
+ PROP_SET_DEFAULT_BITS + "=" + DEF_SET_DEFAULT_BITS);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_SET_DEFAULT_BITS + ";boolean;Specify whether to set the Netscape certificate " +
+ "type extension with default bits ('ssl client' and 'email') in certificates " +
+ "specified by the predicate " +
+ "expression.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nscerttype",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Netscape Certificate Type extension."
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java
new file mode 100644
index 000000000..b204e57b2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java
@@ -0,0 +1,468 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Name Constraints Extension Policy
+ * Adds the name constraints extension to a (CA) certificate.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NameConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_PERMITTEDSUBTREES = "numPermittedSubtrees";
+ protected static final String PROP_NUM_EXCLUDEDSUBTREES = "numExcludedSubtrees";
+
+ protected static final String PROP_PERMITTEDSUBTREES = "permittedSubtrees";
+ protected static final String PROP_EXCLUDEDSUBTREES = "excludedSubtrees";
+
+ protected static final boolean DEF_CRITICAL = true;
+ protected static final int DEF_NUM_PERMITTEDSUBTREES = 8;
+ protected static final int DEF_NUM_EXCLUDEDSUBTREES = 8;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumPermittedSubtrees = 0;
+ protected int mNumExcludedSubtrees = 0;
+ protected Subtree[] mPermittedSubtrees = null;
+ protected Subtree[] mExcludedSubtrees = null;
+ protected NameConstraintsExtension mNameConstraintsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ public NameConstraintsExt() {
+ NAME = "NameConstraintsExt";
+ DESC = "Sets Name Constraints Extension on subordinate CA certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor)owner).getAuthority();
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+ mNumPermittedSubtrees = mConfig.getInteger(
+ PROP_NUM_PERMITTEDSUBTREES, DEF_NUM_PERMITTEDSUBTREES);
+ mNumExcludedSubtrees = mConfig.getInteger(
+ PROP_NUM_EXCLUDEDSUBTREES, DEF_NUM_EXCLUDEDSUBTREES);
+
+ if (mNumPermittedSubtrees < 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_PERMITTEDSUBTREES,
+ "value must be greater than or equal to 0"));
+ }
+ if (mNumExcludedSubtrees < 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_EXCLUDEDSUBTREES,
+ "value must be greater than or equal to 0"));
+ }
+
+ // init permitted subtrees if any.
+ if (mNumPermittedSubtrees > 0) {
+ mPermittedSubtrees =
+ form_subtrees(PROP_PERMITTEDSUBTREES, mNumPermittedSubtrees);
+ CMS.debug("NameConstraintsExt: formed permitted subtrees");
+ }
+
+ // init excluded subtrees if any.
+ if (mNumExcludedSubtrees > 0) {
+ mExcludedSubtrees =
+ form_subtrees(PROP_EXCLUDEDSUBTREES, mNumExcludedSubtrees);
+ CMS.debug("NameConstraintsExt: formed excluded subtrees");
+ }
+
+ // create instance of name constraints extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector permittedSubtrees = new Vector();
+
+ for (int i = 0; i < mNumPermittedSubtrees; i++) {
+ permittedSubtrees.addElement(
+ mPermittedSubtrees[i].mGeneralSubtree);
+ }
+ Vector excludedSubtrees = new Vector();
+
+ for (int j = 0; j < mNumExcludedSubtrees; j++) {
+ excludedSubtrees.addElement(
+ mExcludedSubtrees[j].mGeneralSubtree);
+ }
+ GeneralSubtrees psb = null;
+
+ if (permittedSubtrees.size() > 0) {
+ psb = new GeneralSubtrees(permittedSubtrees);
+ }
+ GeneralSubtrees esb = null;
+
+ if (excludedSubtrees.size() > 0) {
+ esb = new GeneralSubtrees(excludedSubtrees);
+ }
+ mNameConstraintsExtension =
+ new NameConstraintsExtension(mCritical,
+ psb,
+ esb);
+ CMS.debug("NameConstraintsExt: formed Name Constraints Extension " +
+ mNameConstraintsExtension);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing Name Constraints Extension: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + "=" + mNumPermittedSubtrees);
+ mInstanceParams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + "=" + mNumExcludedSubtrees);
+ if (mNumPermittedSubtrees > 0) {
+ for (int i = 0; i < mPermittedSubtrees.length; i++)
+ mPermittedSubtrees[i].getInstanceParams(mInstanceParams);
+ }
+ if (mNumExcludedSubtrees > 0) {
+ for (int j = 0; j < mExcludedSubtrees.length; j++)
+ mExcludedSubtrees[j].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ Subtree[] form_subtrees(String subtreesName, int numSubtrees)
+ throws EBaseException {
+ Subtree[] subtrees = new Subtree[numSubtrees];
+
+ for (int i = 0; i < numSubtrees; i++) {
+ String subtreeName = subtreesName + i;
+ IConfigStore subtreeConfig = mConfig.getSubStore(subtreeName);
+ Subtree subtree =
+ new Subtree(subtreeName, subtreeConfig, mEnabled);
+
+ subtrees[i] = subtree;
+ }
+ return subtrees;
+ }
+
+ /**
+ * Adds Name Constraints Extension to a (CA) certificate.
+ *
+ * If a Name constraints Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mNameConstraintsExtension == null) {
+ //setError(req, PolicyResources.EXTENSION_NOT_INITED_1, NAME);
+ //return PolicyResult.REJECTED;
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // check if name constraints extension already exists.
+ // if not agent approved, replace name constraints extension with ours.
+ // else ignore.
+ try {
+ NameConstraintsExtension nameConstraintsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ nameConstraintsExt = (NameConstraintsExtension)
+ extensions.get(NameConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (nameConstraintsExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "NameConstraintsExt: request id from agent " + req.getRequestId() +
+ " already has name constraints - accepted");
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "NameConstraintsExt: request id " + req.getRequestId() + " from user " +
+ " already has name constraints - deleted");
+ extensions.delete(NameConstraintsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ NameConstraintsExtension.NAME, mNameConstraintsExtension);
+ CMS.debug(
+ "NameConstraintsExt: added Name Constraints Extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_NAME_CONST_EXTENSION", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + "=" + DEF_NUM_PERMITTEDSUBTREES);
+ mDefParams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + "=" + DEF_NUM_EXCLUDEDSUBTREES);
+ for (int k = 0; k < DEF_NUM_PERMITTEDSUBTREES; k++) {
+ Subtree.getDefaultParams(PROP_PERMITTEDSUBTREES + k, mDefParams);
+ }
+ for (int l = 0; l < DEF_NUM_EXCLUDEDSUBTREES; l++) {
+ Subtree.getDefaultParams(PROP_EXCLUDEDSUBTREES + l, mDefParams);
+ }
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST be critical.");
+ theparams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + ";number;See RFC 2459 sec 4.2.1.11");
+ theparams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + ";number;See RFC 2459 sec 4.2.1.11");
+
+ // now do the subtrees.
+ for (int k = 0; k < DEF_NUM_PERMITTEDSUBTREES; k++) {
+ Subtree.getExtendedPluginInfo(PROP_PERMITTEDSUBTREES + k, theparams);
+ }
+ for (int l = 0; l < DEF_NUM_EXCLUDEDSUBTREES; l++) {
+ Subtree.getExtendedPluginInfo(PROP_EXCLUDEDSUBTREES + l, theparams);
+ }
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nameconstraints");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Name Constraints Extension. See RFC 2459");
+
+ String[] info = new String[theparams.size()];
+
+ theparams.copyInto(info);
+ return info;
+ }
+}
+
+
+/**
+ * subtree configuration
+ */
+class Subtree {
+
+ protected static final String PROP_BASE = "base";
+ protected static final String PROP_MIN = "min";
+ protected static final String PROP_MAX = "max";
+
+ protected static final int DEF_MIN = 0;
+ protected static final int DEF_MAX = -1; // -1 (less than 0) means not set.
+
+ protected static final String
+ MINMAX_INFO = "number;See RFC 2459 section 4.2.1.11";
+
+ String mName = null;
+ IConfigStore mConfig = null;
+ int mMin = DEF_MIN, mMax = DEF_MAX;
+ IGeneralNameAsConstraintsConfig mBase = null;
+ GeneralSubtree mGeneralSubtree = null;
+
+ String mNameDot = null;
+ String mNameDotMin = null;
+ String mNameDotMax = null;
+
+ public Subtree(
+ String subtreeName, IConfigStore config, boolean policyEnabled)
+ throws EBaseException {
+ mName = subtreeName;
+ mConfig = config;
+
+ if (mName != null) {
+ mNameDot = mName + ".";
+ mNameDotMin = mNameDot + PROP_MIN;
+ mNameDotMax = mNameDot + PROP_MAX;
+ } else {
+ mNameDot = "";
+ mNameDotMin = PROP_MIN;
+ mNameDotMax = PROP_MAX;
+ }
+
+ // necessary to expand/shrink # general names from console.
+ if (mConfig.size() == 0) {
+ mConfig.putInteger(mNameDotMin, mMin);
+ mConfig.putInteger(mNameDotMax, mMax);
+ // GeneralNameConfig will take care of stuff for generalname.
+ }
+
+ // if policy enabled get values to form the general subtree.
+ mMin = mConfig.getInteger(PROP_MIN, DEF_MIN);
+ mMax = mConfig.getInteger(PROP_MAX, DEF_MAX);
+ if (mMax < -1) mMax = -1;
+ mBase = CMS.createGeneralNameAsConstraintsConfig(
+ mNameDot + PROP_BASE, mConfig.getSubStore(PROP_BASE),
+ true, policyEnabled);
+
+ if (policyEnabled) {
+ mGeneralSubtree =
+ new GeneralSubtree(mBase.getGeneralName(), mMin, mMax);
+ }
+ }
+
+ void getInstanceParams(Vector instanceParams) {
+ mBase.getInstanceParams(instanceParams);
+ instanceParams.addElement(mNameDotMin + "=" + mMin);
+ instanceParams.addElement(mNameDotMax + "=" + mMax);
+ }
+
+ static void getDefaultParams(String name, Vector params) {
+ String nameDot = "";
+
+ if (name != null && name.length() >= 0)
+ nameDot = name + ".";
+ CMS.getGeneralNameConfigDefaultParams(nameDot + PROP_BASE, true, params);
+ params.addElement(nameDot + PROP_MIN + "=" + DEF_MIN);
+ params.addElement(nameDot + PROP_MAX + "=" + DEF_MAX);
+ }
+
+ static void getExtendedPluginInfo(String name, Vector info) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ CMS.getGeneralNameConfigExtendedPluginInfo(nameDot + PROP_BASE, true, info);
+ info.addElement(nameDot + PROP_MIN + ";" + MINMAX_INFO);
+ info.addElement(nameDot + PROP_MAX + ";" + MINMAX_INFO);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
new file mode 100644
index 000000000..289e2d297
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
@@ -0,0 +1,183 @@
+// --- 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.policy.extensions;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This implements an OCSP Signing policy, it
+ * adds the OCSP Signing extension to the certificate.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class OCSPNoCheckExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ public static final String PROP_CRITICAL = "critical";
+ private boolean mCritical = false;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private OCSPNoCheckExtension mOCSPNoCheck = null;
+
+ /**
+ * Constructs an OCSP No check extension.
+ */
+ public OCSPNoCheckExt() {
+ NAME = "OCSPNoCheckExt";
+ DESC = "Sets OCSPNoCheck extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2560 recommendation: SHOULD be non-critical.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-ocspnocheck",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds OCSP signing extension to certificate"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOCSPNoCheck = new OCSPNoCheckExtension();
+
+ if (mOCSPNoCheck != null) {
+ // configure the extension itself
+ mCritical = config.getBoolean(PROP_CRITICAL,
+ DEFAULT_CRITICALITY);
+ mOCSPNoCheck.setCritical(mCritical);
+ }
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mOCSPNoCheck == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(OCSPNoCheckExtension.NAME);
+ } catch (IOException ex) {
+ // OCSPNoCheck extension is not already there
+ // log(ILogger.LL_FAILURE, "No previous extension: "+OCSPNoCheckExtension.NAME+" "+ex.getMessage());
+ }
+ }
+
+ extensions.set(OCSPNoCheckExtension.NAME, mOCSPNoCheck);
+
+ return PolicyResult.ACCEPTED;
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Returns instance parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ return params;
+
+ }
+
+ /**
+ * Returns default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ return defParams;
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
new file mode 100644
index 000000000..4396a09dd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
@@ -0,0 +1,282 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy Constraints Extension Policy
+ * Adds the policy constraints extension to (CA) certificates.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PolicyConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String
+ PROP_REQ_EXPLICIT_POLICY = "reqExplicitPolicy";
+ protected static final String
+ PROP_INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_REQ_EXPLICIT_POLICY = -1; // not set
+ protected static final int DEF_INHIBIT_POLICY_MAPPING = -1; // not set
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mReqExplicitPolicy = DEF_REQ_EXPLICIT_POLICY;
+ protected int mInhibitPolicyMapping = DEF_INHIBIT_POLICY_MAPPING;
+ protected PolicyConstraintsExtension mPolicyConstraintsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + DEF_REQ_EXPLICIT_POLICY);
+ mDefaultParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + DEF_INHIBIT_POLICY_MAPPING);
+ }
+
+ public PolicyConstraintsExt() {
+ NAME = "PolicyConstriantsExt";
+ DESC = "Sets Policy Constraints Extension on subordinate CA certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((GenericPolicyProcessor)owner).mAuthority;
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mReqExplicitPolicy = mConfig.getInteger(
+ PROP_REQ_EXPLICIT_POLICY, DEF_REQ_EXPLICIT_POLICY);
+ mInhibitPolicyMapping = mConfig.getInteger(
+ PROP_INHIBIT_POLICY_MAPPING, DEF_INHIBIT_POLICY_MAPPING);
+
+ if (mReqExplicitPolicy < -1)
+ mReqExplicitPolicy = -1;
+ if (mInhibitPolicyMapping < -1)
+ mInhibitPolicyMapping = -1;
+
+ // create instance of policy constraings extension
+ try {
+ mPolicyConstraintsExtension =
+ new PolicyConstraintsExtension(mCritical,
+ mReqExplicitPolicy, mInhibitPolicyMapping);
+ CMS.debug(
+ "PolicyConstraintsExt: Created Policy Constraints Extension: " +
+ mPolicyConstraintsExtension);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CANT_INIT_POLICY_CONST_EXT", e.toString()));
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Could not init Policy Constraints Extension. Error: " + e));
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + mReqExplicitPolicy);
+ mInstanceParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + mInhibitPolicyMapping);
+ }
+
+ /**
+ * Adds Policy Constraints Extension to a (CA) certificate.
+ *
+ * If a Policy constraints Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mPolicyConstraintsExtension == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ // check if name constraints extension already exists.
+ // if not agent approved, replace name constraints extension with ours.
+ // else ignore.
+ try {
+ PolicyConstraintsExtension policyConstraintsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ policyConstraintsExt = (PolicyConstraintsExtension)
+ extensions.get(PolicyConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (policyConstraintsExt != null) {
+ if (agentApproved(req)) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ extensions.delete(PolicyConstraintsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ "PolicyConstriantsExt", mPolicyConstraintsExtension);
+ CMS.debug("PolicyConstraintsExt: added our policy constraints extension");
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CANT_PROCESS_POLICY_CONST_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ /**
+ * gets plugin info for pretty console edit displays.
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + mReqExplicitPolicy);
+ mInstanceParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + mInhibitPolicyMapping);
+
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: may be critical or non-critical.",
+ PROP_REQ_EXPLICIT_POLICY + ";integer;Number of addional certificates that may appear in the path before an explicit policy is required. If less than 0 this field is unset in the extension.",
+ PROP_INHIBIT_POLICY_MAPPING + ";integer;Number of addional certificates that may appear in the path before policy mapping is no longer permitted. If less than 0 this field is unset in the extension.",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-policyconstraints"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
new file mode 100644
index 000000000..aafecb17a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
@@ -0,0 +1,417 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy Mappings Extension Policy
+ * Adds the Policy Mappings extension to a (CA) certificate.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PolicyMappingsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_POLICYMAPPINGS = "numPolicyMappings";
+
+ protected static final String PROP_POLICYMAP = "policyMap";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_POLICYMAPPINGS = 1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumPolicyMappings = DEF_NUM_POLICYMAPPINGS;
+ protected PolicyMap[] mPolicyMaps = null;
+ protected PolicyMappingsExtension mPolicyMappingsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ public PolicyMappingsExt() {
+ NAME = "PolicyMappingsExt";
+ DESC = "Sets Policy Mappings Extension on subordinate CA certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor)owner).getAuthority();
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mNumPolicyMappings = mConfig.getInteger(
+ PROP_NUM_POLICYMAPPINGS, DEF_NUM_POLICYMAPPINGS);
+ if (mNumPolicyMappings < 1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_ATTR_VALUE_2", NAME, ""));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_POLICYMAPPINGS,
+ "value must be greater than or equal to 1"));
+ }
+
+ // init Policy Mappings, check values if enabled.
+ mPolicyMaps = new PolicyMap[mNumPolicyMappings];
+ for (int i = 0; i < mNumPolicyMappings; i++) {
+ String subtreeName = PROP_POLICYMAP + i;
+
+ try {
+ mPolicyMaps[i] = new PolicyMap(subtreeName, mConfig, mEnabled);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("POLICY_ERROR_CREATE_MAP", e.toString()));
+ throw e;
+ }
+ }
+
+ // create instance of policy mappings extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector certPolicyMaps = new Vector();
+
+ for (int j = 0; j < mNumPolicyMappings; j++) {
+ certPolicyMaps.addElement(
+ mPolicyMaps[j].mCertificatePolicyMap);
+ }
+ mPolicyMappingsExtension =
+ new PolicyMappingsExtension(mCritical, certPolicyMaps);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing " + NAME + " Error: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_POLICYMAPPINGS + "=" + mNumPolicyMappings);
+ for (int i = 0; i < mNumPolicyMappings; i++) {
+ mPolicyMaps[i].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Adds policy mappings Extension to a (CA) certificate.
+ *
+ * If a policy mappings Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mPolicyMappingsExtension == null) {
+ //setError(req, PolicyResources.EXTENSION_NOT_INITED_1, NAME);
+ //return PolicyResult.REJECTED;
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // check if policy mappings extension already exists.
+ // if not agent approved, replace policy mappings extension with ours.
+ // else ignore.
+ try {
+ PolicyMappingsExtension policyMappingsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ policyMappingsExt = (PolicyMappingsExtension)
+ extensions.get(PolicyMappingsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (policyMappingsExt != null) {
+ if (agentApproved(req)) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ extensions.delete(PolicyMappingsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ PolicyMappingsExtension.NAME, mPolicyMappingsExtension);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_PROCESS_POLICYMAP_EXT", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_POLICYMAPPINGS + "=" + DEF_NUM_POLICYMAPPINGS);
+ String policyMap0Dot = PROP_POLICYMAP + "0.";
+
+ mDefParams.addElement(
+ policyMap0Dot + PolicyMap.PROP_ISSUER_DOMAIN_POLICY + "=" + "");
+ mDefParams.addElement(
+ policyMap0Dot + PolicyMap.PROP_SUBJECT_DOMAIN_POLICY + "=" + "");
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST be non-critical.");
+ theparams.addElement(PROP_NUM_POLICYMAPPINGS + ";number; Number of policy mappings. The value must be greater than or equal to 1");
+
+ String policyInfo =
+ ";string;An object identifier in the form n.n.n.n";
+
+ for (int k = 0; k < 5; k++) {
+ String policyMapkDot = PROP_POLICYMAP + k + ".";
+
+ theparams.addElement(policyMapkDot +
+ PolicyMap.PROP_ISSUER_DOMAIN_POLICY + policyInfo);
+ theparams.addElement(policyMapkDot +
+ PolicyMap.PROP_SUBJECT_DOMAIN_POLICY + policyInfo);
+ }
+
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-policymappings");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Policy Mappings Extension. See RFC 2459 (4.2.1.6)");
+
+ String[] params = new String[theparams.size()];
+
+ theparams.copyInto(params);
+ return params;
+ }
+}
+
+
+class PolicyMap {
+
+ protected static String PROP_ISSUER_DOMAIN_POLICY = "issuerDomainPolicy";
+ protected static String PROP_SUBJECT_DOMAIN_POLICY = "subjectDomainPolicy";
+
+ protected String mName = null;
+ protected String mNameDot = null;
+ protected IConfigStore mConfig = null;
+ protected String mIssuerDomainPolicy = null;
+ protected String mSubjectDomainPolicy = null;
+ protected CertificatePolicyMap mCertificatePolicyMap = null;
+
+ /**
+ * forms policy map parameters.
+ * @param name name of this policy map, for example policyMap0
+ * @param config parent's config from where we find this configuration.
+ * @param enabled whether policy was enabled.
+ */
+ protected PolicyMap(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ mName = name;
+ mConfig = config.getSubStore(mName);
+ mNameDot = mName + ".";
+
+ if( mConfig == null ) {
+ CMS.debug( "PolicyMappingsExt::PolicyMap - mConfig is null!" );
+ return;
+ }
+
+ // if there's no configuration for this map put it there.
+ if (mConfig.size() == 0) {
+ config.putString(mNameDot + PROP_ISSUER_DOMAIN_POLICY, "");
+ config.putString(mNameDot + PROP_SUBJECT_DOMAIN_POLICY, "");
+ mConfig = config.getSubStore(mName);
+ if (mConfig == null || mConfig.size() == 0) {
+ CMS.debug( "PolicyMappingsExt::PolicyMap - mConfig " +
+ "is null or empty!" );
+ return;
+ }
+ }
+
+ // get policy ids from configuration.
+ mIssuerDomainPolicy =
+ mConfig.getString(PROP_ISSUER_DOMAIN_POLICY, null);
+ mSubjectDomainPolicy =
+ mConfig.getString(PROP_SUBJECT_DOMAIN_POLICY, null);
+
+ // adjust for "" and console returning "null"
+ if (mIssuerDomainPolicy != null &&
+ (mIssuerDomainPolicy.length() == 0 ||
+ mIssuerDomainPolicy.equals("null"))) {
+ mIssuerDomainPolicy = null;
+ }
+ if (mSubjectDomainPolicy != null &&
+ (mSubjectDomainPolicy.length() == 0 ||
+ mSubjectDomainPolicy.equals("null"))) {
+ mSubjectDomainPolicy = null;
+ }
+
+ // policy ids cannot be null if policy is enabled.
+ String msg = "value cannot be null.";
+
+ if (mIssuerDomainPolicy == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY, msg));
+ if (mSubjectDomainPolicy == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY, msg));
+
+ // if a policy id is not null check that it is a valid OID.
+ ObjectIdentifier issuerPolicyId = null;
+ ObjectIdentifier subjectPolicyId = null;
+
+ if (mIssuerDomainPolicy != null)
+ issuerPolicyId = CMS.checkOID(
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY, mIssuerDomainPolicy);
+ if (mSubjectDomainPolicy != null)
+ subjectPolicyId = CMS.checkOID(
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY, mSubjectDomainPolicy);
+
+ // if enabled, form CertificatePolicyMap to be encoded in extension.
+ // policy ids should be all set.
+ if (enabled) {
+ mCertificatePolicyMap = new CertificatePolicyMap(
+ new CertificatePolicyId(issuerPolicyId),
+ new CertificatePolicyId(subjectPolicyId));
+ }
+ }
+
+ protected void getInstanceParams(Vector instanceParams) {
+ instanceParams.addElement(
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY + "=" + (mIssuerDomainPolicy == null ? "" :
+ mIssuerDomainPolicy));
+ instanceParams.addElement(
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY + "=" + (mSubjectDomainPolicy == null ? "" :
+ mSubjectDomainPolicy));
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java
new file mode 100644
index 000000000..60da8f9a3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java
@@ -0,0 +1,164 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ca.*;
+import netscape.ldap.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+/**
+ * Checks extension presence.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PresenceExt extends APolicyRule {
+ private static Vector mDefParams = new Vector();
+ private IConfigStore mConfig = null;
+ private String mOID = null;
+ private boolean mCritical;
+ private int mVersion = 0;
+ private String mStreetAddress;
+ private String mTelephoneNumber;
+ private String mRFC822Name;
+ private String mID;
+ private String mHostName;
+ private int mPortNumber = 0;
+ private int mMaxUsers = 0;
+ private int mServiceLevel = 0;
+
+ public static final String PROP_IS_CRITICAL = "critical";
+ public static final String PROP_OID = "oid";
+ public static final String PROP_VERSION = "version";
+ public static final String PROP_STREET_ADDRESS = "streetAddress";
+ public static final String PROP_TELEPHONE_NUMBER = "telephoneNumber";
+ public static final String PROP_RFC822_NAME = "rfc822Name";
+ public static final String PROP_ID = "id";
+ public static final String PROP_HOSTNAME = "hostName";
+ public static final String PROP_PORT_NUMBER = "portNumber";
+ public static final String PROP_MAX_USERS = "maxUsers";
+ public static final String PROP_SERVICE_LEVEL = "serviceLevel";
+
+ static {
+ mDefParams.addElement(PROP_IS_CRITICAL + "=false");
+ }
+
+ public PresenceExt() {
+ NAME = "PresenceExtPolicy";
+ DESC = "Sets Presence Server Extension in certificates.";
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, false);
+ mOID = config.getString(PROP_OID, "");
+ mVersion = config.getInteger(PROP_VERSION, 0);
+ mStreetAddress = config.getString(PROP_STREET_ADDRESS, "");
+ mTelephoneNumber = config.getString(PROP_TELEPHONE_NUMBER, "");
+ mRFC822Name = config.getString(PROP_RFC822_NAME, "");
+ mID = config.getString(PROP_ID, "");
+ mHostName = config.getString(PROP_HOSTNAME, "");
+ mPortNumber = config.getInteger(PROP_PORT_NUMBER, 0);
+ mMaxUsers = config.getInteger(PROP_MAX_USERS, 0);
+ mServiceLevel = config.getInteger(PROP_SERVICE_LEVEL, 0);
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ /*
+ PresenceServerExtension ext = new PresenceServerExtension(mCritical,
+ mOID, mVersion, mStreetAddress,
+ mTelephoneNumber, mRFC822Name, mID,
+ mHostName, mPortNumber, mMaxUsers, mServiceLevel);
+ */
+
+ return res;
+ }
+
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_OID + "=" + mOID);
+ params.addElement(PROP_VERSION + "=" + mVersion);
+ params.addElement(PROP_STREET_ADDRESS + "=" + mStreetAddress);
+ params.addElement(PROP_TELEPHONE_NUMBER + "=" + mTelephoneNumber);
+ params.addElement(PROP_RFC822_NAME + "=" + mRFC822Name);
+ params.addElement(PROP_ID + "=" + mID);
+ params.addElement(PROP_HOSTNAME + "=" + mHostName);
+ params.addElement(PROP_PORT_NUMBER + "=" + mPortNumber);
+ params.addElement(PROP_MAX_USERS + "=" + mMaxUsers);
+ params.addElement(PROP_SERVICE_LEVEL + "=" + mServiceLevel);
+ return params;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_IS_CRITICAL + ";boolean;Criticality",
+ PROP_OID + ";string; Object identifier of this extension",
+ PROP_VERSION + ";string; version",
+ PROP_STREET_ADDRESS + ";string; street address",
+ PROP_TELEPHONE_NUMBER + ";string; telephone number",
+ PROP_RFC822_NAME + ";string; rfc822 name",
+ PROP_ID + ";string; identifier",
+ PROP_HOSTNAME + ";string; host name",
+ PROP_PORT_NUMBER + ";string; port number",
+ PROP_MAX_USERS + ";string; max users",
+ PROP_SERVICE_LEVEL + ";string; service level",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-presenceext",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Presence Server Extension;"
+
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
new file mode 100644
index 000000000..468abdf7b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
@@ -0,0 +1,250 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * PrivateKeyUsagePeriod Identifier Extension policy.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PrivateKeyUsagePeriodExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ private final static String PROP_NOT_BEFORE = "notBefore";
+ private final static String PROP_NOT_AFTER = "notAfter";
+ protected static final String PROP_IS_CRITICAL = "critical";
+
+ // 6 months roughly
+ private final static long defDuration = 60L * 60 * 24 * 180 * 1000;
+
+ private static final String DATE_PATTERN = "MM/dd/yyyy";
+ static SimpleDateFormat formatter = new SimpleDateFormat(DATE_PATTERN);
+ private static Date now = CMS.getCurrentDate();
+ private static Date six_months = new Date(now.getTime() + defDuration);
+
+ public static final String DEFAULT_NOT_BEFORE = formatter.format(now);
+ public static final String DEFAULT_NOT_AFTER = formatter.format(six_months);
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ protected String mNotBefore;
+ protected String mNotAfter;
+ protected boolean mCritical;
+
+ private static Vector defaultParams;
+
+ static {
+
+ formatter.setLenient(false);
+
+ defaultParams = new Vector();
+ defaultParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defaultParams.addElement(PROP_NOT_BEFORE + "=" + DEFAULT_NOT_BEFORE);
+ defaultParams.addElement(PROP_NOT_AFTER + "=" + DEFAULT_NOT_AFTER);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_IS_CRITICAL + ";boolean;RFC 2459 recommendation: The profile " +
+ "recommends against the use of this extension. CAs " +
+ "conforming to the profile MUST NOT generate certs with " +
+ "critical private key usage period extensions.",
+ PROP_NOT_BEFORE + ";string; Date before which the Private Key is invalid.",
+ PROP_NOT_AFTER + ";string; Date after which the Private Key is invalid.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-privatekeyusageperiod",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds (deprecated) Private Key Usage Period Extension. " +
+ "Defined in RFC 2459 (4.2.1.4)"
+ };
+
+ return params;
+ }
+
+ /**
+ * Adds the private key usage extension to all certs.
+ */
+ public PrivateKeyUsagePeriodExt() {
+ NAME = "PrivateKeyUsagePeriodExt";
+ DESC = "Sets Private Key Usage Extension for a certificate";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * ra.Policy.rule.<ruleName>.implName=PrivateKeyUsageExtension
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.notBefore=30
+ * ra.Policy.rule.<ruleName>.notAfter=180
+ * ra.Policy.rule.<ruleName>.critical=false
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ try {
+ // Get params.
+ mNotBefore = config.getString(PROP_NOT_BEFORE, null);
+ mNotAfter = config.getString(PROP_NOT_AFTER, null);
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, false);
+
+ // Check the parameter formats
+ String notBefore;
+ String notAfter;
+
+ notBefore = formatter.format(formatter.parse(mNotBefore.trim()));
+ notAfter = formatter.format(formatter.parse(mNotAfter.trim()));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ Object[] params = {getInstanceName(), e};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ }
+
+ }
+
+ /**
+ * Adds a private key usage extension if none exists.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // get private key usage extension from cert info if any.
+ CertificateExtensions extensions = null;
+ PrivateKeyUsageExtension ext = null;
+
+ try {
+ // get subject key id extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // no extensions or subject key identifier extension.
+ } catch (CertificateException e) {
+ // no extensions or subject key identifier extension.
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(PrivateKeyUsageExtension.NAME);
+
+ } catch (IOException e) {
+ }
+
+ }
+
+ try {
+ ext = new PrivateKeyUsageExtension(
+ formatter.parse(mNotBefore),
+ formatter.parse(mNotAfter));
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions.set(PrivateKeyUsageExtension.NAME, ext);
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CREATE_PRIVATE_KEY_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return Empty Vector since this policy has no configuration parameters.
+ * for this policy instance.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_NOT_BEFORE + "=" + mNotBefore);
+ params.addElement(PROP_NOT_AFTER + "=" + mNotAfter);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return Empty Vector since this policy implementation has no
+ * configuration parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defParams.addElement(PROP_NOT_BEFORE + "=" + DEFAULT_NOT_BEFORE);
+ defParams.addElement(PROP_NOT_AFTER + "=" + DEFAULT_NOT_AFTER);
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
new file mode 100644
index 000000000..b8dba995e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
@@ -0,0 +1,141 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Remove Basic Constraints policy.
+ * Adds the Basic constraints extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RemoveBasicConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public RemoveBasicConstraintsExt() {
+ NAME = "RemoveBasicConstraintsExt";
+ DESC = "Remove Basic Constraints extension";
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, certInfo);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(
+ IRequest req, X509CertInfo certInfo) {
+ // get basic constraints extension from cert info if any.
+ CertificateExtensions extensions = null;
+
+ try {
+ // get basic constraints extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions != null) {
+ try {
+ extensions.delete(BasicConstraintsExtension.NAME);
+ CMS.debug("PolicyRule RemoveBasicConstraintsExt: removed the extension from request " + req.getRequestId().toString());
+ } catch (IOException e) {
+ }
+ }
+ } catch (IOException e) {
+ // no extensions or basic constraints extension.
+ } catch (CertificateException e) {
+ // no extensions or basic constraints extension.
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ return defParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-removebasicconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Removes the Basic Constraints extension."
+ };
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java
new file mode 100644
index 000000000..32e2c48fb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java
@@ -0,0 +1,350 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ *
+ * THIS POLICY HAS BEEN DEPRECATED SINCE CMS 4.2.
+ * New Policy is com.netscape.certsrv.policy.SubjectAltNameExt.
+ * <p>
+ *
+ * Subject Alternative Name extension policy in CMS 4.1.
+ *
+ * Adds the subject alternative name extension depending on the
+ * certificate type requested.
+ *
+ * Two forms are supported. 1) For S/MIME certificates, email
+ * addresses are copied from data stored in the request by the
+ * authentication component. Both 'e' and 'altEmail' are supported
+ * so that both the primary address and alternative forms may be
+ * certified. Only the primary goes in the subjectName position (which
+ * should be phased out).
+ *
+ * e
+ * mailAlternateAddress
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ // for future use. currently always allow.
+ protected static final String PROP_AGENT_OVERR = "allowAgentOverride";
+ protected static final String PROP_EE_OVERR = "AllowEEOverride";
+ protected static final String PROP_ENABLE_MANUAL_VALUES =
+ "enableManualValues";
+
+ // for future use. currently always non-critical
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+
+ // for future use to allow overrides from forms.
+ // request must be agent approved or authenticated.
+ protected boolean mAllowAgentOverride = false;
+ protected boolean mAllowEEOverride = false;
+ protected boolean mEnableManualValues = false;
+
+ // for future use. currently always critical
+ // (standard says SHOULD be marked critical if included.)
+ protected boolean mCritical = false;
+
+ public SubjAltNameExt() {
+ NAME = "SubjAltNameExt";
+ DESC = "Sets alternative subject names for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: If the certificate subject field contains an empty sequence, the subjectAltName extension MUST be marked critical.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjaltname",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Subject Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.7). " +
+ "* Note: you probably want to use this policy in " +
+ "conjunction with an authentication manager which sets " +
+ "the 'mail' or 'mailalternateaddress' values in the authToken. " +
+ "See the 'ldapStringAttrs' parameter in the Directory-based " +
+ "authentication plugin"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=SubjAltNameExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // future use.
+ mAllowAgentOverride = config.getBoolean(PROP_AGENT_OVERR, false);
+ mAllowEEOverride = config.getBoolean(PROP_EE_OVERR, false);
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ // mEnableManualValues = config.getBoolean(PROP_ENABLE_MANUAL_VALUES, false);
+ }
+
+ /**
+ * Adds the subject alternative names extension if not set already.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // Find the X509CertInfo object in the request
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ //
+ // General error handling block
+ //
+ apply:
+ try {
+
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ //
+ // Remove any previously computed version of the extension
+ //
+ try {
+ extensions.delete(SubjectAlternativeNameExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+
+ //
+ // Determine the type of the request. For future expansion
+ // this test should dispatch to a specialized object to
+ // handle each particular type. For now just return for
+ // non-client certs, and implement client certs directly here.
+ //
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType == null ||
+ !certType.equals(IRequest.CLIENT_CERT) ||
+ !req.getExtDataInBoolean(IRequest.SMIME, false)) {
+ break apply;
+ }
+
+ // Create a list of email addresses that should be added
+ // to the certificate
+
+ IAuthToken tok = findAuthToken(req, null);
+
+ if (tok == null) break apply;
+
+ Vector emails = getEmailList(tok);
+
+ if (emails == null) break apply;
+
+ // Create the extension
+ SubjectAlternativeNameExtension subjAltNameExt = mkExt(emails);
+
+ if (extensions == null)
+ extensions = createCertificateExtensions(certInfo);
+
+ extensions.set(SubjectAlternativeNameExtension.NAME,
+ subjAltNameExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ return res;
+ }
+
+ /**
+ * Find a particular authentication token by manager name.
+ * If the token is not present return null
+ */
+ protected IAuthToken
+ findAuthToken(IRequest req, String authMgrName) {
+
+ return req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+ }
+
+ /**
+ * Generate a String Vector containing all the email addresses
+ * found in this Authentication token
+ */
+ protected Vector /* of String */
+ getEmailList(IAuthToken tok) {
+
+ Vector v = new Vector();
+
+ addValues(tok, "mail", v);
+ addValues(tok, "mailalternateaddress", v);
+
+ if (v.size() == 0) return null;
+
+ return v;
+ }
+
+ /**
+ * Add attribute values from an LDAP attribute to a vector
+ */
+ protected void
+ addValues(IAuthToken tok, String attrName, Vector v) {
+ String attr[] = tok.getInStringArray(attrName);
+
+ if (attr == null) return;
+
+ for (int i = 0; i < attr.length; i++) {
+ v.addElement(attr[i]);
+ }
+ }
+
+ /**
+ * Make a Subject name extension given a list of email addresses
+ */
+ protected SubjectAlternativeNameExtension
+ mkExt(Vector emails)
+ throws IOException {
+ SubjectAlternativeNameExtension sa;
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < emails.size(); i++) {
+ String email = (String) emails.elementAt(i);
+
+ gns.addElement(new RFC822Name(email));
+ }
+
+ sa = new SubjectAlternativeNameExtension(gns);
+
+ return sa;
+ }
+
+ /**
+ * Create a new SET of extensions in the certificate info
+ * object.
+ *
+ * This should be a method in the X509CertInfo object
+ */
+ protected CertificateExtensions
+ createCertificateExtensions(X509CertInfo certInfo)
+ throws IOException, CertificateException {
+ CertificateExtensions extensions;
+
+ // Force version to V3
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ return extensions;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ //params.addElement("PROP_AGENT_OVERR = " + mAllowAgentOverride);
+ //params.addElement("PROP_EE_OVERR = " + mAllowEEOverride);
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ // params.addElement(PROP_ENABLE_MANUAL_VALUES + " = " +
+ // mEnableManualValues);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ //defParams.addElement("PROP_AGENT_OVERR = " + DEF_AGENT_OVERR);
+ //defParams.addElement("PROP_EE_OVERR = " + DEF_EE_OVERR);
+ defParams.addElement(PROP_CRITICAL + "=false");
+ // defParams.addElement(PROP_ENABLE_MANUAL_VALUES + "= false");
+
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java
new file mode 100644
index 000000000..eb7dba173
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java
@@ -0,0 +1,322 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Subject Alternative Name extension policy.
+ *
+ * Adds the subject alternative name extension as configured.
+ *
+ * Two forms are supported. 1) For S/MIME certificates, email
+ * addresses are copied from data stored in the request by the
+ * authentication component. Both 'e' and 'altEmail' are supported
+ * so that both the primary address and alternative forms may be
+ * certified. Only the primary goes in the subjectName position (which
+ * should be phased out).
+ *
+ * e
+ * mailAlternateAddress
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final boolean DEF_CRITICAL = false;
+
+ protected IConfigStore mConfig = null;
+ protected boolean mEnabled = false;
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumGNs = 0;
+ protected ISubjAltNameConfig[] mGNs = null;
+
+ Vector mInstanceParams = new Vector();
+
+ // init default params and extended plugin info.
+ private static Vector mDefParams = new Vector();
+ static {
+ // default params.
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES + "=" +
+ IGeneralNameUtil.DEF_NUM_GENERALNAMES);
+ for (int i = 0; i < IGeneralNameUtil.DEF_NUM_GENERALNAMES; i++) {
+ CMS.getSubjAltNameConfigDefaultParams(
+ IGeneralNameUtil.PROP_GENERALNAME + i, mDefParams);
+ }
+ }
+
+ private String[] mExtendedPluginInfo = null;
+
+ public SubjectAltNameExt() {
+ NAME = "SubjectAltNameExt";
+ DESC = "Sets alternative subject names for certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=SubjectAltNameExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // get criticality
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ // get enabled
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+
+ // get general names configuration.
+ mNumGNs = mConfig.getInteger(IGeneralNameUtil.PROP_NUM_GENERALNAMES);
+ if (mNumGNs <= 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER",
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES));
+ }
+ mGNs = new ISubjAltNameConfig[mNumGNs];
+ for (int i = 0; i < mNumGNs; i++) {
+ String name = IGeneralNameUtil.PROP_GENERALNAME + i;
+ IConfigStore substore = mConfig.getSubStore(name);
+
+ mGNs[i] = CMS.createSubjAltNameConfig(name, substore, mEnabled);
+ }
+
+ // init instance params.
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES + "=" + mNumGNs);
+ for (int j = 0; j < mGNs.length; j++) {
+ mGNs[j].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Adds the subject alternative names extension if not set already.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // Find the X509CertInfo object in the request
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // Remove any previously computed version of the extension
+ // unless it is from RA. If from RA, accept what RA put in
+ // request and don't add our own.
+ if (extensions != null) {
+ String sourceId = req.getSourceId();
+
+ if (sourceId != null && sourceId.length() > 0)
+ return res; // accepted
+ try {
+ extensions.delete(SubjectAlternativeNameExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+
+ // form list of general names for the extension.
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < mNumGNs; i++) {
+ Object value = null;
+
+ value = req.getExtDataInString(mGNs[i].getPfx(), mGNs[i].getAttr());
+ if (value == null) {
+ continue;
+ }
+ Vector gn = mGNs[i].formGeneralNames(value);
+
+ if (gn.size() == 0)
+ continue;
+ for (Enumeration n = gn.elements(); n.hasMoreElements();) {
+ gns.addElement((GeneralName) n.nextElement());
+ }
+ }
+
+ // nothing was found in request to put into extension
+ if (gns.size() == 0)
+ return res; // accepted
+
+ String subject = certInfo.get(X509CertInfo.SUBJECT).toString();
+
+ boolean curCritical = mCritical;
+
+ if (subject.equals("")) {
+ curCritical = true;
+ }
+
+ // make the extension
+ SubjectAlternativeNameExtension
+ sa = new SubjectAlternativeNameExtension(curCritical, gns);
+
+ // add it to certInfo.
+ if (extensions == null)
+ extensions = createCertificateExtensions(certInfo);
+
+ extensions.set(SubjectAlternativeNameExtension.NAME, sa);
+
+ return res; // accepted.
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INTERNAL_ERROR_1", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Internal Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * Create a new SET of extensions in the certificate info
+ * object.
+ *
+ * This should be a method in the X509CertInfo object
+ */
+ protected CertificateExtensions
+ createCertificateExtensions(X509CertInfo certInfo)
+ throws IOException, CertificateException {
+ CertificateExtensions extensions;
+
+ // Force version to V3
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ return extensions;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+
+ // extended plugin info.
+ Vector info = new Vector();
+
+ info.addElement(PROP_CRITICAL + ";boolean;RFC2459 recommendation: If the certificate subject field contains an empty sequence, the extension MUST be marked critical.");
+ info.addElement(IGeneralNameUtil.PROP_NUM_GENERALNAMES_INFO);
+ for (int i = 0; i < IGeneralNameUtil.DEF_NUM_GENERALNAMES; i++) {
+ CMS.getSubjAltNameConfigExtendedPluginInfo(
+ IGeneralNameUtil.PROP_GENERALNAME + i, info);
+ }
+ info.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjaltname");
+ info.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Subject Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.7). " +
+ "* Note: you probably want to use this policy in " +
+ "conjunction with an authentication manager which sets " +
+ "the 'mail' or 'mailalternateaddress' values in the authToken. " +
+ "See the 'ldapStringAttrs' parameter in the Directory-based " +
+ "authentication plugin");
+ mExtendedPluginInfo = new String[info.size()];
+ info.copyInto(mExtendedPluginInfo);
+ return mExtendedPluginInfo;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
new file mode 100644
index 000000000..be065245a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
@@ -0,0 +1,434 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy to add the subject directory attributes extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectDirectoryAttributesExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_ATTRIBUTE = "attribute";
+ protected static final String PROP_NUM_ATTRIBUTES = "numAttributes";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_ATTRIBUTES = 3;
+ protected static final int MAX_NUM_ATTRIBUTES = 10;
+
+ protected boolean mCritical;
+ protected int mNumAttributes;
+ protected AttributeConfig[] mAttributes = null;
+
+ protected IConfigStore mConfig;
+ protected SubjectDirAttributesExtension mExt = null;
+
+ protected Vector mParams = new Vector();
+ private String[] mEPI = null; // extended plugin info
+ protected static Vector mDefParams = new Vector();
+
+ static {
+ setDefaultParams();
+ }
+
+ public SubjectDirectoryAttributesExt() {
+ NAME = "SubjectDirectoryAttributesExtPolicy";
+ DESC = "Sets Subject Directory Attributes Extension in certificates.";
+ setExtendedPluginInfo();
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ boolean enabled = config.getBoolean("enabled", false);
+
+ mConfig = config;
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, false);
+ mNumAttributes = mConfig.getInteger(PROP_NUM_ATTRIBUTES, DEF_NUM_ATTRIBUTES);
+ if (mNumAttributes < 1) {
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_NUM_ATTRIBUTES));
+
+ log(ILogger.LL_FAILURE, NAME + " Error: " + ex.toString());
+ throw ex;
+ }
+ mAttributes = new AttributeConfig[mNumAttributes];
+ for (int i = 0; i < mNumAttributes; i++) {
+ String name = PROP_ATTRIBUTE + i;
+ IConfigStore c = mConfig.getSubStore(name);
+
+ mAttributes[i] = new AttributeConfig(name, c, enabled);
+ }
+ if (enabled) {
+ try {
+ mExt = formExt(null);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, NAME + " Error: " + e.getMessage());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error forming Subject Directory Attributes Extension. " +
+ "See log file for details."));
+ }
+ }
+ setInstanceParams();
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ CertificateExtensions extensions = null;
+ SubjectDirAttributesExtension subjDirExt = null;
+
+ try {
+ // get extension and remove if exists.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(SubjectDirAttributesExtension.NAME);
+ } catch (IOException ee) {
+ // if name is not found, try deleting the extension using the OID
+ try {
+ extensions.delete("2.5.29.9");
+ } catch (IOException eee) {
+ }
+ }
+ }
+
+ // form extension and set.
+ if (mExt != null) {
+ extensions.set(SubjectDirAttributesExtension.NAME, mExt);
+ } else {
+ SubjectDirAttributesExtension ext = formExt(req);
+
+ if (ext != null)
+ extensions.set(SubjectDirAttributesExtension.NAME, formExt(req));
+ }
+ return PolicyResult.ACCEPTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "IOException Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ private Vector formValues(String val) {
+ StringTokenizer tokenizer = new StringTokenizer(val, "+");
+ Vector v = new Vector();
+
+ while (tokenizer.hasMoreElements()) {
+ String s = (String) tokenizer.nextElement();
+
+ v.addElement(s);
+ }
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ return mParams; // inited in init()
+ }
+
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return mEPI; // inited in the constructor.
+ }
+
+ private void setInstanceParams() {
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mParams.addElement(PROP_NUM_ATTRIBUTES + "=" + mNumAttributes);
+ for (int i = 0; i < mNumAttributes; i++) {
+ mAttributes[i].getInstanceParams(mParams);
+ }
+ // clean up others if exists. expensive.
+ for (int j = mNumAttributes; j < MAX_NUM_ATTRIBUTES; j++) {
+ mConfig.removeSubStore(PROP_ATTRIBUTE + j);
+ }
+ }
+
+ private static void setDefaultParams() {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(PROP_NUM_ATTRIBUTES + "=" + DEF_NUM_ATTRIBUTES);
+ for (int i = 0; i < DEF_NUM_ATTRIBUTES; i++) {
+ AttributeConfig.getDefaultParams(PROP_ATTRIBUTE + i, mDefParams);
+ }
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST be non-critical.");
+ v.addElement(PROP_NUM_ATTRIBUTES + ";number;" +
+ "Number of Attributes in the extension.");
+
+ for (int i = 0; i < MAX_NUM_ATTRIBUTES; i++) {
+ AttributeConfig.getExtendedPluginInfo(PROP_ATTRIBUTE + i, v);
+ }
+
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjectdirectoryattributes");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Subject Directory Attributes extension. See RFC 2459 (4.2.1.9). It's not recommended as an essential part of the profile, but may be used in local environments.");
+
+ mEPI = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ private SubjectDirAttributesExtension formExt(IRequest req)
+ throws IOException {
+ Vector attrs = new Vector();
+
+ // if we're called from init and one attribute is from request attribute
+ // the ext can't be formed yet.
+ if (req == null) {
+ for (int i = 0; i < mNumAttributes; i++) {
+ if (mAttributes[i].mWhereToGetValue ==
+ AttributeConfig.USE_REQUEST_ATTR)
+ return null;
+ }
+ }
+ // either we're called from apply or all values are fixed.
+ for (int i = 0; i < mNumAttributes; i++) {
+ if (mAttributes[i].mAttribute != null) {
+ attrs.addElement(mAttributes[i].mAttribute);
+ } else {
+ // skip attribute if request attribute doesn't exist.
+ Attribute a = mAttributes[i].formAttr(req);
+
+ if (a == null)
+ continue;
+ attrs.addElement(a);
+ }
+ }
+ if (attrs.size() == 0)
+ return null;
+ Attribute[] attrList = new Attribute[attrs.size()];
+
+ attrs.copyInto(attrList);
+ SubjectDirAttributesExtension ext =
+ new SubjectDirAttributesExtension(attrList);
+
+ return ext;
+ }
+}
+
+
+class AttributeConfig {
+
+ protected static final String PROP_ATTRIBUTE_NAME = "attributeName";
+ protected static final String PROP_WTG_VALUE = "whereToGetValue";
+ protected static final String PROP_VALUE = "value";
+
+ protected static final String USE_REQUEST_ATTR = "Request Attribute";
+ protected static final String USE_FIXED = "Fixed Value";
+
+ protected String mAttributeName = null;
+ protected String mWhereToGetValue = null;
+ protected String mValue = null;
+
+ protected String mPrefix = null;
+ protected String mReqAttr = null;
+ protected ObjectIdentifier mAttributeOID = null;
+
+ protected String mName = null;
+ protected IConfigStore mConfig = null;
+ protected Attribute mAttribute = null;
+
+ protected static final String ATTRIBUTE_NAME_INFO = "Attribute name.";
+ protected static final String WTG_VALUE_INFO =
+ PROP_WTG_VALUE + ";choice(" + USE_REQUEST_ATTR + "," + USE_FIXED + ");" +
+ "Get value from a request attribute or use a fixed value specified below.";
+ protected static final String VALUE_INFO =
+ PROP_VALUE + ";string;" +
+ "Request attribute name or a fixed value to put into the extension.";
+
+ public AttributeConfig(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ X500NameAttrMap map = X500NameAttrMap.getDefault();
+
+ mName = name;
+ mConfig = config;
+ if (enabled) {
+ mAttributeName = mConfig.getString(PROP_ATTRIBUTE_NAME);
+ mWhereToGetValue = mConfig.getString(PROP_WTG_VALUE);
+ mValue = mConfig.getString(PROP_VALUE);
+ } else {
+ mAttributeName = mConfig.getString(PROP_ATTRIBUTE_NAME, "");
+ mWhereToGetValue = mConfig.getString(PROP_WTG_VALUE, USE_REQUEST_ATTR);
+ mValue = mConfig.getString(PROP_VALUE, "");
+ }
+
+ if (mAttributeName.length() > 0) {
+ mAttributeOID = map.getOid(mAttributeName);
+ if (mAttributeOID == null)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", mAttributeName));
+ }
+
+ if (mWhereToGetValue.equalsIgnoreCase(USE_REQUEST_ATTR)) {
+ mWhereToGetValue = USE_REQUEST_ATTR;
+ if (enabled && mValue.length() == 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", PROP_VALUE));
+ }
+ int dot = mValue.indexOf('.');
+
+ if (dot != -1) {
+ mPrefix = mValue.substring(0, dot);
+ mReqAttr = mValue.substring(dot + 1);
+ if (mPrefix == null || mPrefix.length() == 0 ||
+ mReqAttr == null || mReqAttr.length() == 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", mValue));
+ }
+ } else {
+ mPrefix = null;
+ mReqAttr = mValue;
+ }
+ } else if (mWhereToGetValue.equalsIgnoreCase(USE_FIXED)) {
+ mWhereToGetValue = USE_FIXED;
+ if (mAttributeOID != null) {
+ try {
+ checkValue(mAttributeOID, mValue);
+ mAttribute = new Attribute(mAttributeOID, mValue);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mAttributeName, e.getMessage()));
+ }
+ }
+ } else if (enabled || mWhereToGetValue.length() > 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_VALUE_FOR_TYPE", PROP_WTG_VALUE,
+ "Must be either '" + USE_REQUEST_ATTR + "' or '" + USE_FIXED + "'."));
+ }
+ }
+
+ public static void getDefaultParams(String name, Vector v) {
+ String nameDot = name + ".";
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + "=");
+ v.addElement(nameDot + PROP_WTG_VALUE + "=" + USE_REQUEST_ATTR);
+ v.addElement(nameDot + PROP_VALUE + "=");
+ }
+
+ public static void getExtendedPluginInfo(String name, Vector v) {
+ String nameDot = name + ".";
+ String attrChoices = getAllNames();
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + ";choice(" + attrChoices + ");" +
+ ATTRIBUTE_NAME_INFO);
+ v.addElement(nameDot + WTG_VALUE_INFO);
+ v.addElement(nameDot + VALUE_INFO);
+ }
+
+ public void getInstanceParams(Vector v) {
+ String nameDot = mName + ".";
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + "=" + mAttributeName);
+ v.addElement(nameDot + PROP_WTG_VALUE + "=" + mWhereToGetValue);
+ v.addElement(nameDot + PROP_VALUE + "=" + mValue);
+ }
+
+ public Attribute formAttr(IRequest req)
+ throws IOException {
+ String val = req.getExtDataInString(mPrefix, mReqAttr);
+
+ if (val == null || val.length() == 0) {
+ return null;
+ }
+ checkValue(mAttributeOID, val);
+ return new Attribute(mAttributeOID, val);
+ }
+
+ static private String getAllNames() {
+ Enumeration n = X500NameAttrMap.getDefault().getAllNames();
+ StringBuffer sb = new StringBuffer();
+ sb.append((String) n.nextElement());
+
+ while (n.hasMoreElements()) {
+ sb.append(",");
+ sb.append((String) n.nextElement());
+ }
+ return sb.toString();
+ }
+
+ private static void checkValue(ObjectIdentifier oid, String val)
+ throws IOException {
+ AVAValueConverter c = X500NameAttrMap.getDefault().getValueConverter(oid);
+ DerValue derval;
+
+ derval = c.getValue(val); // errs encountered will get thrown.
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
new file mode 100644
index 000000000..a8069be29
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
@@ -0,0 +1,368 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidKeyException;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Subject Public Key Extension Policy
+ * Adds the subject public key id extension to certificates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectKeyIdentifierExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_KEYID_TYPE = "keyIdentifierType";
+ protected static final String PROP_REQATTR_NAME = "requestAttrName";
+
+ protected static final String KEYID_TYPE_SHA1 = "SHA1";
+ protected static final String KEYID_TYPE_TYPEFIELD = "TypeField";
+ protected static final String KEYID_TYPE_SPKISHA1 = "SpkiSHA1";
+ protected static final String KEYID_TYPE_REQATTR = "RequestAttribute";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final String DEF_KEYID_TYPE = KEYID_TYPE_SHA1;
+ protected static final String DEF_REQATTR_NAME = "KeyIdentifier";
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected String mKeyIdType = DEF_KEYID_TYPE;;
+ protected String mReqAttrName = DEF_REQATTR_NAME;
+
+ protected Vector mInstanceParams = new Vector();
+
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ // form static default params.
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(PROP_KEYID_TYPE + "=" + DEF_KEYID_TYPE);
+
+ /*
+ mDefaultParams.addElement(PROP_REQATTR_NAME+"="+DEF_REQATTR_NAME);
+ */
+ }
+
+ public SubjectKeyIdentifierExt() {
+ NAME = "SubjectKeyIdentifierExt";
+ DESC = "Adds Subject Key Idenifier Extension to certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mKeyIdType = mConfig.getString(PROP_KEYID_TYPE, DEF_KEYID_TYPE);
+
+ /*
+ mReqAttrName = mConfig.getString(PROP_REQATTR_NAME, DEF_REQATTR_NAME);
+ */
+
+ // parse key id type
+ if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_SHA1))
+ mKeyIdType = KEYID_TYPE_SHA1;
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_TYPEFIELD))
+ mKeyIdType = KEYID_TYPE_TYPEFIELD;
+
+ /*
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_REQATTR)
+ mKeyIdType = KEYID_TYPE_REQATTR;
+ */
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_SPKISHA1))
+ mKeyIdType = KEYID_TYPE_SPKISHA1;
+ else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("KRA_UNKNOWN_KEY_ID_TYPE", mKeyIdType));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_KEYID_TYPE,
+ "value must be one of " +
+ KEYID_TYPE_SHA1 + ", " +
+ KEYID_TYPE_TYPEFIELD + ", " +
+ KEYID_TYPE_SPKISHA1));
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(PROP_KEYID_TYPE + "=" + mKeyIdType);
+
+ /*
+ mInstanceParams.addElement(PROP_REQATTR_NAME+"="+mReqAttrName);
+ */
+ }
+
+ /**
+ * Adds Subject Key identifier Extension to a certificate.
+ * If the extension is already there, accept it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // if subject key id extension already exists, leave it if approved.
+ SubjectKeyIdentifierExtension subjectKeyIdExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ subjectKeyIdExt = (SubjectKeyIdentifierExtension)
+ extensions.get(SubjectKeyIdentifierExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+ if (subjectKeyIdExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "SubjectKeyIdentifierExt: agent approved request id " + req.getRequestId() +
+ " already has subject key id extension with value " +
+ subjectKeyIdExt);
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "SubjectKeyIdentifierExt: request id from user " + req.getRequestId() +
+ " had subject key identifier - deleted to be replaced");
+ extensions.delete(SubjectKeyIdentifierExtension.NAME);
+ }
+ }
+
+ // create subject key id extension.
+ KeyIdentifier keyId = null;
+
+ try {
+ keyId = formKeyIdentifier(certInfo, req);
+ } catch (EBaseException e) {
+ setPolicyException(req, e);
+ return PolicyResult.REJECTED;
+ }
+ subjectKeyIdExt =
+ new SubjectKeyIdentifierExtension(
+ mCritical, keyId.getIdentifier());
+
+ // add subject key id extension.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ SubjectKeyIdentifierExtension.NAME, subjectKeyIdExt);
+ CMS.debug(
+ "SubjectKeyIdentifierExt: added subject key id ext to request " + req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR,NAME", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Form the Key Identifier in the Subject Key Identifier extension.
+ * <p>
+ * @param certInfo Certificate Info
+ * @param req request
+ * @return A Key Identifier.
+ */
+ protected KeyIdentifier formKeyIdentifier(
+ X509CertInfo certInfo, IRequest req) throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ if (mKeyIdType == KEYID_TYPE_SHA1) {
+ keyId = formSHA1KeyId(certInfo);
+ } else if (mKeyIdType == KEYID_TYPE_TYPEFIELD) {
+ keyId = formTypeFieldKeyId(certInfo);
+ } /*
+ else if (mKeyIdType == KEYID_TYPE_REQATTR) {
+ keyId = formReqAttrKeyId(certInfo, req);
+ }
+ */ else if (mKeyIdType == KEYID_TYPE_SPKISHA1) {
+ keyId = formSpkiSHA1KeyId(certInfo);
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mKeyIdType, "Unknown Key Identifier type."));
+ }
+ return keyId;
+ }
+
+ /**
+ * Form key identifier from a type field value of 0100 followed by
+ * the least significate 60 bits of the sha-1 hash of the subject
+ * public key BIT STRING in accordance with RFC 2459.
+ * <p>
+ * @param certInfo - certificate info
+ * @return A Key Identifier with value formulatd as described.
+ */
+
+ protected KeyIdentifier formTypeFieldKeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+ X509Key key = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", NAME));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", NAME));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_GET_KEY_FROM_CERT", e.toString()));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_GET_KEY_FROM_CERT", e.toString()));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ try {
+ byte[] octetString = new byte[8];
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getKey());
+ byte[] hash = md.digest();
+
+ System.arraycopy(hash, hash.length - 8, octetString, 0, 8);
+ octetString[0] &= (0x08f & octetString[0]);
+ keyId = new KeyIdentifier(octetString);
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ /**
+ * Gets extended plugin info for pretty Console displays.
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST NOT be marked critical.",
+ PROP_KEYID_TYPE + ";" +
+ "choice(" + KEYID_TYPE_SHA1 + "," +
+ KEYID_TYPE_TYPEFIELD + "," +
+ KEYID_TYPE_SPKISHA1 + ");" +
+ "Method to derive the Key Identifier.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjectkeyidentifier",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds the Subject Key Identifier extension. See RFC 2459 (4.2.1.2)"
+ };
+
+ return params;
+ }
+}
+
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
new file mode 100644
index 000000000..aac1bb3c0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
@@ -0,0 +1,1186 @@
+// --- 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.common;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.registry.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * This class implements a basic profile.
+ *
+ * @version $Revision$, $Date$
+ */
+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_XML_OUTPUT = "xmlOutput";
+ public static final String PROP_VISIBLE = "visible";
+ public static final String PROP_INPUT_LIST = "list";
+ public static final String PROP_OUTPUT_LIST = "list";
+ public static final String PROP_UPDATER_LIST = "list";
+ public static final String PROP_POLICY_LIST = "list";
+ public static final String PROP_DEFAULT = "default";
+ public static final String PROP_CONSTRAINT = "constraint";
+ public static final String PROP_INPUT = "input";
+ public static final String PROP_OUTPUT = "output";
+ public static final String PROP_CLASS_ID = "class_id";
+ public static final String PROP_INSTANCE_ID = "instance_id";
+ public static final String PROP_PARAMS = "params";
+ public static final String PROP_NAME = "name";
+ public static final String PROP_DESC = "desc";
+ public static final String PROP_NO_DEFAULT = "noDefaultImpl";
+ public static final String PROP_NO_CONSTRAINT= "noConstraintImpl";
+ public static final String PROP_GENERIC_EXT_DEFAULT= "genericExtDefaultImpl";
+
+ protected IProfileSubsystem mOwner = null;
+ protected IConfigStore mConfig = null;
+ protected IPluginRegistry mRegistry = null;
+
+ protected Vector mInputNames = new Vector();
+ protected Hashtable mInputs = new Hashtable();
+ protected Vector mInputIds = new Vector();
+ protected Hashtable mOutputs = new Hashtable();
+ protected Vector mOutputIds = new Vector();
+ protected Hashtable mUpdaters = new Hashtable();
+ protected Vector mUpdaterIds = new Vector();
+ protected IProfileAuthenticator mAuthenticator = null;
+ protected String mAuthInstanceId = null;
+ protected String mId = null;
+ protected String mAuthzAcl = "";
+
+ protected Hashtable mPolicySet = new Hashtable();
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ public BasicProfile() {
+ }
+
+ public boolean isEnable() {
+ try {
+ return mConfig.getBoolean(PROP_ENABLE, false);
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+
+ public String isRenewal() {
+ try {
+ return mConfig.getString(PROP_IS_RENEWAL, "false");
+ } catch (EBaseException e) {
+ return "false";
+ }
+ }
+
+ public String isXmlOutput() {
+ try {
+ return mConfig.getString(PROP_XML_OUTPUT, "false");
+ } catch (EBaseException e) {
+ return "false";
+ }
+ }
+
+ public String getApprovedBy() {
+ try {
+ return mConfig.getString(PROP_ENABLE_BY, "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public IProfileAuthenticator getAuthenticator() throws EProfileException {
+ try {
+ IAuthSubsystem authSub = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IProfileAuthenticator auth = (IProfileAuthenticator)
+ authSub.get(mAuthInstanceId);
+
+ if (mAuthInstanceId != null && mAuthInstanceId.length() > 0
+ && auth == null) {
+ throw new EProfileException("Cannot load " +
+ mAuthInstanceId);
+ }
+ return auth;
+ } catch (Exception e) {
+ if (mAuthInstanceId != null) {
+ throw new EProfileException("Cannot load " +
+ mAuthInstanceId);
+ }
+ return null;
+ }
+ }
+
+ public String getRequestorDN(IRequest request) {
+ return null;
+ }
+
+ public String getAuthenticatorId() {
+ return mAuthInstanceId;
+ }
+
+ public void setAuthenticatorId(String id) {
+ mAuthInstanceId = id;
+ mConfig.putString("auth." + PROP_INSTANCE_ID, id);
+ }
+
+ public String getAuthzAcl() {
+ return mAuthzAcl;
+ }
+
+ /**
+ * Initializes this profile.
+ */
+ public void init(IProfileSubsystem owner, IConfigStore config)
+ throws EBaseException {
+ CMS.debug("BasicProfile: start init");
+ mOwner = owner;
+ mConfig = config;
+
+ mRegistry = (IPluginRegistry) CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+
+ // Configure File Formats:
+ // visible
+ // auth.class_id=NoAuthImpl
+ // auth.params.x1=x1
+ // input.list=i1,i2,...
+ // input.i1.class=com.netscape.cms.profile.input.CertReqInput
+ // input.i1.params.x1=x1
+ // policy.list=p1,p2,...
+ // policy.p1.enable=true
+ // policy.p1.default.class=com.netscape.cms.profile.defaults.SubjectName
+ // policy.p1.default.params.x1=x1
+ // policy.p1.default.params.x2=x2
+ // policy.p1.constraint.class= ... .cms.profile.constraints.ValidityRange
+ // policy.p1.constraint.params.x1=x1
+ // policy.p1.constraint.params.x2=x2
+
+ // handle profile authentication plugins
+ try {
+ mAuthInstanceId = config.getString("auth." + PROP_INSTANCE_ID, null);
+ mAuthzAcl = config.getString("authz.acl", "");
+ } catch (EBaseException e) {
+ CMS.debug("BasicProfile: authentication class not found " +
+ e.toString());
+ }
+
+ // handle profile input plugins
+ IConfigStore inputStore = config.getSubStore("input");
+ String input_list = inputStore.getString(PROP_INPUT_LIST, "");
+ StringTokenizer input_st = new StringTokenizer(input_list, ",");
+
+ while (input_st.hasMoreTokens()) {
+ String input_id = (String) input_st.nextToken();
+ String inputClassId = inputStore.getString(input_id + "." +
+ PROP_CLASS_ID);
+ IPluginInfo inputInfo = mRegistry.getPluginInfo("profileInput",
+ inputClassId);
+ String inputClass = inputInfo.getClassName();
+
+ IProfileInput input = null;
+
+ try {
+ input = (IProfileInput)
+ Class.forName(inputClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug("BasicProfile: input plugin Class.forName " +
+ inputClass + " " + e.toString());
+ throw new EBaseException( e.toString() );
+ }
+ IConfigStore inputConfig = inputStore.getSubStore(input_id);
+ input.init(this, inputConfig);
+ mInputs.put(input_id, input);
+ mInputIds.addElement(input_id);
+ }
+
+ // handle profile output plugins
+ IConfigStore outputStore = config.getSubStore("output");
+ String output_list = outputStore.getString(PROP_OUTPUT_LIST, "");
+ StringTokenizer output_st = new StringTokenizer(output_list, ",");
+
+ while (output_st.hasMoreTokens()) {
+ String output_id = (String) output_st.nextToken();
+
+ String outputClassId = outputStore.getString(output_id + "." +
+ PROP_CLASS_ID);
+ IPluginInfo outputInfo = mRegistry.getPluginInfo("profileOutput",
+ outputClassId);
+ String outputClass = outputInfo.getClassName();
+
+ IProfileOutput output = null;
+
+ try {
+ output = (IProfileOutput)
+ Class.forName(outputClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug("BasicProfile: output plugin Class.forName " +
+ outputClass + " " + e.toString());
+ throw new EBaseException( e.toString() );
+ }
+ IConfigStore outputConfig = outputStore.getSubStore(output_id);
+ output.init(this, outputConfig);
+ mOutputs.put(output_id, output);
+ mOutputIds.addElement(output_id);
+ }
+
+ // handle profile output plugins
+ IConfigStore updaterStore = config.getSubStore("updater");
+ String updater_list = updaterStore.getString(PROP_UPDATER_LIST, "");
+ StringTokenizer updater_st = new StringTokenizer(updater_list, ",");
+
+ while (updater_st.hasMoreTokens()) {
+ String updater_id = (String) updater_st.nextToken();
+
+ String updaterClassId = updaterStore.getString(updater_id + "." +
+ PROP_CLASS_ID);
+ IPluginInfo updaterInfo = mRegistry.getPluginInfo("profileUpdater",
+ updaterClassId);
+ String updaterClass = updaterInfo.getClassName();
+
+ IProfileUpdater updater = null;
+
+ try {
+ updater = (IProfileUpdater)
+ Class.forName(updaterClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug("BasicProfile: updater plugin Class.forName " +
+ updaterClass + " " + e.toString());
+ throw new EBaseException( e.toString() );
+ }
+ IConfigStore updaterConfig = updaterStore.getSubStore(updater_id);
+ updater.init(this, updaterConfig);
+ mUpdaters.put(updater_id, updater);
+ mUpdaterIds.addElement(updater_id);
+ }
+
+ // handle profile policy plugins
+ IConfigStore policySetStore = config.getSubStore("policyset");
+ String setlist = policySetStore.getString("list", "");
+ StringTokenizer st = new StringTokenizer(setlist, ",");
+
+ while (st.hasMoreTokens()) {
+ String setId = (String) st.nextToken();
+
+ IConfigStore policyStore = policySetStore.getSubStore(setId);
+ String list = policyStore.getString(PROP_POLICY_LIST, "");
+ StringTokenizer st1 = new StringTokenizer(list, ",");
+
+ while (st1.hasMoreTokens()) {
+ String id = (String) st1.nextToken();
+
+ String defaultRoot = id + "." + PROP_DEFAULT;
+ String defaultClassId = policyStore.getString(defaultRoot + "." +
+ PROP_CLASS_ID);
+
+ String constraintRoot = id + "." + PROP_CONSTRAINT;
+ String constraintClassId =
+ policyStore.getString(constraintRoot + "." + PROP_CLASS_ID);
+
+ createProfilePolicy(setId, id, defaultClassId,
+ constraintClassId, false);
+ }
+ }
+ CMS.debug("BasicProfile: done init");
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public Enumeration getInputNames() {
+ return mInputNames.elements();
+ }
+
+ public Enumeration getProfileUpdaterIds() {
+ return mUpdaterIds.elements(); // ordered list
+ }
+
+ public IProfileUpdater getProfileUpdater(String name) {
+ return (IProfileUpdater) mUpdaters.get(name);
+ }
+
+ public Enumeration getProfileOutputIds() {
+ return mOutputIds.elements(); // ordered list
+ }
+
+ public IProfileOutput getProfileOutput(String name) {
+ return (IProfileOutput) mOutputs.get(name);
+ }
+
+ public Enumeration getProfileInputIds() {
+ return mInputIds.elements(); // ordered list
+ }
+
+ public IProfileInput getProfileInput(String name) {
+ return (IProfileInput) mInputs.get(name);
+ }
+
+ public void addInputName(String name) {
+ mInputNames.addElement(name);
+ }
+
+ public IDescriptor getInputDescriptor(String name) {
+ return null;
+ }
+
+ public String getInput(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ return null;
+ }
+
+ public void setInput(String name, Locale locale, IRequest request,
+ String value) throws EProfileException {
+ }
+
+ public Enumeration getProfilePolicySetIds() {
+ return mPolicySet.keys();
+ }
+
+ public void deleteProfilePolicy(String setId, String policyId)
+ throws EProfileException {
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ if (policies == null) {
+ return;
+ }
+ try {
+ IConfigStore policySetSubStore = mConfig.getSubStore("policyset");
+ IConfigStore policySubStore = policySetSubStore.getSubStore(setId);
+
+ policySubStore.removeSubStore(policyId);
+ String list = policySubStore.getString(PROP_POLICY_LIST, null);
+ StringTokenizer st = new StringTokenizer(list, ",");
+ String newlist = "";
+ StringBuffer sb = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ String e = st.nextToken();
+
+ if (!e.equals(policyId)) {
+ sb.append(e);
+ sb.append(",");
+ }
+ }
+ newlist = sb.toString();
+ if (!newlist.equals("")) {
+ newlist = newlist.substring(0, newlist.length() - 1);
+ policySubStore.putString(PROP_POLICY_LIST, newlist);
+ } else {
+ policySetSubStore.removeSubStore(setId);
+ }
+
+ int size = policies.size();
+ boolean found = false;
+
+ for (int i = 0; i < size; i++) {
+ ProfilePolicy policy = (ProfilePolicy) policies.elementAt(i);
+ String id = policy.getId();
+
+ if (id.equals(policyId)) {
+ policies.removeElementAt(i);
+ if (size == 1) {
+ mPolicySet.remove(setId);
+ String setlist = policySetSubStore.getString(PROP_POLICY_LIST, null);
+ StringTokenizer st1 = new StringTokenizer(setlist, ",");
+ String newlist1 = "";
+
+ while (st1.hasMoreTokens()) {
+ String e = st1.nextToken();
+
+ if (!e.equals(setId))
+ newlist1 = newlist1 + e + ",";
+ }
+ if (!newlist1.equals(""))
+ newlist1 = newlist1.substring(0, newlist1.length() - 1);
+ policySetSubStore.putString(PROP_POLICY_LIST, newlist1);
+ }
+ break;
+ }
+ }
+
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ mConfig.commit(false);
+ } catch (Exception e) {
+ }
+
+ }
+
+ public void deleteProfileInput(String inputId) throws EProfileException {
+ try {
+ mConfig.removeSubStore("input." + inputId);
+ String list = mConfig.getString("input." + PROP_INPUT_LIST, null);
+ StringTokenizer st = new StringTokenizer(list, ",");
+ String newlist = "";
+ StringBuffer sb = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ String e = st.nextToken();
+
+ if (!e.equals(inputId)) {
+ sb.append(e);
+ sb.append(",");
+ }
+ }
+ newlist = sb.toString();
+ if (!newlist.equals(""))
+ newlist = newlist.substring(0, newlist.length() - 1);
+
+ int size = mInputIds.size();
+ boolean found = false;
+
+ for (int i = 0; i < size; i++) {
+ String id = (String) mInputIds.elementAt(i);
+
+ if (id.equals(inputId)) {
+ mInputIds.removeElementAt(i);
+ break;
+ }
+ }
+
+ mInputs.remove(inputId);
+ mConfig.putString("input." + PROP_INPUT_LIST, newlist);
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ mConfig.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public void deleteProfileOutput(String outputId) throws EProfileException {
+ try {
+ mConfig.removeSubStore("output." + outputId);
+ String list = mConfig.getString("output." + PROP_OUTPUT_LIST, null);
+ StringTokenizer st = new StringTokenizer(list, ",");
+ String newlist = "";
+ StringBuffer sb = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ String e = st.nextToken();
+
+ if (!e.equals(outputId)) {
+ sb.append(e);
+ sb.append(",");
+ }
+ }
+ newlist = sb.toString();
+ if (!newlist.equals(""))
+ newlist = newlist.substring(0, newlist.length() - 1);
+
+ int size = mOutputIds.size();
+ boolean found = false;
+
+ for (int i = 0; i < size; i++) {
+ String id = (String) mOutputIds.elementAt(i);
+
+ if (id.equals(outputId)) {
+ mOutputIds.removeElementAt(i);
+ break;
+ }
+ }
+
+ mOutputs.remove(outputId);
+ mConfig.putString("output." + PROP_OUTPUT_LIST, newlist);
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ mConfig.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public IProfileOutput createProfileOutput(String id, String outputId,
+ NameValuePairs nvps)
+ throws EProfileException {
+ return createProfileOutput(id, outputId, nvps, true);
+ }
+
+ public IProfileOutput createProfileOutput(String id, String outputId,
+ NameValuePairs nvps, boolean createConfig)
+
+
+ throws EProfileException {
+ IConfigStore outputStore = mConfig.getSubStore("output");
+ String output_list = null;
+
+ try {
+ output_list = outputStore.getString(PROP_OUTPUT_LIST, "");
+ } catch (Exception ee) {
+ }
+
+ IPluginInfo outputInfo = mRegistry.getPluginInfo("profileOutput",
+ outputId);
+
+ if (outputInfo == null) {
+ CMS.debug("Cannot find " + outputId);
+ throw new EProfileException("Cannot find " + outputId);
+ }
+ String outputClass = outputInfo.getClassName();
+
+ CMS.debug("BasicProfile: loading output class " + outputClass);
+ IProfileOutput output = null;
+
+ try {
+ output = (IProfileOutput)
+ Class.forName(outputClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug(e.toString());
+ }
+ if (output == null) {
+ CMS.debug("BasicProfile: failed to create " + outputClass);
+ } else {
+ CMS.debug("BasicProfile: initing " + id + " output");
+
+ CMS.debug("BasicProfile: outputStore " + outputStore);
+ output.init(this, outputStore);
+
+ mOutputs.put(id, output);
+ mOutputIds.addElement(id);
+ }
+
+ if (createConfig) {
+ String list = null;
+
+ try {
+ list = outputStore.getString(PROP_OUTPUT_LIST, null);
+ } catch (EBaseException e) {
+ }
+ if (list == null || list.equals("")) {
+ outputStore.putString(PROP_OUTPUT_LIST, id);
+ } else {
+ StringTokenizer st1 = new StringTokenizer(list, ",");
+
+ while (st1.hasMoreTokens()) {
+ String pid = st1.nextToken();
+
+ if (pid.equals(id)) {
+ throw new EProfileException("Duplicate output id: " + id);
+ }
+ }
+ outputStore.putString(PROP_OUTPUT_LIST, list + "," + id);
+ }
+ String prefix = id + ".";
+
+ outputStore.putString(prefix + "name",
+ outputInfo.getName(Locale.getDefault()));
+ outputStore.putString(prefix + "class_id", outputId);
+
+ Enumeration enum1 = nvps.getNames();
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ outputStore.putString(prefix + "params." + name, nvps.getValue(name));
+ try {
+ if (output != null) {
+ output.setConfig(name, nvps.getValue(name));
+ }
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ try {
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ mConfig.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ return output;
+ }
+
+ public IProfileInput createProfileInput(String id, String inputId,
+ NameValuePairs nvps)
+ throws EProfileException {
+ return createProfileInput(id, inputId, nvps, true);
+ }
+
+ public IProfileInput createProfileInput(String id, String inputId,
+ NameValuePairs nvps, boolean createConfig)
+ throws EProfileException {
+ IConfigStore inputStore = mConfig.getSubStore("input");
+
+ String input_list = null;
+
+ try {
+ input_list = inputStore.getString(PROP_INPUT_LIST, "");
+ } catch (Exception ee) {
+ }
+
+ IPluginInfo inputInfo = mRegistry.getPluginInfo("profileInput",
+ inputId);
+
+ if (inputInfo == null) {
+ CMS.debug("Cannot find " + inputId);
+ throw new EProfileException("Cannot find " + inputId);
+ }
+ String inputClass = inputInfo.getClassName();
+
+ CMS.debug("BasicProfile: loading input class " + inputClass);
+ IProfileInput input = null;
+
+ try {
+ input = (IProfileInput)
+ Class.forName(inputClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug(e.toString());
+ }
+ if (input == null) {
+ CMS.debug("BasicProfile: failed to create " + inputClass);
+ } else {
+ CMS.debug("BasicProfile: initing " + id + " input");
+
+ CMS.debug("BasicProfile: inputStore " + inputStore);
+ input.init(this, inputStore);
+
+ mInputs.put(id, input);
+ mInputIds.addElement(id);
+ }
+
+ if (createConfig) {
+ String list = null;
+
+ try {
+ list = inputStore.getString(PROP_INPUT_LIST, null);
+ } catch (EBaseException e) {
+ }
+ if (list == null || list.equals("")) {
+ inputStore.putString(PROP_INPUT_LIST, id);
+ } else {
+ StringTokenizer st1 = new StringTokenizer(list, ",");
+
+ while (st1.hasMoreTokens()) {
+ String pid = st1.nextToken();
+
+ if (pid.equals(id)) {
+ throw new EProfileException("Duplicate input id: " + id);
+ }
+ }
+ inputStore.putString(PROP_INPUT_LIST, list + "," + id);
+ }
+ String prefix = id + ".";
+
+ inputStore.putString(prefix + "name",
+ inputInfo.getName(Locale.getDefault()));
+ inputStore.putString(prefix + "class_id", inputId);
+
+ Enumeration enum1 = nvps.getNames();
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ inputStore.putString(prefix + "params." + name, nvps.getValue(name));
+ try {
+ if (input != null) {
+ input.setConfig(name, nvps.getValue(name));
+ }
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ try {
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ mConfig.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ return input;
+ }
+
+ /**
+ * Creates a profile policy
+ */
+ public IProfilePolicy createProfilePolicy(String setId, String id,
+ String defaultClassId, String constraintClassId)
+ throws EProfileException {
+ return createProfilePolicy(setId, id, defaultClassId,
+ constraintClassId, true);
+ }
+
+ public IProfilePolicy createProfilePolicy(String setId, String id,
+ String defaultClassId, String constraintClassId,
+ boolean createConfig)
+ throws EProfileException {
+
+ // String setId ex: policyset.set1
+ // String id Id of policy : examples: p1,p2,p3
+ // String defaultClassId : id of the default plugin ex: validityDefaultImpl
+ // String constraintClassId : if of the constraint plugin ex: basicConstraintsExtConstraintImpl
+ // boolean createConfig : true : being called from the console. false: being called from server startup code
+
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ IConfigStore policyStore = mConfig.getSubStore("policyset." + setId);
+ if (policies == null) {
+ policies = new Vector();
+ mPolicySet.put(setId, policies);
+ if (createConfig) {
+ // re-create policyset.list
+ StringBuffer setlist =new StringBuffer();
+ Enumeration keys = mPolicySet.keys();
+
+ while (keys.hasMoreElements()) {
+ String k = (String) keys.nextElement();
+
+ if (!(setlist.toString()).equals("")) {
+ setlist.append(",");
+ }
+ setlist.append(k);
+ }
+ mConfig.putString("policyset.list", setlist.toString());
+ }
+ } else {
+ String ids = null;
+
+ try {
+ ids = policyStore.getString(PROP_POLICY_LIST, "");
+ } catch (Exception ee) {
+ }
+
+ if( ids == null ) {
+ CMS.debug("BasicProfile::createProfilePolicy() - ids is null!" );
+ return null;
+ }
+
+ StringTokenizer st1 = new StringTokenizer(ids, ",");
+ int appearances = 0;
+ int appearancesTooMany = 0;
+ if (createConfig)
+ appearancesTooMany = 1;
+ else
+ appearancesTooMany = 2;
+
+ while (st1.hasMoreTokens()) {
+ String pid = st1.nextToken();
+ if (pid.equals(id)) {
+ appearances++;
+ if (appearances >= appearancesTooMany) {
+ CMS.debug("WARNING detected duplicate policy id: " + id + " Profile: " + mId);
+ if (createConfig) {
+ throw new EProfileException("Duplicate policy id: " + id);
+ }
+ }
+ }
+ }
+ }
+
+ // Now make sure we aren't trying to add a policy that already exists
+ IConfigStore policySetStore = mConfig.getSubStore("policyset");
+ String setlist = null;
+ try {
+ setlist = policySetStore.getString("list", "");
+ } catch (Exception e) {
+ }
+ StringTokenizer st = new StringTokenizer(setlist, ",");
+
+ int matches = 0;
+ while (st.hasMoreTokens()) {
+ String sId = (String) st.nextToken();
+
+ //Only search the setId set. Ex: encryptionCertSet
+ if (!sId.equals(setId)) {
+ continue;
+ }
+ IConfigStore pStore = policySetStore.getSubStore(sId);
+
+ String list = null;
+ try {
+ list = pStore.getString(PROP_POLICY_LIST, "");
+ } catch (Exception e) {
+ CMS.debug("WARNING, can't get policy id list!");
+ }
+
+ StringTokenizer st1 = new StringTokenizer(list, ",");
+
+ while (st1.hasMoreTokens()) {
+ String curId = (String) st1.nextToken();
+
+ String defaultRoot = curId + "." + PROP_DEFAULT;
+ String curDefaultClassId = null;
+ try {
+ curDefaultClassId = pStore.getString(defaultRoot + "." +
+ PROP_CLASS_ID);
+ } catch(Exception e) {
+ CMS.debug("WARNING, can't get default plugin id!");
+ }
+
+ String constraintRoot = curId + "." + PROP_CONSTRAINT;
+ String curConstraintClassId = null;
+ try {
+ curConstraintClassId = pStore.getString(constraintRoot + "." + PROP_CLASS_ID);
+ } catch (Exception e) {
+ CMS.debug("WARNING, can't get constraint plugin id!");
+ }
+
+ //Disallow duplicate defaults with the following exceptions:
+ // noDefaultImpl, genericExtDefaultImpl
+
+ if ((curDefaultClassId.equals(defaultClassId) &&
+ !curDefaultClassId.equals(PROP_NO_DEFAULT) &&
+ !curDefaultClassId.equals(PROP_GENERIC_EXT_DEFAULT)) ) {
+
+ matches++;
+ if (createConfig) {
+ if (matches == 1) {
+ CMS.debug("WARNING attempt to add duplicate Policy " + defaultClassId + ":" + constraintClassId +
+ " Contact System Administrator.");
+ throw new EProfileException("Attempt to add duplicate Policy : " + defaultClassId + ":" + constraintClassId);
+ }
+ } else {
+ if( matches > 1) {
+ CMS.debug("WARNING attempt to add duplicate Policy " + defaultClassId + ":" + constraintClassId +
+ " Contact System Administrator.");
+ }
+ }
+ }
+ }
+ }
+
+ String defaultRoot = id + "." + PROP_DEFAULT;
+ String constraintRoot = id + "." + PROP_CONSTRAINT;
+ IPluginInfo defInfo = mRegistry.getPluginInfo("defaultPolicy",
+ defaultClassId);
+
+ if (defInfo == null) {
+ CMS.debug("BasicProfile: Cannot find " + defaultClassId);
+ throw new EProfileException("Cannot find " + defaultClassId);
+ }
+ String defaultClass = defInfo.getClassName();
+
+ CMS.debug("BasicProfile: loading default class " + defaultClass);
+ IPolicyDefault def = null;
+
+ try {
+ def = (IPolicyDefault)
+ Class.forName(defaultClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug("BasicProfile: default policy " +
+ defaultClass + " " + e.toString());
+ }
+ if (def == null) {
+ CMS.debug("BasicProfile: failed to create " + defaultClass);
+ } else {
+ IConfigStore defStore = null;
+
+ defStore = policyStore.getSubStore(defaultRoot);
+ def.init(this, defStore);
+ }
+
+ IPluginInfo conInfo = mRegistry.getPluginInfo("constraintPolicy",
+ constraintClassId);
+ String constraintClass = conInfo.getClassName();
+ IPolicyConstraint constraint = null;
+
+ try {
+ constraint = (IPolicyConstraint)
+ Class.forName(constraintClass).newInstance();
+ } catch (Exception e) {
+ // throw Exception
+ CMS.debug("BasicProfile: constraint policy " +
+ constraintClass + " " + e.toString());
+ }
+ ProfilePolicy policy = null;
+ if (constraint == null) {
+ CMS.debug("BasicProfile: failed to create " + constraintClass);
+ } else {
+ IConfigStore conStore = null;
+
+ conStore = policyStore.getSubStore(constraintRoot);
+ constraint.init(this, conStore);
+ policy = new ProfilePolicy(id, def, constraint);
+ policies.addElement(policy);
+ }
+
+ if (createConfig) {
+ String list = null;
+
+ try {
+ list = policyStore.getString(PROP_POLICY_LIST, null);
+ } catch (EBaseException e) {
+ }
+ if (list == null || list.equals("")) {
+ policyStore.putString(PROP_POLICY_LIST, id);
+ } else {
+ policyStore.putString(PROP_POLICY_LIST, list + "," + id);
+ }
+ policyStore.putString(id + ".default.name",
+ defInfo.getName(Locale.getDefault()));
+ policyStore.putString(id + ".default.class_id",
+ defaultClassId);
+ policyStore.putString(id + ".constraint.name",
+ conInfo.getName(Locale.getDefault()));
+ policyStore.putString(id + ".constraint.class_id",
+ constraintClassId);
+ try {
+ mConfig.putString("lastModified",
+ Long.toString(CMS.getCurrentDate().getTime()));
+ policyStore.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug("BasicProfile: commiting config store " +
+ e.toString());
+ }
+ }
+
+ return policy;
+ }
+
+ public IProfilePolicy getProfilePolicy(String setId, String id) {
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = (ProfilePolicy) policies.elementAt(i);
+
+ if (policy.getId().equals(id)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+
+ public boolean isVisible() {
+ try {
+ return mConfig.getBoolean(PROP_VISIBLE, false);
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+
+ public void setVisible(boolean v) {
+ mConfig.putBoolean(PROP_VISIBLE, v);
+ }
+
+ /**
+ * Returns the profile name.
+ */
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(PROP_NAME, "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ public void setName(Locale locale, String name) {
+ mConfig.putString(PROP_NAME, name);
+ }
+
+ public abstract IProfileContext createContext();
+
+ /**
+ * Creates request.
+ */
+ public abstract IRequest[] createRequests(IProfileContext ctx, Locale locale)
+ throws EProfileException;
+
+ /**
+ * Returns the profile description.
+ */
+ public String getDescription(Locale locale) {
+ try {
+ return mConfig.getString(PROP_DESC, "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ public void setDescription(Locale locale, String desc) {
+ mConfig.putString(PROP_DESC, desc);
+ }
+
+ public void populateInput(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ Enumeration ids = getProfileInputIds();
+
+ while (ids.hasMoreElements()) {
+ String id = (String) ids.nextElement();
+ IProfileInput input = getProfileInput(id);
+
+ input.populate(ctx, request);
+ }
+ }
+
+ public Vector getPolicies(String setId) {
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ return policies;
+ }
+
+ /**
+ * Passes the request to the set of default policies that
+ * populate the profile information against the profile.
+ */
+ public void populate(IRequest request)
+ 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)
+ policies.elementAt(i);
+
+ policy.getDefault().populate(request);
+ }
+ }
+
+ /**
+ * Passes the request to the set of constraint policies
+ * that validate the request against the profile.
+ */
+ public void validate(IRequest request)
+ throws ERejectException {
+ String setId = getPolicySetId(request);
+ CMS.debug("BasicProfile: validate start on setId="+ setId);
+ Vector policies = getPolicies(setId);
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = (ProfilePolicy)
+ policies.elementAt(i);
+
+ policy.getConstraint().validate(request);
+ }
+ CMS.debug("BasicProfile: change to pending state");
+ request.setRequestStatus(RequestStatus.PENDING);
+ CMS.debug("BasicProfile: validate end");
+ }
+
+ public Enumeration getProfilePolicies(String setId) {
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+ return policies.elements();
+ }
+
+ public Enumeration getProfilePolicyIds(String setId) {
+ Vector policies = (Vector) mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+
+ Vector v = new Vector();
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = (ProfilePolicy)
+ policies.elementAt(i);
+
+ v.addElement(policy.getId());
+ }
+ return v.elements();
+ }
+
+ public void execute(IRequest request)
+ throws EProfileException {
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "BasicProfile"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "BasicProfile"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java
new file mode 100644
index 000000000..d525689bd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java
@@ -0,0 +1,147 @@
+// --- 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.common;
+
+
+import java.security.cert.*;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+/**
+ * This class implements a Certificate Manager enrollment
+ * profile for CA Certificates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CACertCAEnrollProfile extends CAEnrollProfile
+ implements IProfileEx {
+
+ /**
+ * Called after initialization. It populates default
+ * policies, inputs, and outputs.
+ */
+ public void populate() throws EBaseException
+ {
+ // create inputs
+ NameValuePairs inputParams1 = new NameValuePairs();
+ IProfileInput input1 =
+ createProfileInput("i1", "certReqInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ IProfileInput input2 =
+ createProfileInput("i2", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ IProfileOutput output1 =
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ // create policies
+ IProfilePolicy policy1 =
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def1 = policy1.getDefault();
+ IConfigStore defConfig1 = def1.getConfigStore();
+ IPolicyConstraint con1 = policy1.getConstraint();
+ IConfigStore conConfig1 = con1.getConfigStore();
+
+ IProfilePolicy policy2 =
+ createProfilePolicy("set1", "p2",
+ "validityDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def2 = policy2.getDefault();
+ IConfigStore defConfig2 = def2.getConfigStore();
+ defConfig2.putString("params.range","180");
+ defConfig2.putString("params.startTime","0");
+ IPolicyConstraint con2 = policy2.getConstraint();
+ IConfigStore conConfig2 = con2.getConfigStore();
+
+ IProfilePolicy policy3 =
+ createProfilePolicy("set1", "p3",
+ "userKeyDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def3 = policy3.getDefault();
+ IConfigStore defConfig3 = def3.getConfigStore();
+ defConfig3.putString("params.keyType","RSA");
+ defConfig3.putString("params.keyMinLength","512");
+ defConfig3.putString("params.keyMaxLength","4096");
+ IPolicyConstraint con3 = policy3.getConstraint();
+ IConfigStore conConfig3 = con3.getConfigStore();
+
+ IProfilePolicy policy4 =
+ createProfilePolicy("set1", "p4",
+ "signingAlgDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def4 = policy4.getDefault();
+ IConfigStore defConfig4 = def4.getConfigStore();
+ defConfig4.putString("params.signingAlg","-");
+ defConfig4.putString("params.signingAlgsAllowed",
+ "SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA256withEC,SHA384withEC,SHA512withEC");
+ IPolicyConstraint con4 = policy4.getConstraint();
+ IConfigStore conConfig4 = con4.getConfigStore();
+
+ // extensions
+ IProfilePolicy policy5 =
+ createProfilePolicy("set1", "p5",
+ "keyUsageExtDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def5 = policy5.getDefault();
+ IConfigStore defConfig5 = def5.getConfigStore();
+ defConfig5.putString("params.keyUsageCritical","true");
+ defConfig5.putString("params.keyUsageCrlSign","true");
+ defConfig5.putString("params.keyUsageDataEncipherment","false");
+ defConfig5.putString("params.keyUsageDecipherOnly","false");
+ defConfig5.putString("params.keyUsageDigitalSignature","true");
+ defConfig5.putString("params.keyUsageEncipherOnly","false");
+ defConfig5.putString("params.keyUsageKeyAgreement","false");
+ defConfig5.putString("params.keyUsageKeyCertSign","true");
+ defConfig5.putString("params.keyUsageKeyEncipherment","false");
+ defConfig5.putString("params.keyUsageNonRepudiation","true");
+ IPolicyConstraint con5 = policy5.getConstraint();
+ IConfigStore conConfig5 = con5.getConfigStore();
+
+ IProfilePolicy policy6 =
+ createProfilePolicy("set1", "p6",
+ "basicConstraintsExtDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def6 = policy6.getDefault();
+ IConfigStore defConfig6 = def6.getConfigStore();
+ defConfig6.putString("params.basicConstraintsPathLen","-1");
+ defConfig6.putString("params.basicConstraintsIsCA","true");
+ defConfig6.putString("params.basicConstraintsPathLen","-1");
+ IPolicyConstraint con6 = policy6.getConstraint();
+ IConfigStore conConfig6 = con6.getConfigStore();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java
new file mode 100644
index 000000000..c3b2a5ddc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java
@@ -0,0 +1,252 @@
+// --- 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.common;
+
+
+import java.security.cert.*;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+/**
+ * This class implements a Certificate Manager enrollment
+ * profile.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CAEnrollProfile extends EnrollProfile {
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4";
+
+
+ public CAEnrollProfile() {
+ super();
+ }
+
+ public IAuthority getAuthority() {
+ IAuthority authority = (IAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+
+ if (authority == null)
+ return null;
+ return authority;
+ }
+
+ public X500Name getIssuerName() {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ X500Name issuerName = ca.getX500Name();
+
+ return issuerName;
+ }
+
+ public void execute(IRequest request)
+ throws EProfileException {
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ if (!isEnable()) {
+ CMS.debug("CAEnrollProfile: Profile Not Enabled");
+ throw new EProfileException("Profile Not Enabled");
+ }
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(request);
+ String auditArchiveID = ILogger.UNIDENTIFIED;
+
+
+ String id = request.getRequestId().toString();
+ if (id != null) {
+ auditArchiveID = id.trim();
+ }
+
+ CMS.debug("CAEnrollProfile: execute reqId=" +
+ request.getRequestId().toString());
+ ICertificateAuthority ca = (ICertificateAuthority) getAuthority();
+ ICAService caService = (ICAService) ca.getCAService();
+
+ if (caService == null) {
+ throw new EProfileException("No CA Service");
+ }
+
+ // if PKI Archive Option present, send this request
+ // to DRM
+ byte optionsData[] = request.getExtDataInByteArray(REQUEST_ARCHIVE_OPTIONS);
+
+ // do not archive keys for renewal requests
+ if ((optionsData != null) && (!request.getRequestType().equals(IRequest.RENEWAL_REQUEST))) {
+ PKIArchiveOptions options = (PKIArchiveOptions)
+ toPKIArchiveOptions(optionsData);
+
+ if (options != null) {
+ CMS.debug("CAEnrollProfile: execute found " +
+ "PKIArchiveOptions");
+ try {
+ IConnector kraConnector = caService.getKRAConnector();
+
+ if (kraConnector == null) {
+ CMS.debug("CAEnrollProfile: KRA connector " +
+ "not configured");
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ } else {
+ CMS.debug("CAEnrollProfile: execute send request");
+ kraConnector.send(request);
+
+
+
+ // check response
+ if (!request.isSuccess()) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new ERejectException(
+ request.getError(getLocale(request)));
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ }
+ } catch (Exception e) {
+
+
+ if (e instanceof ERejectException) {
+ throw (ERejectException) e;
+ }
+ CMS.debug("CAEnrollProfile: " + e.toString());
+ CMS.debug(e);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EProfileException(e.toString());
+ }
+ }
+ }
+
+ // process certificate issuance
+ X509CertInfo info = request.getExtDataInCertInfo(REQUEST_CERTINFO);
+ X509CertImpl theCert = null;
+
+ // #615460 - added audit log (transaction)
+ SessionContext sc = SessionContext.getExistingContext();
+ sc.put("profileId", getId());
+ String setId = request.getExtDataInString("profileSetId");
+ if (setId != null) {
+ sc.put("profileSetId", setId);
+ }
+
+ try {
+ theCert = caService.issueX509Cert(info, getId() /* profileId */,
+ id /* requestId */);
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+
+ throw new EProfileException(e.toString());
+ }
+ request.setExtData(REQUEST_ISSUED_CERT, theCert);
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ String initiative = AuditFormat.FROMAGENT
+ + " userID: "
+ + (String)sc.get(SessionContext.USER_ID);
+ String authMgr = (String)sc.get(SessionContext.AUTH_MANAGER_ID);
+
+ ILogger logger = CMS.getLogger();
+ if( logger != null ) {
+ logger.log( ILogger.EV_AUDIT,
+ ILogger.S_OTHER, AuditFormat.LEVEL, AuditFormat.FORMAT,
+ new Object[] {
+ request.getRequestType(),
+ request.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ theCert.getSubjectDN(),
+ "cert issued serial number: 0x" +
+ theCert.getSerialNumber().toString(16) +
+ " time: " + (endTime - startTime) }
+ );
+ }
+
+ request.setRequestStatus(RequestStatus.COMPLETE);
+
+ // notifies updater plugins
+ Enumeration updaterIds = getProfileUpdaterIds();
+ while (updaterIds.hasMoreElements()) {
+ String updaterId = (String)updaterIds.nextElement();
+ IProfileUpdater updater = getProfileUpdater(updaterId);
+ updater.update(request, RequestStatus.COMPLETE);
+ }
+
+ // set value for predicate value - checking in getRule
+ if (CMS.isEncryptionCert(theCert))
+ request.setExtData("isEncryptionCert", "true");
+ else
+ request.setExtData("isEncryptionCert", "false");
+ }
+}
+
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
new file mode 100644
index 000000000..b60b73c9a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -0,0 +1,1403 @@
+// --- 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.common;
+
+
+import java.security.cert.CertificateException;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.util.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+
+
+/**
+ * This class implements a generic enrollment profile.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollProfile extends BasicProfile
+ implements IEnrollProfile {
+
+ private final static String LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5";
+ private final static String LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION =
+ "LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2";
+
+ private PKIData mCMCData;
+ public EnrollProfile() {
+ super();
+ }
+
+ public abstract IAuthority getAuthority();
+
+ public IRequestQueue getRequestQueue() {
+ IAuthority authority = getAuthority();
+
+ return authority.getRequestQueue();
+ }
+
+ public IProfileContext createContext() {
+ return new EnrollProfileContext();
+ }
+
+ /**
+ * Creates request.
+ */
+ public IRequest[] createRequests(IProfileContext context, Locale locale)
+ throws EProfileException {
+ EnrollProfileContext ctx = (EnrollProfileContext) context;
+
+ // determine how many requests should be created
+ String cert_request_type = ctx.get(CTX_CERT_REQUEST_TYPE);
+ String cert_request = ctx.get(CTX_CERT_REQUEST);
+ String is_renewal = ctx.get(CTX_RENEWAL);
+ Integer renewal_seq_num = 0;
+
+ /* cert_request_type can be null for the case of CMC */
+ if (cert_request_type == null) {
+ CMS.debug("EnrollProfile: request type is null");
+ }
+
+ int num_requests = 1; // default to 1 request
+
+ if (cert_request_type != null && cert_request_type.startsWith("pkcs10")) {
+ // catch for invalid request
+ parsePKCS10(locale, cert_request);
+ }
+ if (cert_request_type != null && cert_request_type.startsWith("crmf")) {
+ CertReqMsg msgs[] = parseCRMF(locale, cert_request);
+
+ num_requests = msgs.length;
+ }
+ if (cert_request_type != null && cert_request_type.startsWith("cmc")) {
+ // catch for invalid request
+ TaggedRequest[] msgs = parseCMC(locale, cert_request);
+ if (msgs == null)
+ return null;
+ else
+ num_requests = msgs.length;
+ }
+
+ // only 1 request for renewal
+ if ((is_renewal != null) && (is_renewal.equals("true"))) {
+ num_requests = 1;
+ String renewal_seq_num_str = ctx.get(CTX_RENEWAL_SEQ_NUM);
+ if (renewal_seq_num_str != null) {
+ renewal_seq_num = Integer.parseInt(renewal_seq_num_str);
+ } else {
+ renewal_seq_num =0;
+ }
+ }
+
+
+ // populate requests with appropriate content
+ IRequest result[] = new IRequest[num_requests];
+
+ for (int i = 0; i < num_requests; i++) {
+ result[i] = createEnrollmentRequest();
+ if ((is_renewal != null) && (is_renewal.equals("true"))) {
+ result[i].setExtData(REQUEST_SEQ_NUM,renewal_seq_num);
+ } else {
+ result[i].setExtData(REQUEST_SEQ_NUM, Integer.valueOf(i));
+ }
+ if (locale != null) {
+ result[i].setExtData(REQUEST_LOCALE, locale.getLanguage());
+ }
+ }
+ return result;
+ }
+
+ public abstract X500Name getIssuerName();
+
+ public void setDefaultCertInfo(IRequest req) throws EProfileException {
+ // create an empty certificate template so that
+ // default plugins that store stuff
+ X509CertInfo info = new X509CertInfo();
+
+ // retrieve issuer name
+ X500Name issuerName = getIssuerName();
+
+ byte[] dummykey = new byte[] {
+ 48, 92, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5,
+ 0, 3, 75, 0, 48, 72, 2, 65, 0, -65, 121, -119, -59, 105, 66,
+ -122, -78, -30, -64, 63, -47, 44, -48, -104, 103, -47, -108,
+ 42, -38, 46, -8, 32, 49, -29, -26, -112, -29, -86,71, 24,
+ -104, 78, -31, -75, -128, 90, -92, -34, -51, -125, -13, 80, 101,
+ -78, 39, -119, -38, 117, 28, 67, -19, -71, -124, -85, 105, -53,
+ -103, -59, -67, -38, -83, 118, 65, 2, 3, 1, 0, 1};
+ // default values into x509 certinfo. This thing is
+ // not serializable by default
+ try {
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ info.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber(new BigInteger("0")));
+ info.set(X509CertInfo.ISSUER,
+ new CertificateIssuerName(issuerName));
+ info.set(X509CertInfo.KEY,
+ new CertificateX509Key(X509Key.parse(new DerValue(dummykey))));
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(issuerName));
+ info.set(X509CertInfo.VALIDITY,
+ new CertificateValidity(new Date(), new Date()));
+ info.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(
+ AlgorithmId.getAlgorithmId("MD5withRSA")));
+
+ // add default extension container
+ info.set(X509CertInfo.EXTENSIONS,
+ new CertificateExtensions());
+ } catch (Exception e) {
+ // throw exception - add key to template
+ CMS.debug("EnrollProfile: Building X509CertInfo - " + e.toString());
+ throw new EProfileException(e.toString());
+ }
+ req.setExtData(REQUEST_CERTINFO, info);
+ }
+
+ public IRequest createEnrollmentRequest()
+ throws EProfileException {
+ IRequest req = null;
+
+ try {
+ req = getRequestQueue().newRequest("enrollment");
+
+ setDefaultCertInfo(req);
+
+ // put the certificate info into request
+ req.setExtData(REQUEST_EXTENSIONS,
+ new CertificateExtensions());
+
+ CMS.debug("EnrollProfile: createRequest " +
+ req.getRequestId().toString());
+ } catch (EBaseException e) {
+ // raise exception
+ CMS.debug("EnrollProfile: create new enroll request " +
+ e.toString());
+ }
+
+ return req;
+ }
+
+ public abstract void execute(IRequest request)
+ throws EProfileException;
+
+ /**
+ * Perform simple policy set assignment.
+ */
+ public String getPolicySetId(IRequest req) {
+ Integer seq = req.getExtDataInInteger(REQUEST_SEQ_NUM);
+ int seq_no = seq.intValue(); // start from 0
+
+ int count = 0;
+ Enumeration setIds = getProfilePolicySetIds();
+
+ while (setIds.hasMoreElements()) {
+ String setId = (String) setIds.nextElement();
+
+ if (count == seq_no) {
+ return setId;
+ }
+ count++;
+ }
+ return null;
+ }
+
+ public String getRequestorDN(IRequest request) {
+ X509CertInfo info = request.getExtDataInCertInfo(REQUEST_CERTINFO);
+
+ try {
+ CertificateSubjectName sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+
+ return sn.toString();
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: getRequestDN " + e.toString());
+ }
+ return null;
+ }
+
+ /**
+ * This method is called after the user submits the
+ * request from the end-entity page.
+ */
+ public void submit(IAuthToken token, IRequest request)
+ throws EDeferException, EProfileException {
+ // Request Submission Logic:
+ //
+ // if (Authentication Failed) {
+ // return Error
+ // } else {
+ // if (No Auth Token) {
+ // queue request
+ // } else {
+ // process request
+ // }
+ // }
+
+ IAuthority authority = (IAuthority)
+ getAuthority();
+ IRequestQueue queue = authority.getRequestQueue();
+
+ // this profile queues request that is authenticated
+ // by NoAuth
+ try {
+ queue.updateRequest(request);
+ } catch (EBaseException e) {
+ // save request to disk
+ CMS.debug("EnrollProfile: Update request " + e.toString());
+ }
+
+ if (token == null) {
+ CMS.debug("EnrollProfile: auth token is null");
+ CMS.debug("EnrollProfile: validating request");
+ validate(request);
+ try {
+ queue.updateRequest(request);
+ } catch (EBaseException e) {
+ CMS.debug("EnrollProfile: Update request (after validation) " + e.toString());
+ }
+
+ throw new EDeferException("defer request");
+ } else {
+ // this profile executes request that is authenticated
+ // by non NoAuth
+ CMS.debug("EnrollProfile: auth token is not null");
+ validate(request);
+ execute(request);
+ }
+ }
+
+ public TaggedRequest[] parseCMC(Locale locale, String certreq)
+ throws EProfileException {
+ /* cert request must not be null */
+ if (certreq == null) {
+ CMS.debug("EnrollProfile: parseCMC() certreq null");
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ CMS.debug("EnrollProfile: Start parseCMC(): " + certreq);
+
+ Hashtable t1 = new Hashtable();
+ TaggedRequest msgs[] = null;
+
+ String creq = normalizeCertReq(certreq);
+ try {
+ byte data[] = CMS.AtoB(creq);
+ ByteArrayInputStream cmcBlobIn =
+ new ByteArrayInputStream(data);
+
+ org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(cmcBlobIn);
+ org.mozilla.jss.pkix.cms.SignedData cmcFullReq = (org.mozilla.jss.pkix.cms.SignedData)cmcReq.getInterpretedContent();
+ org.mozilla.jss.pkix.cms.EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+ OBJECT_IDENTIFIER id = ci.getContentType();
+ OCTET_STRING content = ci.getContent();
+
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ mCMCData = pkiData;
+ //PKIData pkiData = (PKIData)
+ // (new PKIData.Template()).decode(cmcBlobIn);
+ SEQUENCE controlSeq = pkiData.getControlSequence();
+ int numcontrols = controlSeq.size();
+ SEQUENCE reqSeq = pkiData.getReqSequence();
+ byte randomSeed[] = null;
+ SessionContext context = SessionContext.getContext();
+ if (!context.containsKey("numOfControls")) {
+ if (numcontrols > 0) {
+ context.put("numOfControls", Integer.valueOf(numcontrols));
+ TaggedAttribute[] attributes = new TaggedAttribute[numcontrols];
+ for (int i=0; i<numcontrols; i++) {
+ attributes[i] = (TaggedAttribute)controlSeq.elementAt(i);
+ OBJECT_IDENTIFIER oid = attributes[i].getType();
+ if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identityProof)) {
+ boolean valid = verifyIdentityProof(attributes[i],
+ reqSeq);
+ if (!valid) {
+ SEQUENCE bpids = getRequestBpids(reqSeq);
+ context.put("identityProof", bpids);
+ return null;
+ }
+ } else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkRandom)) {
+ SET vals = attributes[i].getValues();
+ OCTET_STRING ostr =
+ (OCTET_STRING)(ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ randomSeed = ostr.toByteArray();
+ } else {
+ context.put(attributes[i].getType(), attributes[i]);
+ }
+ }
+ }
+ }
+
+ SEQUENCE otherMsgSeq = pkiData.getOtherMsgSequence();
+ int numOtherMsgs = otherMsgSeq.size();
+ if (!context.containsKey("numOfOtherMsgs")) {
+ context.put("numOfOtherMsgs", Integer.valueOf(numOtherMsgs));
+ for (int i=0; i<numOtherMsgs; i++) {
+ OtherMsg omsg =(OtherMsg)(ASN1Util.decode(OtherMsg.getTemplate(),
+ ASN1Util.encode(otherMsgSeq.elementAt(i))));
+ context.put("otherMsg"+i, omsg);
+ }
+ }
+
+ int nummsgs = reqSeq.size();
+ if (nummsgs > 0) {
+ msgs = new TaggedRequest[reqSeq.size()];
+ SEQUENCE bpids = new SEQUENCE();
+ boolean valid = true;
+ for (int i = 0; i < nummsgs; i++) {
+ msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
+ if (!context.containsKey("POPLinkWitness")) {
+ if (randomSeed != null) {
+ valid = verifyPOPLinkWitness(randomSeed, msgs[i], bpids);
+ if (!valid || bpids.size() > 0) {
+ context.put("POPLinkWitness", bpids);
+ return null;
+ }
+ }
+ }
+ }
+ } else
+ return null;
+
+ return msgs;
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: parseCMC " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+ private boolean verifyPOPLinkWitness(byte[] randomSeed, TaggedRequest req,
+ SEQUENCE bpids) {
+ ISharedToken tokenClass = null;
+ boolean sharedSecretFound = true;
+ String name = null;
+ try {
+ name = CMS.getConfigStore().getString("cmc.sharedSecret.class");
+ } catch (EPropertyNotFound e) {
+ CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
+ sharedSecretFound = false;
+ } catch (EBaseException e) {
+ CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
+ sharedSecretFound = false;
+ }
+
+ try {
+ tokenClass = (ISharedToken)Class.forName(name).newInstance();
+ } catch (ClassNotFoundException e) {
+ CMS.debug("EnrollProfile: Failed to find class name: "+name);
+ sharedSecretFound = false;
+ } catch (InstantiationException e) {
+ CMS.debug("EnrollProfile: Failed to instantiate class: "+name);
+ sharedSecretFound = false;
+ } catch (IllegalAccessException e) {
+ CMS.debug("EnrollProfile: Illegal access: "+name);
+ sharedSecretFound = false;
+ }
+
+ INTEGER reqId = null;
+ byte[] bv = null;
+ String sharedSecret = null;
+ if (tokenClass != null)
+ sharedSecret = tokenClass.getSharedToken(mCMCData);
+ if (req.getType().equals(TaggedRequest.PKCS10)) {
+ TaggedCertificationRequest tcr = req.getTcr();
+ if (!sharedSecretFound) {
+ bpids.addElement(tcr.getBodyPartID());
+ return false;
+ } else {
+ CertificationRequest creq = tcr.getCertificationRequest();
+ CertificationRequestInfo cinfo = creq.getInfo();
+ SET attrs = cinfo.getAttributes();
+ for (int j=0; j<attrs.size(); j++) {
+ Attribute pkcs10Attr = (Attribute)attrs.elementAt(j);
+ if (pkcs10Attr.getType().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
+ SET witnessVal = pkcs10Attr.getValues();
+ if (witnessVal.size() > 0) {
+ try {
+ OCTET_STRING str =
+ (OCTET_STRING)(ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(witnessVal.elementAt(0))));
+ bv = str.toByteArray();
+ return verifyDigest(sharedSecret.getBytes(),
+ randomSeed, bv);
+ } catch (InvalidBERException ex) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+ } else if (req.getType().equals(TaggedRequest.CRMF)) {
+ CertReqMsg crm = req.getCrm();
+ CertRequest certReq = crm.getCertReq();
+ reqId = certReq.getCertReqId();
+ if (!sharedSecretFound) {
+ bpids.addElement(reqId);
+ return false;
+ } else {
+ for (int i = 0; i < certReq.numControls(); i++) {
+ AVA ava = certReq.controlAt(i);
+
+ if (ava.getOID().equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness)) {
+ ASN1Value value = ava.getValue();
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ ASN1Util.encode(value));
+ OCTET_STRING ostr = null;
+ try {
+ ostr = (OCTET_STRING)
+ (new OCTET_STRING.Template()).decode(bis);
+ bv = ostr.toByteArray();
+ } catch (Exception e) {
+ bpids.addElement(reqId);
+ return false;
+ }
+
+ boolean valid = verifyDigest(sharedSecret.getBytes(),
+ randomSeed, bv);
+ if (!valid) {
+ bpids.addElement(reqId);
+ return valid;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private boolean verifyDigest(byte[] sharedSecret, byte[] text, byte[] bv) {
+ byte[] key = null;
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ key = SHA1Digest.digest(sharedSecret);
+ } catch (NoSuchAlgorithmException ex) {
+ CMS.debug("EnrollProfile: No such algorithm for this message digest.");
+ return false;
+ }
+
+ byte[] finalDigest = null;
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key);
+ hmacDigest.update(text);
+ finalDigest = hmacDigest.digest();
+ } catch (NoSuchAlgorithmException ex) {
+ CMS.debug("EnrollProfile: No such algorithm for this message digest.");
+ return false;
+ }
+
+ if (finalDigest.length != bv.length) {
+ CMS.debug("EnrollProfile: The length of two HMAC digest are not the same.");
+ return false;
+ }
+
+ for (int j=0; j<bv.length; j++) {
+ if (bv[j] != finalDigest[j]) {
+ CMS.debug("EnrollProfile: The content of two HMAC digest are not the same.");
+ return false;
+ }
+ }
+
+ CMS.debug("EnrollProfile: The content of two HMAC digest are the same.");
+ return true;
+ }
+
+ private SEQUENCE getRequestBpids(SEQUENCE reqSeq) {
+ SEQUENCE bpids = new SEQUENCE();
+ for (int i = 0; i < reqSeq.size(); i++) {
+ TaggedRequest req = (TaggedRequest) reqSeq.elementAt(i);
+ if (req.getType().equals(TaggedRequest.PKCS10)) {
+ TaggedCertificationRequest tcr = req.getTcr();
+ bpids.addElement(tcr.getBodyPartID());
+ } else if (req.getType().equals(TaggedRequest.CRMF)) {
+ CertReqMsg crm = req.getCrm();
+ CertRequest request = crm.getCertReq();
+ bpids.addElement(request.getCertReqId());
+ }
+ }
+
+ return bpids;
+ }
+
+ private boolean verifyIdentityProof(TaggedAttribute attr, SEQUENCE reqSeq) {
+ SET vals = attr.getValues();
+ if (vals.size() < 1)
+ return false;
+ String name = null;
+ try {
+ name = CMS.getConfigStore().getString("cmc.sharedSecret.class");
+ } catch (EPropertyNotFound e) {
+ } catch (EBaseException e) {
+ }
+
+ if (name == null)
+ return false;
+ else {
+ ISharedToken tokenClass = null;
+ try {
+ tokenClass = (ISharedToken)Class.forName(name).newInstance();
+ } catch (ClassNotFoundException e) {
+ CMS.debug("EnrollProfile: Failed to find class name: "+name);
+ return false;
+ } catch (InstantiationException e) {
+ CMS.debug("EnrollProfile: Failed to instantiate class: "+name);
+ return false;
+ } catch (IllegalAccessException e) {
+ CMS.debug("EnrollProfile: Illegal access: "+name);
+ return false;
+ }
+
+ String token = tokenClass.getSharedToken(mCMCData);
+ OCTET_STRING ostr = null;
+ try {
+ ostr = (OCTET_STRING)(ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ } catch (InvalidBERException e) {
+ CMS.debug("EnrollProfile: Failed to decode the byte value.");
+ return false;
+ }
+ byte[] b = ostr.toByteArray();
+ byte[] text = ASN1Util.encode(reqSeq);
+
+ return verifyDigest(token.getBytes(), text, b);
+ }
+ }
+
+ public void fillTaggedRequest(Locale locale, TaggedRequest tagreq, X509CertInfo info,
+ IRequest req)
+ throws EProfileException {
+ TaggedRequest.Type type = tagreq.getType();
+
+ if (type.equals(TaggedRequest.PKCS10)) {
+ try {
+ TaggedCertificationRequest tcr = tagreq.getTcr();
+ CertificationRequest p10 = tcr.getCertificationRequest();
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ p10.encode(ostream);
+ PKCS10 pkcs10 = new PKCS10(ostream.toByteArray());
+
+ req.setExtData("bodyPartId", tcr.getBodyPartID());
+ fillPKCS10(locale, pkcs10, info, req);
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: fillTaggedRequest " +
+ e.toString());
+ }
+ } else if (type.equals(TaggedRequest.CRMF)) {
+ CertReqMsg crm = tagreq.getCrm();
+ SessionContext context = SessionContext.getContext();
+ Integer nums = (Integer)(context.get("numOfControls"));
+
+ // check if the LRA POP Witness Control attribute exists
+ if (nums != null && nums.intValue() > 0) {
+ TaggedAttribute attr =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness));
+ if (attr != null) {
+ parseLRAPopWitness(locale, crm, attr);
+ } else {
+ CMS.debug("EnrollProfile: verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ verifyPOP(locale, crm);
+ }
+ } else {
+ CMS.debug("EnrollProfile: verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ verifyPOP(locale, crm);
+ }
+
+ fillCertReqMsg(locale, crm, info, req);
+ } else {
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+ private void parseLRAPopWitness(Locale locale, CertReqMsg crm,
+ TaggedAttribute attr) throws EProfileException {
+ SET vals = attr.getValues();
+ boolean donePOP = false;
+ INTEGER reqId = null;
+ if (vals.size() > 0) {
+ LraPopWitness lraPop = null;
+ try {
+ lraPop = (LraPopWitness)(ASN1Util.decode(LraPopWitness.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ } catch (InvalidBERException e) {
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENCODING_ERROR"));
+ }
+
+ SEQUENCE bodyIds = lraPop.getBodyIds();
+ reqId = crm.getCertReq().getCertReqId();
+
+ for (int i=0; i<bodyIds.size(); i++) {
+ INTEGER num = (INTEGER)(bodyIds.elementAt(i));
+ if (num.toString().equals(reqId.toString())) {
+ donePOP = true;
+ CMS.debug("EnrollProfile: skip POP for request: "+reqId.toString()+ " because LRA POP Witness control is found.");
+ break;
+ }
+ }
+ }
+
+ if (!donePOP) {
+ CMS.debug("EnrollProfile: not skip POP for request: "+reqId.toString()+" because this request id is not part of the body list in LRA Pop witness control.");
+ verifyPOP(locale, crm);
+ }
+ }
+
+ public CertReqMsg[] parseCRMF(Locale locale, String certreq)
+ throws EProfileException {
+
+ /* cert request must not be null */
+ if (certreq == null) {
+ CMS.debug("EnrollProfile: parseCRMF() certreq null");
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ CMS.debug("EnrollProfile: Start parseCRMF(): " + certreq);
+
+ CertReqMsg msgs[] = null;
+ String creq = normalizeCertReq(certreq);
+ try {
+ byte data[] = CMS.AtoB(creq);
+ ByteArrayInputStream crmfBlobIn =
+ new ByteArrayInputStream(data);
+ SEQUENCE crmfMsgs = (SEQUENCE)
+ new SEQUENCE.OF_Template(new
+ CertReqMsg.Template()).decode(crmfBlobIn);
+ int nummsgs = crmfMsgs.size();
+
+ if (nummsgs <= 0)
+ return null;
+ msgs = new CertReqMsg[crmfMsgs.size()];
+ for (int i = 0; i < nummsgs; i++) {
+ msgs[i] = (CertReqMsg) crmfMsgs.elementAt(i);
+ }
+ return msgs;
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: parseCRMF " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+ private static final OBJECT_IDENTIFIER PKIARCHIVEOPTIONS_OID =
+ new OBJECT_IDENTIFIER(new long[] {1, 3, 6, 1, 5, 5, 7, 5, 1, 4}
+ );
+
+ protected PKIArchiveOptions getPKIArchiveOptions(AVA ava) {
+ ASN1Value archVal = ava.getValue();
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ ASN1Util.encode(archVal));
+ PKIArchiveOptions archOpts = null;
+
+ try {
+ archOpts = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(bis);
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: getPKIArchiveOptions " + e.toString());
+ }
+ return archOpts;
+ }
+
+ public PKIArchiveOptions toPKIArchiveOptions(byte options[]) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(options);
+ PKIArchiveOptions archOpts = null;
+
+ try {
+ archOpts = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(bis);
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: toPKIArchiveOptions " + e.toString());
+ }
+ return archOpts;
+ }
+
+ public byte[] toByteArray(PKIArchiveOptions options) {
+ return ASN1Util.encode(options);
+ }
+
+ public void fillCertReqMsg(Locale locale, CertReqMsg certReqMsg, X509CertInfo info,
+ IRequest req)
+ throws EProfileException {
+ try {
+ CMS.debug("Start parseCertReqMsg ");
+ CertRequest certReq = certReqMsg.getCertReq();
+ req.setExtData("bodyPartId", certReq.getCertReqId());
+ // handle PKIArchiveOption (key archival)
+ for (int i = 0; i < certReq.numControls(); i++) {
+ AVA ava = certReq.controlAt(i);
+
+ if (ava.getOID().equals(PKIARCHIVEOPTIONS_OID)) {
+ PKIArchiveOptions opt = getPKIArchiveOptions(ava);
+
+ //req.set(REQUEST_ARCHIVE_OPTIONS, opt);
+ req.setExtData(REQUEST_ARCHIVE_OPTIONS,
+ toByteArray(opt));
+ }
+ }
+
+ CertTemplate certTemplate = certReq.getCertTemplate();
+
+ // parse key
+ SubjectPublicKeyInfo spki = certTemplate.getPublicKey();
+ ByteArrayOutputStream keyout = new ByteArrayOutputStream();
+
+ spki.encode(keyout);
+ byte[] keybytes = keyout.toByteArray();
+ X509Key key = new X509Key();
+
+ key.decode(keybytes);
+
+ // XXX - kmccarth - this may simply undo the decoding above
+ // but for now it's unclear whether X509Key
+ // changest the format when decoding.
+ CertificateX509Key certKey = new CertificateX509Key(key);
+ ByteArrayOutputStream certKeyOut = new ByteArrayOutputStream();
+ certKey.encode(certKeyOut);
+ req.setExtData(REQUEST_KEY, certKeyOut.toByteArray());
+
+ // parse validity
+ if (certTemplate.getNotBefore() != null ||
+ certTemplate.getNotAfter() != null) {
+ CMS.debug("EnrollProfile: requested notBefore: " + certTemplate.getNotBefore());
+ CMS.debug("EnrollProfile: requested notAfter: " + certTemplate.getNotAfter());
+ CMS.debug("EnrollProfile: current CA time: " + new Date());
+ CertificateValidity certValidity = new CertificateValidity(
+ certTemplate.getNotBefore(), certTemplate.getNotAfter());
+ ByteArrayOutputStream certValidityOut =
+ new ByteArrayOutputStream();
+ certValidity.encode(certValidityOut);
+ req.setExtData(REQUEST_VALIDITY, certValidityOut.toByteArray());
+ } else {
+ CMS.debug("EnrollProfile: validity not supplied");
+ }
+
+ // parse subject
+ if (certTemplate.hasSubject()) {
+ Name subjectdn = certTemplate.getSubject();
+ ByteArrayOutputStream subjectEncStream =
+ new ByteArrayOutputStream();
+
+ subjectdn.encode(subjectEncStream);
+ byte[] subjectEnc = subjectEncStream.toByteArray();
+ X500Name subject = new X500Name(subjectEnc);
+
+ //info.set(X509CertInfo.SUBJECT,
+ // new CertificateSubjectName(subject));
+
+ req.setExtData(REQUEST_SUBJECT_NAME,
+ new CertificateSubjectName(subject));
+ try {
+ String subjectCN = subject.getCommonName();
+ if (subjectCN == null) subjectCN = "";
+ req.setExtData(REQUEST_SUBJECT_NAME+".cn", subjectCN);
+ } catch (Exception ee) {
+ req.setExtData(REQUEST_SUBJECT_NAME+".cn", "");
+ }
+ try {
+ String subjectUID = subject.getUserID();
+ if (subjectUID == null) subjectUID = "";
+ req.setExtData(REQUEST_SUBJECT_NAME+".uid", subjectUID);
+ } catch (Exception ee) {
+ req.setExtData(REQUEST_SUBJECT_NAME+".uid", "");
+ }
+ }
+
+ // parse extensions
+ CertificateExtensions extensions = null;
+
+ // try {
+ extensions = req.getExtDataInCertExts(REQUEST_EXTENSIONS);
+ // } catch (CertificateException e) {
+ // extensions = null;
+ // } catch (IOException e) {
+ // extensions = null;
+ // }
+ if (certTemplate.hasExtensions()) {
+ // put each extension from CRMF into CertInfo.
+ // index by extension name, consistent with
+ // CertificateExtensions.parseExtension() method.
+ if (extensions == null)
+ extensions = new CertificateExtensions();
+ int numexts = certTemplate.numExtensions();
+
+ for (int j = 0; j < numexts; j++) {
+ org.mozilla.jss.pkix.cert.Extension jssext =
+ certTemplate.extensionAt(j);
+ boolean isCritical = jssext.getCritical();
+ org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssoid =
+ jssext.getExtnId();
+ long[] numbers = jssoid.getNumbers();
+ int[] oidNumbers = new int[numbers.length];
+
+ for (int k = numbers.length - 1; k >= 0; k--) {
+ oidNumbers[k] = (int) numbers[k];
+ }
+ ObjectIdentifier oid =
+ new ObjectIdentifier(oidNumbers);
+ org.mozilla.jss.asn1.OCTET_STRING jssvalue =
+ jssext.getExtnValue();
+ ByteArrayOutputStream jssvalueout =
+ new ByteArrayOutputStream();
+
+ jssvalue.encode(jssvalueout);
+ byte[] extValue = jssvalueout.toByteArray();
+
+ Extension ext =
+ new Extension(oid, isCritical, extValue);
+
+ extensions.parseExtension(ext);
+ }
+ // info.set(X509CertInfo.EXTENSIONS, extensions);
+ req.setExtData(REQUEST_EXTENSIONS, extensions);
+
+ }
+ } catch (IOException e) {
+ CMS.debug("EnrollProfile: fillCertReqMsg " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ } catch (InvalidKeyException e) {
+ CMS.debug("EnrollProfile: fillCertReqMsg " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ // } catch (CertificateException e) {
+ // CMS.debug("EnrollProfile: fillCertReqMsg " + e.toString());
+ // throw new EProfileException(e.toString());
+ }
+ }
+
+ public PKCS10 parsePKCS10(Locale locale, String certreq)
+ throws EProfileException {
+ /* cert request must not be null */
+ if (certreq == null) {
+ CMS.debug("EnrollProfile:parsePKCS10() certreq null");
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ CMS.debug("Start parsePKCS10(): " + certreq);
+
+ // trim header and footer
+ String creq = normalizeCertReq(certreq);
+
+ // parse certificate into object
+ byte data[] = CMS.AtoB(creq);
+ PKCS10 pkcs10 = null;
+ CryptoManager cm = null;
+ CryptoToken savedToken = null;
+ boolean sigver = true;
+
+ try {
+ cm = CryptoManager.getInstance();
+ sigver = CMS.getConfigStore().getBoolean("ca.requestVerify.enabled", true);
+ if (sigver) {
+ CMS.debug("EnrollProfile: parsePKCS10: signature verification enabled");
+ String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
+ "Internal Key Storage Token");
+ savedToken = cm.getThreadToken();
+ CryptoToken signToken = cm.getTokenByName(tokenName);
+ CMS.debug("EnrollProfile: parsePKCS10 setting thread token");
+ cm.setThreadToken(signToken);
+ pkcs10 = new PKCS10(data);
+ } else {
+ CMS.debug("EnrollProfile: parsePKCS10: signature verification disabled");
+ pkcs10 = new PKCS10(data, sigver);
+ }
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: parsePKCS10 " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ } finally {
+ if (sigver) {
+ CMS.debug("EnrollProfile: parsePKCS10 restoring thread token");
+ cm.setThreadToken(savedToken);
+ }
+ }
+
+ return pkcs10;
+ }
+
+ public void fillPKCS10(Locale locale, PKCS10 pkcs10, X509CertInfo info, IRequest req)
+ throws EProfileException {
+ X509Key key = pkcs10.getSubjectPublicKeyInfo();
+
+ try {
+ CertificateX509Key certKey = new CertificateX509Key(key);
+ ByteArrayOutputStream certKeyOut = new ByteArrayOutputStream();
+ certKey.encode(certKeyOut);
+ req.setExtData(IEnrollProfile.REQUEST_KEY, certKeyOut.toByteArray());
+
+ req.setExtData(EnrollProfile.REQUEST_SUBJECT_NAME,
+ new CertificateSubjectName(pkcs10.getSubjectName()));
+ try {
+ String subjectCN = pkcs10.getSubjectName().getCommonName();
+ if (subjectCN == null) subjectCN = "";
+ req.setExtData(REQUEST_SUBJECT_NAME+".cn", subjectCN);
+ } catch (Exception ee) {
+ req.setExtData(REQUEST_SUBJECT_NAME+".cn", "");
+ }
+ try {
+ String subjectUID = pkcs10.getSubjectName().getUserID();
+ if (subjectUID == null) subjectUID = "";
+ req.setExtData(REQUEST_SUBJECT_NAME+".uid", subjectUID);
+ } catch (Exception ee) {
+ req.setExtData(REQUEST_SUBJECT_NAME+".uid", "");
+ }
+
+ info.set(X509CertInfo.KEY, certKey);
+
+ PKCS10Attributes p10Attrs = pkcs10.getAttributes();
+ if (p10Attrs != null) {
+ PKCS10Attribute p10Attr = (PKCS10Attribute)
+ (p10Attrs.getAttribute(CertificateExtensions.NAME));
+ if (p10Attr != null && p10Attr.getAttributeId().equals(
+ PKCS9Attribute.EXTENSION_REQUEST_OID)) { CMS.debug("Found PKCS10 extension");
+ Extensions exts0 = (Extensions)
+ (p10Attr.getAttributeValue());
+ DerOutputStream extOut = new DerOutputStream();
+
+ exts0.encode(extOut);
+ byte[] extB = extOut.toByteArray();
+ DerInputStream extIn = new DerInputStream(extB);
+ CertificateExtensions exts = new CertificateExtensions(extIn);
+ if (exts != null) {
+ CMS.debug("Set extensions " + exts);
+ // info.set(X509CertInfo.EXTENSIONS, exts);
+ req.setExtData(REQUEST_EXTENSIONS, exts);
+ }
+ } else {
+ CMS.debug("PKCS10 extension Not Found");
+ }
+ }
+
+ CMS.debug("Finish parsePKCS10 - " + pkcs10.getSubjectName());
+ } catch (IOException e) {
+ CMS.debug("EnrollProfile: fillPKCS10 " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ } catch (CertificateException e) {
+ CMS.debug("EnrollProfile: fillPKCS10 " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+
+ // for netkey
+ public void fillNSNKEY(Locale locale, String sn, String skey, X509CertInfo info, IRequest req)
+ throws EProfileException {
+
+ try {
+ //cfu - is the algorithm going to be replaced by the policy?
+ X509Key key = new X509Key();
+ key.decode(CMS.AtoB(skey));
+
+ info.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ // req.set(EnrollProfile.REQUEST_SUBJECT_NAME,
+ // new CertificateSubjectName(new
+ // X500Name("CN="+sn)));
+ req.setExtData("screenname", sn);
+ // keeping "aoluid" to be backward compatible
+ req.setExtData("aoluid", sn);
+ req.setExtData("uid", sn);
+ CMS.debug("EnrollPrifile: fillNSNKEY(): uid="+sn);
+
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: fillNSNKEY(): "+e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+ // for house key
+ public void fillNSHKEY(Locale locale, String tcuid, String skey, X509CertInfo info, IRequest req)
+ throws EProfileException {
+
+ try {
+ //cfu - is the algorithm going to be replaced by the policy?
+ X509Key key = new X509Key();
+ key.decode(CMS.AtoB(skey));
+
+ info.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ // req.set(EnrollProfile.REQUEST_SUBJECT_NAME,
+ // new CertificateSubjectName(new
+ // X500Name("CN="+sn)));
+ req.setExtData("tokencuid", tcuid);
+
+ CMS.debug("EnrollPrifile: fillNSNKEY(): tokencuid="+tcuid);
+
+ } catch (Exception e) {
+ CMS.debug("EnrollProfile: fillNSHKEY(): "+e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+
+ public DerInputStream parseKeyGen(Locale locale, String certreq)
+ throws EProfileException {
+ byte data[] = CMS.AtoB(certreq);
+
+ DerInputStream derIn = new DerInputStream(data);
+
+ return derIn;
+ }
+
+ public void fillKeyGen(Locale locale, DerInputStream derIn, X509CertInfo info, IRequest req
+ )
+ throws EProfileException {
+ try {
+
+ /* get SPKAC Algorithm & Signature */
+ DerValue derSPKACContent[] = derIn.getSequence(3);
+ AlgorithmId mAlgId = AlgorithmId.parse(derSPKACContent[1]);
+ byte mSignature[] = derSPKACContent[2].getBitString();
+
+ /* get PKAC SPKI & Challenge */
+ byte mPKAC[] = derSPKACContent[0].toByteArray();
+
+ derIn = new DerInputStream(mPKAC);
+ DerValue derPKACContent[] = derIn.getSequence(2);
+
+ DerValue mDerSPKI = derPKACContent[0];
+ X509Key mSPKI = X509Key.parse(derPKACContent[0]);
+
+ String mChallenge;
+ DerValue mDerChallenge = derPKACContent[1];
+
+ if (mDerChallenge.length() != 0)
+ mChallenge = derPKACContent[1].getIA5String();
+
+ CertificateX509Key certKey = new CertificateX509Key(mSPKI);
+ ByteArrayOutputStream certKeyOut = new ByteArrayOutputStream();
+ certKey.encode(certKeyOut);
+ req.setExtData(IEnrollProfile.REQUEST_KEY, certKeyOut.toByteArray());
+ info.set(X509CertInfo.KEY, certKey);
+ } catch (IOException e) {
+ CMS.debug("EnrollProfile: fillKeyGen " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ } catch (CertificateException e) {
+ CMS.debug("EnrollProfile: fillKeyGen " + e.toString());
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
+ }
+ }
+
+ public String normalizeCertReq(String s) {
+ if (s == null) {
+ return s;
+ }
+ s = s.replaceAll("-----BEGIN CERTIFICATE REQUEST-----", "");
+ s = s.replaceAll("-----BEGIN NEW CERTIFICATE REQUEST-----", "");
+ s = s.replaceAll("-----END CERTIFICATE REQUEST-----", "");
+ s = s.replaceAll("-----END NEW CERTIFICATE REQUEST-----", "");
+
+ StringBuffer sb = new StringBuffer();
+ StringTokenizer st = new StringTokenizer(s, "\r\n ");
+
+ while (st.hasMoreTokens()) {
+ String nextLine = st.nextToken();
+
+ nextLine = nextLine.trim();
+ if (nextLine.equals("-----BEGIN CERTIFICATE REQUEST-----"))
+ continue;
+ if (nextLine.equals("-----BEGIN NEW CERTIFICATE REQUEST-----"))
+ continue;
+ if (nextLine.equals("-----END CERTIFICATE REQUEST-----"))
+ continue;
+ if (nextLine.equals("-----END NEW CERTIFICATE REQUEST-----"))
+ continue;
+ sb.append(nextLine);
+ }
+ return sb.toString();
+ }
+
+ public Locale getLocale(IRequest request) {
+ Locale locale = null;
+ String language = request.getExtDataInString(
+ EnrollProfile.REQUEST_LOCALE);
+ if (language != null) {
+ locale = new Locale(language);
+ }
+ return locale;
+ }
+
+ /**
+ * Populate input
+ * <P>
+ *
+ * (either all "agent" profile cert requests NOT made through a connector,
+ * or all "EE" profile cert requests NOT made through a connector)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST used when a
+ * profile cert request is made (before approval process)
+ * </ul>
+ * @param ctx profile context
+ * @param request the certificate request
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ public void populateInput(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ super.populateInput(ctx, request);
+ }
+
+ public void populate(IRequest request)
+ throws EProfileException {
+ super.populate(request);
+
+ }
+
+ /**
+ * Passes the request to the set of constraint policies
+ * that validate the request against the profile.
+ */
+ public void validate(IRequest request)
+ throws ERejectException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(request);
+ String auditProfileID = auditProfileID();
+ String auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String subject = null;
+
+ // try {
+ X509CertInfo info = request.getExtDataInCertInfo(REQUEST_CERTINFO);
+
+ try {
+ CertificateSubjectName sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+
+ // if the cert subject name is NOT MISSING, retrieve the
+ // actual "auditCertificateSubjectName" and "normalize" it
+ if (sn != null) {
+ subject = sn.toString();
+ if (subject != null) {
+ // NOTE: This is ok even if the cert subject name
+ // is "" (empty)!
+ auditCertificateSubjectName = subject.trim();
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditProfileID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } catch (CertificateException e) {
+ CMS.debug("EnrollProfile: populate " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditProfileID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } catch (IOException e) {
+ CMS.debug("EnrollProfile: populate " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditProfileID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ }
+
+ super.validate(request);
+ Object key = null;
+
+ try {
+ key = info.get(X509CertInfo.KEY);
+ } catch (CertificateException e) {
+ } catch (IOException e) {
+ }
+
+ if (key == null) {
+ Locale locale = getLocale(request);
+
+ throw new ERejectException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_EMPTY_KEY"));
+ }
+
+ try {
+ CMS.debug("EnrollProfile certInfo : " + info);
+ } catch (NullPointerException e) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is inherited by all extended "EnrollProfile"s,
+ * and is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ protected String auditRequesterID(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = ILogger.UNIDENTIFIED;
+
+ if (request != null) {
+ // overwrite "requesterID" if and only if "id" != null
+ String id = request.getRequestId().toString();
+
+ if (id != null) {
+ requesterID = id.trim();
+ }
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Profile ID
+ *
+ * This method is inherited by all extended "EnrollProfile"s,
+ * and is called to obtain the "ProfileID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message ProfileID
+ */
+ protected String auditProfileID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String profileID = getId();
+
+ if (profileID != null) {
+ profileID = profileID.trim();
+ } else {
+ profileID = ILogger.UNIDENTIFIED;
+ }
+
+ return profileID;
+ }
+
+ public void verifyPOP(Locale locale, CertReqMsg certReqMsg)
+ throws EProfileException {
+ CMS.debug("EnrollProfile ::in verifyPOP");
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ if (!certReqMsg.hasPop()) {
+ return;
+ }
+ ProofOfPossession pop = certReqMsg.getPop();
+ ProofOfPossession.Type popType = pop.getType();
+
+ if (popType != ProofOfPossession.SIGNATURE) {
+ return;
+ }
+
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
+ "Internal Key Storage Token");
+ CryptoToken verifyToken = cm.getTokenByName(tokenName);
+ if (tokenName.equals("Internal Key Storage Token")) {
+ //use internal token
+ CMS.debug("POP verification using internal token");
+ certReqMsg.verify();
+ } else {
+ CMS.debug("POP verification using token:"+ tokenName);
+ certReqMsg.verify(verifyToken);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.SUCCESS );
+ audit( auditMessage );
+ } catch (Exception e) {
+
+ CMS.debug("Failed POP verify! "+e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new EProfileException(CMS.getUserMessage(locale,
+ "CMS_POP_VERIFICATION_ERROR"));
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java b/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java
new file mode 100644
index 000000000..dd994e83a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java
@@ -0,0 +1,36 @@
+// --- 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.common;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.profile.*;
+
+
+/**
+ * This class implements an enrollment profile context
+ * that carries information for request creation.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EnrollProfileContext extends ProfileContext
+ implements IProfileContext {
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/ProfileContext.java b/pki/base/common/src/com/netscape/cms/profile/common/ProfileContext.java
new file mode 100644
index 000000000..12bbaa783
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/ProfileContext.java
@@ -0,0 +1,41 @@
+// --- 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.common;
+
+
+import java.util.*;
+
+import com.netscape.certsrv.profile.*;
+
+
+/**
+ * This class implements the profile context.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileContext implements IProfileContext {
+ private Hashtable m_Attrs = new Hashtable();
+
+ public void set(String name, String value) {
+ m_Attrs.put(name, value);
+ }
+
+ public String get(String name) {
+ return (String) m_Attrs.get(name);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java b/pki/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java
new file mode 100644
index 000000000..bf9594fa7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java
@@ -0,0 +1,53 @@
+// --- 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.common;
+
+
+import com.netscape.certsrv.profile.*;
+
+
+/**
+ * This class implements a profile policy that
+ * contains a default policy and a constraint
+ * policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfilePolicy implements IProfilePolicy {
+ private String mId = null;
+ private IPolicyDefault mDefault = null;
+ private IPolicyConstraint mConstraint = null;
+
+ public ProfilePolicy(String id, IPolicyDefault def, IPolicyConstraint constraint) {
+ mId = id;
+ mDefault = def;
+ mConstraint = constraint;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public IPolicyDefault getDefault() {
+ return mDefault;
+ }
+
+ public IPolicyConstraint getConstraint() {
+ return mConstraint;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java
new file mode 100644
index 000000000..cd980c5c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java
@@ -0,0 +1,138 @@
+// --- 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.common;
+
+
+import java.security.cert.*;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+/**
+ * This class implements a Registration Manager
+ * enrollment profile.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RAEnrollProfile extends EnrollProfile {
+
+ public RAEnrollProfile() {
+ super();
+ }
+
+ public IAuthority getAuthority() {
+ IAuthority authority = (IAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ if (authority == null)
+ return null;
+ return authority;
+ }
+
+ public X500Name getIssuerName() {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+ X500Name issuerName = ra.getX500Name();
+
+ return issuerName;
+ }
+
+ public void execute(IRequest request)
+ throws EProfileException {
+
+
+ if (!isEnable()) {
+ CMS.debug("CAEnrollProfile: Profile Not Enabled");
+ throw new EProfileException("Profile Not Enabled");
+ }
+
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority) getAuthority();
+ IRAService raService = (IRAService) ra.getRAService();
+
+ if (raService == null) {
+ throw new EProfileException("No RA Service");
+ }
+
+
+ IRequestQueue queue = ra.getRequestQueue();
+
+ // send request to CA
+ try {
+ IConnector caConnector = raService.getCAConnector();
+
+ if (caConnector == null) {
+ CMS.debug("RAEnrollProfile: CA connector not configured");
+ } else {
+ caConnector.send(request);
+ // check response
+ if (!request.isSuccess()) {
+ CMS.debug("RAEnrollProfile error talking to CA setting req status to SVC_PENDING");
+
+ request.setRequestStatus(RequestStatus.SVC_PENDING);
+
+ try {
+ queue.updateRequest(request);
+ } catch (EBaseException e) {
+ CMS.debug("RAEnrollProfile: Update request " + e.toString());
+ }
+ throw new ERejectException(
+ request.getError(getLocale(request)));
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("RAEnrollProfile: " + e.toString());
+ throw new EProfileException(e.toString());
+ }
+
+ // request handling
+ Enumeration names = ra.getRequestListenerNames();
+
+ if (names != null) {
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ CMS.debug("CAEnrollProfile: listener " + name);
+ IRequestListener listener = ra.getRequestListener(name);
+
+ if (listener != null) {
+ listener.accept(request);
+ }
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java
new file mode 100644
index 000000000..c83f05746
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java
@@ -0,0 +1,135 @@
+// --- 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.common;
+
+
+import java.security.cert.*;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+/**
+ * This class implements a Certificate Manager enrollment
+ * profile for Server Certificates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ServerCertCAEnrollProfile extends CAEnrollProfile
+ implements IProfileEx {
+
+ /**
+ * Called after initialization. It populates default
+ * policies, inputs, and outputs.
+ */
+ public void populate() throws EBaseException
+ {
+ // create inputs
+ NameValuePairs inputParams1 = new NameValuePairs();
+ IProfileInput input1 =
+ createProfileInput("i1", "certReqInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ IProfileInput input2 =
+ createProfileInput("i2", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ IProfileOutput output1 =
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ IProfilePolicy policy1 =
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def1 = policy1.getDefault();
+ IConfigStore defConfig1 = def1.getConfigStore();
+ IPolicyConstraint con1 = policy1.getConstraint();
+ IConfigStore conConfig1 = con1.getConfigStore();
+
+ IProfilePolicy policy2 =
+ createProfilePolicy("set1", "p2",
+ "validityDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def2 = policy2.getDefault();
+ IConfigStore defConfig2 = def2.getConfigStore();
+ defConfig2.putString("params.range","180");
+ defConfig2.putString("params.startTime","0");
+ IPolicyConstraint con2 = policy2.getConstraint();
+ IConfigStore conConfig2 = con2.getConfigStore();
+
+ IProfilePolicy policy3 =
+ createProfilePolicy("set1", "p3",
+ "userKeyDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def3 = policy3.getDefault();
+ IConfigStore defConfig3 = def3.getConfigStore();
+ defConfig3.putString("params.keyType","RSA");
+ defConfig3.putString("params.keyMinLength","512");
+ defConfig3.putString("params.keyMaxLength","4096");
+ IPolicyConstraint con3 = policy3.getConstraint();
+ IConfigStore conConfig3 = con3.getConfigStore();
+
+ IProfilePolicy policy4 =
+ createProfilePolicy("set1", "p4",
+ "signingAlgDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def4 = policy4.getDefault();
+ IConfigStore defConfig4 = def4.getConfigStore();
+ defConfig4.putString("params.signingAlg","-");
+ defConfig4.putString("params.signingAlgsAllowed",
+ "SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC");
+ IPolicyConstraint con4 = policy4.getConstraint();
+ IConfigStore conConfig4 = con4.getConfigStore();
+
+ IProfilePolicy policy5 =
+ createProfilePolicy("set1", "p5",
+ "keyUsageExtDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def5 = policy5.getDefault();
+ IConfigStore defConfig5 = def5.getConfigStore();
+ defConfig5.putString("params.keyUsageCritical","true");
+ defConfig5.putString("params.keyUsageCrlSign","false");
+ defConfig5.putString("params.keyUsageDataEncipherment","true");
+ defConfig5.putString("params.keyUsageDecipherOnly","false");
+ defConfig5.putString("params.keyUsageDigitalSignature","true");
+ defConfig5.putString("params.keyUsageEncipherOnly","false");
+ defConfig5.putString("params.keyUsageKeyAgreement","false");
+ defConfig5.putString("params.keyUsageKeyCertSign","false");
+ defConfig5.putString("params.keyUsageKeyEncipherment","true");
+ defConfig5.putString("params.keyUsageNonRepudiation","true");
+ IPolicyConstraint con5 = policy5.getConstraint();
+ IConfigStore conConfig5 = con5.getConfigStore();
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java
new file mode 100644
index 000000000..a6acf111e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java
@@ -0,0 +1,137 @@
+// --- 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.common;
+
+
+import java.security.cert.*;
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import java.security.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+/**
+ * This class implements a Certificate Manager enrollment
+ * profile for User Certificates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserCertCAEnrollProfile extends CAEnrollProfile
+ implements IProfileEx {
+
+ /**
+ * Called after initialization. It populates default
+ * policies, inputs, and outputs.
+ */
+ public void populate() throws EBaseException
+ {
+ // create inputs
+ NameValuePairs inputParams1 = new NameValuePairs();
+ IProfileInput input1 =
+ createProfileInput("i1", "keyGenInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ IProfileInput input2 =
+ createProfileInput("i2", "subjectNameInputImpl", inputParams2);
+ NameValuePairs inputParams3 = new NameValuePairs();
+ IProfileInput input3 =
+ createProfileInput("i3", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ IProfileOutput output1 =
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ // create policies
+ IProfilePolicy policy1 =
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def1 = policy1.getDefault();
+ IConfigStore defConfig1 = def1.getConfigStore();
+ IPolicyConstraint con1 = policy1.getConstraint();
+ IConfigStore conConfig1 = con1.getConfigStore();
+
+ IProfilePolicy policy2 =
+ createProfilePolicy("set1", "p2",
+ "validityDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def2 = policy2.getDefault();
+ IConfigStore defConfig2 = def2.getConfigStore();
+ defConfig2.putString("params.range","180");
+ defConfig2.putString("params.startTime","0");
+ IPolicyConstraint con2 = policy2.getConstraint();
+ IConfigStore conConfig2 = con2.getConfigStore();
+
+ IProfilePolicy policy3 =
+ createProfilePolicy("set1", "p3",
+ "userKeyDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def3 = policy3.getDefault();
+ IConfigStore defConfig3 = def3.getConfigStore();
+ defConfig3.putString("params.keyType","RSA");
+ defConfig3.putString("params.keyMinLength","512");
+ defConfig3.putString("params.keyMaxLength","4096");
+ IPolicyConstraint con3 = policy3.getConstraint();
+ IConfigStore conConfig3 = con3.getConfigStore();
+
+ IProfilePolicy policy4 =
+ createProfilePolicy("set1", "p4",
+ "signingAlgDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def4 = policy4.getDefault();
+ IConfigStore defConfig4 = def4.getConfigStore();
+ defConfig4.putString("params.signingAlg","-");
+ defConfig4.putString("params.signingAlgsAllowed",
+ "SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC");
+ IPolicyConstraint con4 = policy4.getConstraint();
+ IConfigStore conConfig4 = con4.getConfigStore();
+
+ IProfilePolicy policy5 =
+ createProfilePolicy("set1", "p5",
+ "keyUsageExtDefaultImpl", "noConstraintImpl");
+ IPolicyDefault def5 = policy5.getDefault();
+ IConfigStore defConfig5 = def5.getConfigStore();
+ defConfig5.putString("params.keyUsageCritical","true");
+ defConfig5.putString("params.keyUsageCrlSign","false");
+ defConfig5.putString("params.keyUsageDataEncipherment","false");
+ defConfig5.putString("params.keyUsageDecipherOnly","false");
+ defConfig5.putString("params.keyUsageDigitalSignature","true");
+ defConfig5.putString("params.keyUsageEncipherOnly","false");
+ defConfig5.putString("params.keyUsageKeyAgreement","false");
+ defConfig5.putString("params.keyUsageKeyCertSign","false");
+ defConfig5.putString("params.keyUsageKeyEncipherment","true");
+ defConfig5.putString("params.keyUsageNonRepudiation","true");
+ IPolicyConstraint con5 = policy5.getConstraint();
+ IConfigStore conConfig5 = con5.getConfigStore();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java
new file mode 100644
index 000000000..c9aa0c65d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java
@@ -0,0 +1,223 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements the basic constraints extension constraint.
+ * It checks if the basic constraint in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class BasicConstraintsExtConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_CRITICAL =
+ "basicConstraintsCritical";
+ public static final String CONFIG_IS_CA =
+ "basicConstraintsIsCA";
+ public static final String CONFIG_MIN_PATH_LEN =
+ "basicConstraintsMinPathLen";
+ public static final String CONFIG_MAX_PATH_LEN =
+ "basicConstraintsMaxPathLen";
+
+ public BasicConstraintsExtConstraint() {
+ super();
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_IS_CA);
+ addConfigName(CONFIG_MIN_PATH_LEN);
+ addConfigName(CONFIG_MAX_PATH_LEN);
+ }
+
+ /**
+ * Initializes this constraint plugin.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_IS_CA)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_IS_CA"));
+ } else if (name.equals(CONFIG_MIN_PATH_LEN)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "-1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_MIN_PATH_LEN"));
+ } else if (name.equals(CONFIG_MAX_PATH_LEN)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "100",
+ CMS.getUserMessage(locale, "CMS_PROFILE_MAX_PATH_LEN"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CertificateExtensions exts = null;
+
+ try {
+ BasicConstraintsExtension ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(),
+ info);
+
+ if (ext == null) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ PKIXExtensions.BasicConstraints_Id.toString()));
+ }
+
+ // check criticality
+ String value = getConfig(CONFIG_CRITICAL);
+
+ if (!isOptional(value)) {
+ boolean critical = getBoolean(value);
+
+ if (critical != ext.isCritical()) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CRITICAL_NOT_MATCHED"));
+ }
+ }
+ value = getConfig(CONFIG_IS_CA);
+ if (!isOptional(value)) {
+ boolean isCA = getBoolean(value);
+ Boolean extIsCA = (Boolean) ext.get(BasicConstraintsExtension.IS_CA);
+
+ if (isCA != extIsCA.booleanValue()) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_IS_CA"));
+ }
+ }
+ value = getConfig(CONFIG_MIN_PATH_LEN);
+ if (!isOptional(value)) {
+ int pathLen = getInt(value);
+ Integer extPathLen = (Integer) ext.get(BasicConstraintsExtension.PATH_LEN);
+
+ if (pathLen > extPathLen.intValue()) {
+ CMS.debug("BasicCOnstraintsExtConstraint: pathLen=" + pathLen + " > extPathLen=" + extPathLen);
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_MIN_PATH"));
+ }
+ }
+ value = getConfig(CONFIG_MAX_PATH_LEN);
+ if (!isOptional(value)) {
+ int pathLen = getInt(value);
+ Integer extPathLen = (Integer) ext.get(BasicConstraintsExtension.PATH_LEN);
+
+ if (pathLen < extPathLen.intValue()) {
+ CMS.debug("BasicCOnstraintsExtConstraint: pathLen=" + pathLen + " < extPathLen=" + extPathLen);
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_MAX_PATH"));
+ }
+ }
+ } catch (IOException e) {
+ CMS.debug("BasicConstraintsExt: validate " + e.toString());
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ PKIXExtensions.BasicConstraints_Id.toString()));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_IS_CA),
+ getConfig(CONFIG_MIN_PATH_LEN),
+ getConfig(CONFIG_MAX_PATH_LEN)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_BASIC_CONSTRAINTS_EXT_TEXT",
+ params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof BasicConstraintsExtDefault)
+ return true;
+ if (def instanceof UserExtensionDefault)
+ return true;
+ return false;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+
+
+ if (mConfig.getSubStore("params") == null) {
+ CMS.debug("BasicConstraintsExt: mConfig.getSubStore is null");
+ //
+ } else {
+
+ CMS.debug("BasicConstraintsExt: setConfig name " + name + " value " + value);
+
+ if(name.equals(CONFIG_MAX_PATH_LEN))
+ {
+
+ String minPathLen = getConfig(CONFIG_MIN_PATH_LEN);
+
+ int minLen = getInt(minPathLen);
+
+ int maxLen = getInt(value);
+
+ if(minLen >= maxLen) {
+ CMS.debug("BasicConstraintExt: minPathLen >= maxPathLen!");
+
+ throw new EPropertyException("bad value");
+ }
+
+
+ }
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java
new file mode 100644
index 000000000..7455eb28c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java
@@ -0,0 +1,58 @@
+// --- 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.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.ca.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This class represents an abstract class for CA enrollment
+ * constraint.
+ */
+public abstract class CAEnrollConstraint extends EnrollConstraint {
+
+ /**
+ * Constructs a CA enrollment constraint.
+ */
+ public CAEnrollConstraint() {
+ super();
+ }
+
+ /**
+ * Retrieves the CA certificate.
+ */
+ public X509CertImpl getCACert() {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ X509CertImpl caCert = ca.getCACert();
+
+ return caCert;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java
new file mode 100644
index 000000000..ca7d41fc4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java
@@ -0,0 +1,134 @@
+// --- 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 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 implements the validity constraint.
+ * It checks if the validity in the certificate
+ * template is within the CA's validity.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CAValidityConstraint extends CAEnrollConstraint {
+
+ private Date mDefNotBefore = null;
+ private Date mDefNotAfter = null;
+
+ public CAValidityConstraint() {
+ super();
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ X509CertImpl caCert = getCACert();
+
+ mDefNotBefore = caCert.getNotBefore();
+ mDefNotAfter = caCert.getNotAfter();
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CMS.debug("CAValidityConstraint: validate start");
+ CertificateValidity v = null;
+
+ try {
+ v = (CertificateValidity) info.get(X509CertInfo.VALIDITY);
+ } catch (Exception e) {
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_VALIDITY_NOT_FOUND"));
+ }
+ Date notBefore = null;
+
+ try {
+ notBefore = (Date) v.get(CertificateValidity.NOT_BEFORE);
+ } catch (IOException e) {
+ CMS.debug("CAValidity: not before " + e.toString());
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_INVALID_NOT_BEFORE"));
+ }
+ Date notAfter = null;
+
+ try {
+ notAfter = (Date) v.get(CertificateValidity.NOT_AFTER);
+ } catch (IOException e) {
+ CMS.debug("CAValidity: not after " + e.toString());
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_INVALID_NOT_AFTER"));
+ }
+
+ if (mDefNotBefore != null) {
+ CMS.debug("ValidtyConstraint: notBefore=" + notBefore +
+ " defNotBefore=" + mDefNotBefore);
+ if (notBefore.before(mDefNotBefore)) {
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_INVALID_NOT_BEFORE"));
+ }
+ }
+ CMS.debug("ValidtyConstraint: notAfter=" + notAfter +
+ " defNotAfter=" + mDefNotAfter);
+ if (notAfter.after(mDefNotAfter)) {
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_INVALID_NOT_AFTER"));
+ }
+
+ CMS.debug("CAValidtyConstraint: validate end");
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ mDefNotBefore.toString(),
+ mDefNotAfter.toString()
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_CA_VALIDITY_CONSTRAINT_TEXT",
+ params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UserValidityDefault)
+ return true;
+ if (def instanceof ValidityDefault)
+ return true;
+ if (def instanceof CAValidityDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java
new file mode 100644
index 000000000..5e0627db7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java
@@ -0,0 +1,207 @@
+// --- 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.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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements the generic enrollment constraint.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollConstraint implements IPolicyConstraint {
+ public static final String CONFIG_NAME = "name";
+
+ protected IConfigStore mConfig = null;
+ protected Vector mConfigNames = new Vector();
+
+ public EnrollConstraint() {
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public void addConfigName(String name) {
+ mConfigNames.addElement(name);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public Locale getLocale(IRequest request) {
+ Locale locale = null;
+ String language = request.getExtDataInString(
+ EnrollProfile.REQUEST_LOCALE);
+ if (language != null) {
+ locale = new Locale(language);
+ }
+ return locale;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (mConfig.getSubStore("params") == null) {
+ //
+ } else {
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public String getConfig(String name) {
+ try {
+ if (mConfig == null)
+ return null;
+ if (mConfig.getSubStore("params") != null) {
+ String val = mConfig.getSubStore("params").getString(name);
+
+ return val;
+ }
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ return "";
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ *
+ * @param request enrollment request
+ * @param info certificate template
+ * @exception ERejectException request is rejected due
+ * to violation of constraint
+ */
+ public abstract void validate(IRequest request, X509CertInfo info)
+ throws ERejectException;
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ *
+ * The current implementation of this method calls
+ * into the subclass's validate(request, info)
+ * method for validation checking.
+ *
+ * @param request request
+ * @exception ERejectException request is rejected due
+ * to violation of constraint
+ */
+ public void validate(IRequest request)
+ throws ERejectException {
+ String name = getClass().getName();
+
+ name = name.substring(name.lastIndexOf('.') + 1);
+ CMS.debug(name + ": validate start");
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ validate(request, info);
+
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ CMS.debug(name + ": validate end");
+ }
+
+ public String getText(Locale locale) {
+ return "Enroll Constraint";
+ }
+
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(CONFIG_NAME);
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+
+ protected Extension getExtension(String name, X509CertInfo info) {
+ CertificateExtensions exts = null;
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ CMS.debug("EnrollConstraint: getExtension " + e.toString());
+ }
+ if (exts == null)
+ return null;
+ Enumeration e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+
+ if (ext.getExtensionId().toString().equals(name)) {
+ return ext;
+ }
+ }
+ return null;
+ }
+
+ protected boolean isOptional(String value) {
+ if (value.equals("") || value.equals("-"))
+ return true;
+ else
+ return false;
+ }
+
+ protected boolean getBoolean(String value) {
+ return Boolean.valueOf(value).booleanValue();
+ }
+
+ protected int getInt(String value) {
+ return Integer.valueOf(value).intValue();
+ }
+
+ protected boolean getConfigBoolean(String value) {
+ return getBoolean(getConfig(value));
+ }
+
+ protected int getConfigInt(String value) {
+ return getInt(getConfig(value));
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ return true;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java
new file mode 100644
index 000000000..42a2d1aa2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java
@@ -0,0 +1,150 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements the extended key usage extension constraint.
+ * It checks if the extended key usage extension in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtendedKeyUsageExtConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_CRITICAL = "exKeyUsageCritical";
+ public static final String CONFIG_OIDS =
+ "exKeyUsageOIDs";
+
+ public ExtendedKeyUsageExtConstraint() {
+ super();
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_OIDS);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_OIDS)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_OIDS"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ ExtendedKeyUsageExtension ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+
+ if (ext == null) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ ExtendedKeyUsageExtension.OID));
+ }
+
+ // check criticality
+ String value = getConfig(CONFIG_CRITICAL);
+
+ if (!isOptional(value)) {
+ boolean critical = getBoolean(value);
+
+ if (critical != ext.isCritical()) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_CRITICAL_NOT_MATCHED"));
+ }
+ }
+
+ // Build local cache of configured OIDs
+ Vector mCache = new Vector();
+ StringTokenizer st = new StringTokenizer(getConfig(CONFIG_OIDS), ",");
+
+ while (st.hasMoreTokens()) {
+ String oid = st.nextToken();
+
+ mCache.addElement(oid);
+ }
+
+ // check OIDs
+ Enumeration e = ext.getOIDs();
+
+ while (e.hasMoreElements()) {
+ ObjectIdentifier oid = (ObjectIdentifier) e.nextElement();
+
+ if (!mCache.contains(oid.toString())) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_OID_NOT_MATCHED",
+ oid.toString()));
+ }
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_OIDS)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_EXTENDED_KEY_EXT_TEXT",
+ params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof ExtendedKeyUsageExtDefault)
+ return true;
+ if (def instanceof UserExtensionDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java
new file mode 100644
index 000000000..5dd83f28b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java
@@ -0,0 +1,144 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements the general extension constraint.
+ * It checks if the extension in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtensionConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_CRITICAL = "extCritical";
+ public static final String CONFIG_OID = "extOID";
+
+ public ExtensionConstraint() {
+ super();
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_OID);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+
+ if (mConfig.getSubStore("params") == null) {
+ CMS.debug("ExtensionConstraint: mConfig.getSubStore is null");
+ } else {
+ CMS.debug("ExtensionConstraint: setConfig name=" + name +
+ " value=" + value);
+
+ if(name.equals(CONFIG_OID))
+ {
+ try {
+ CMS.checkOID("", value);
+ } catch (Exception e) {
+ throw new EPropertyException(
+ CMS.getUserMessage("CMS_PROFILE_PROPERTY_ERROR", value));
+ }
+ }
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_OID)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_OID"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+
+ Extension ext = getExtension(getConfig(CONFIG_OID), info);
+
+ if (ext == null) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ getConfig(CONFIG_OID)));
+ }
+
+ // check criticality
+ String value = getConfig(CONFIG_CRITICAL);
+
+ if (!isOptional(value)) {
+ boolean critical = getBoolean(value);
+
+ if (critical != ext.isCritical()) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CRITICAL_NOT_MATCHED"));
+ }
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_OID)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_EXTENSION_TEXT", params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UserExtensionDefault)
+ return true;
+ if (def instanceof EnrollExtDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java
new file mode 100644
index 000000000..134a78ea5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java
@@ -0,0 +1,299 @@
+// --- 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 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 com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.provider.DSAPublicKey;
+import java.security.interfaces.DSAParams;
+import java.math.BigInteger;
+
+
+/**
+ * This constraint is to check the key type and
+ * key length.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_KEY_TYPE = "keyType"; // (EC, RSA)
+ public static final String CONFIG_KEY_PARAMETERS = "keyParameters";
+
+ private static final String[] ecCurves = {"nistp256","nistp384","nistp521","sect163k1","nistk163","sect163r1","sect163r2",
+ "nistb163","sect193r1","sect193r2","sect233k1","nistk233","sect233r1","nistb233","sect239k1","sect283k1","nistk283",
+ "sect283r1","nistb283","sect409k1","nistk409","sect409r1","nistb409","sect571k1","nistk571","sect571r1","nistb571",
+ "secp160k1","secp160r1","secp160r2","secp192k1","secp192r1","nistp192","secp224k1","secp224r1","nistp224","secp256k1",
+ "secp256r1","secp384r1","secp521r1","prime192v1","prime192v2","prime192v3","prime239v1","prime239v2","prime239v3","c2pnb163v1",
+ "c2pnb163v2","c2pnb163v3","c2pnb176v1","c2tnb191v1","c2tnb191v2","c2tnb191v3","c2pnb208w1","c2tnb239v1","c2tnb239v2","c2tnb239v3",
+ "c2pnb272w1","c2pnb304w1","c2tnb359w1","c2pnb368w1","c2tnb431r1","secp112r1","secp112r2","secp128r1","secp128r2","sect113r1","sect113r2",
+ "sect131r1","sect131r2"
+ };
+
+ private static String[] cfgECCurves = null;
+ private static String keyType = "";
+ private static String keyParams = "";
+
+ public KeyConstraint() {
+ super();
+ addConfigName(CONFIG_KEY_TYPE);
+ addConfigName(CONFIG_KEY_PARAMETERS);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ String ecNames = "";
+ try {
+ ecNames = CMS.getConfigStore().getString("keys.ecc.curve.list");
+ } catch (Exception e) {
+ }
+
+ CMS.debug("KeyConstraint.init ecNames: " + ecNames);
+ if (ecNames != null && ecNames.length() != 0) {
+ cfgECCurves = ecNames.split(",");
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_KEY_TYPE)) {
+ return new Descriptor(IDescriptor.CHOICE, "-,RSA,EC",
+ "RSA",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_TYPE"));
+ } else if (name.equals(CONFIG_KEY_PARAMETERS)) {
+ return new Descriptor(IDescriptor.STRING,null,"",
+ CMS.getUserMessage(locale,"CMS_PROFILE_KEY_PARAMETERS"));
+ }
+
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ try {
+ CertificateX509Key infokey = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ X509Key key = (X509Key) infokey.get(CertificateX509Key.KEY);
+
+ String alg = key.getAlgorithmId().getName().toUpperCase();
+ String value = getConfig(CONFIG_KEY_TYPE);
+ String keyType = value;
+
+ if (!isOptional(value)) {
+ if (!alg.equals(value)) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_KEY_TYPE_NOT_MATCHED",
+ value));
+ }
+ }
+
+ int keySize = 0;
+ String ecCurve = "";
+
+ if (alg.equals("RSA")) {
+ keySize = getRSAKeyLen(key);
+ } else if (alg.equals("DSA")) {
+ keySize = getDSAKeyLen(key);
+ } else if (alg.equals("EC")) {
+ //EC key case.
+ } else {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_INVALID_KEY_TYPE",
+ alg));
+ }
+
+ value = getConfig(CONFIG_KEY_PARAMETERS);
+
+ String[] keyParams = value.split(",");
+
+ if (alg.equals("EC")) {
+ //For now only check for legal EC key type.
+ //We don't have the required EC key class to evaluate curve names.
+ if (!alg.equals(keyType) && !isOptional(keyType)) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_KEY_PARAMS_NOT_MATCHED",
+ value));
+ }
+ CMS.debug("KeyConstraint.validate: EC key constrainst passed.");
+ } else {
+ if ( !arrayContainsString(keyParams,Integer.toString(keySize))) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_KEY_PARAMS_NOT_MATCHED",
+ value));
+ }
+ CMS.debug("KeyConstraint.validate: RSA key contraints passed.");
+ }
+ } catch (Exception e) {
+ if (e instanceof ERejectException) {
+ throw (ERejectException) e;
+ }
+ CMS.debug("KeyConstraint: " + e.toString());
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_KEY_NOT_FOUND"));
+ }
+ }
+
+ public int getRSAKeyLen(X509Key key) throws Exception {
+ X509Key newkey = null;
+
+ try {
+ newkey = new X509Key(AlgorithmId.get("RSA"),
+ key.getKey());
+ } catch (Exception e) {
+ CMS.debug("KeyConstraint: getRSAKey Len " + e.toString());
+ return -1;
+ }
+ RSAPublicKey rsaKey = new RSAPublicKey(newkey.getEncoded());
+
+ return rsaKey.getKeySize();
+ }
+
+ public int getDSAKeyLen(X509Key key) throws Exception {
+ // Check DSAKey parameters.
+ // size refers to the p parameter.
+ DSAPublicKey dsaKey = new DSAPublicKey(key.getEncoded());
+ DSAParams keyParams = dsaKey.getParams();
+ BigInteger p = keyParams.getP();
+ int len = p.bitLength();
+
+ return len;
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_KEY_TYPE),
+ getConfig(CONFIG_KEY_PARAMETERS)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_KEY_TEXT", params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UserKeyDefault)
+ return true;
+ return false;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+
+ CMS.debug("KeyConstraint.setConfig name: " + name + " value: " + value);
+ //establish keyType, we don't know which order these params will arrive
+ if (name.equals(CONFIG_KEY_TYPE)) {
+ keyType = value;
+ if(keyParams.equals(""))
+ return;
+ }
+
+ //establish keyParams
+ if (name.equals(CONFIG_KEY_PARAMETERS)) {
+ CMS.debug("establish keyParams: " + value);
+ keyParams = value;
+
+ if(keyType.equals(""))
+ return;
+ }
+ // All the params we need for validation have been collected,
+ // we don't know which order they will show up
+ if (keyType.length() > 0 && keyParams.length() > 0) {
+ String[] params = keyParams.split(",");
+ boolean isECCurve = false;
+ int keySize = 0;
+
+ for (int i = 0; i < params.length; i++) {
+ if (keyType.equals("EC")) {
+ if (cfgECCurves == null) {
+ //Use the static array as a backup if the config values are not present.
+ isECCurve = arrayContainsString(ecCurves,params[i]);
+ } else {
+ isECCurve = arrayContainsString(cfgECCurves,params[i]);
+ }
+ if (isECCurve == false) { //Not a valid EC curve throw exception.
+ keyType = "";
+ keyParams = "";
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ try {
+ keySize = Integer.parseInt(params[i]);
+ } catch (Exception e) {
+ keySize = 0;
+ }
+ if (keySize <= 0) {
+ keyType = "";
+ keyParams = "";
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", name));
+ }
+ }
+ }
+ }
+ //Actually set the configuration in the profile
+ super.setConfig(CONFIG_KEY_TYPE, keyType);
+ super.setConfig(CONFIG_KEY_PARAMETERS, keyParams);
+
+ //Reset the vars for next round.
+ keyType = "";
+ keyParams = "";
+ }
+
+ private boolean arrayContainsString(String[] array, String value) {
+
+ if (array == null || value == null) {
+ return false;
+ }
+
+ for (int i = 0 ; i < array.length; i++) {
+ if (array[i].equals(value)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java
new file mode 100644
index 000000000..ff87f9045
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java
@@ -0,0 +1,286 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements the key usage extension constraint.
+ * It checks if the key usage constraint in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyUsageExtConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_CRITICAL = "keyUsageCritical";
+ public static final String CONFIG_DIGITAL_SIGNATURE =
+ "keyUsageDigitalSignature";
+ public static final String CONFIG_NON_REPUDIATION =
+ "keyUsageNonRepudiation";
+ public static final String CONFIG_KEY_ENCIPHERMENT =
+ "keyUsageKeyEncipherment";
+ public static final String CONFIG_DATA_ENCIPHERMENT =
+ "keyUsageDataEncipherment";
+ public static final String CONFIG_KEY_AGREEMENT = "keyUsageKeyAgreement";
+ public static final String CONFIG_KEY_CERTSIGN = "keyUsageKeyCertSign";
+ public static final String CONFIG_CRL_SIGN = "keyUsageCrlSign";
+ public static final String CONFIG_ENCIPHER_ONLY = "keyUsageEncipherOnly";
+ public static final String CONFIG_DECIPHER_ONLY = "keyUsageDecipherOnly";
+
+ public KeyUsageExtConstraint() {
+ super();
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_DIGITAL_SIGNATURE);
+ addConfigName(CONFIG_NON_REPUDIATION);
+ addConfigName(CONFIG_KEY_ENCIPHERMENT);
+ addConfigName(CONFIG_DATA_ENCIPHERMENT);
+ addConfigName(CONFIG_KEY_AGREEMENT);
+ addConfigName(CONFIG_KEY_CERTSIGN);
+ addConfigName(CONFIG_CRL_SIGN);
+ addConfigName(CONFIG_ENCIPHER_ONLY);
+ addConfigName(CONFIG_DECIPHER_ONLY);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_DIGITAL_SIGNATURE)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DIGITAL_SIGNATURE"));
+ } else if (name.equals(CONFIG_NON_REPUDIATION)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NON_REPUDIATION"));
+ } else if (name.equals(CONFIG_KEY_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_ENCIPHERMENT"));
+ } else if (name.equals(CONFIG_DATA_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DATA_ENCIPHERMENT"));
+ } else if (name.equals(CONFIG_KEY_AGREEMENT)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_AGREEMENT"));
+ } else if (name.equals(CONFIG_KEY_CERTSIGN)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_CERTSIGN"));
+ } else if (name.equals(CONFIG_CRL_SIGN)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRL_SIGN"));
+ } else if (name.equals(CONFIG_ENCIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENCIPHER_ONLY"));
+ } else if (name.equals(CONFIG_DECIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DECIPHER_ONLY"));
+ }
+ return null;
+ }
+
+ public boolean isSet(boolean bits[], int position) {
+ if (bits.length <= position)
+ return false;
+ return bits[position];
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ KeyUsageExtension ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+
+ if (ext == null) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ PKIXExtensions.KeyUsage_Id.toString()));
+ }
+
+ boolean[] bits = ext.getBits();
+ String value = getConfig(CONFIG_CRITICAL);
+
+ if (!isOptional(value)) {
+ boolean critical = getBoolean(value);
+
+ if (critical != ext.isCritical()) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CRITICAL_NOT_MATCHED"));
+ }
+ }
+ value = getConfig(CONFIG_DIGITAL_SIGNATURE);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 0)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_DIGITAL_SIGNATURE_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_NON_REPUDIATION);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 1)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_NON_REPUDIATION_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_KEY_ENCIPHERMENT);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 2)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_KEY_ENCIPHERMENT_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_DATA_ENCIPHERMENT);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 3)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_DATA_ENCIPHERMENT_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_KEY_AGREEMENT);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 4)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_KEY_AGREEMENT_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_KEY_CERTSIGN);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 5)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_KEY_CERTSIGN_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_CRL_SIGN);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 6)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CRL_SIGN_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_ENCIPHER_ONLY);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 7)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_ENCIPHER_ONLY_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_DECIPHER_ONLY);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != isSet(bits, 8)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_DECIPHER_ONLY_NOT_MATCHED",
+ value));
+ }
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_DIGITAL_SIGNATURE),
+ getConfig(CONFIG_NON_REPUDIATION),
+ getConfig(CONFIG_KEY_ENCIPHERMENT),
+ getConfig(CONFIG_DATA_ENCIPHERMENT),
+ getConfig(CONFIG_KEY_AGREEMENT),
+ getConfig(CONFIG_KEY_CERTSIGN),
+ getConfig(CONFIG_CRL_SIGN),
+ getConfig(CONFIG_ENCIPHER_ONLY),
+ getConfig(CONFIG_DECIPHER_ONLY)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_KEY_USAGE_EXT_TEXT", params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof KeyUsageExtDefault)
+ return true;
+ if (def instanceof UserExtensionDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java
new file mode 100644
index 000000000..2ae8e5346
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java
@@ -0,0 +1,240 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements the Netscape certificate type extension constraint.
+ * It checks if the Netscape certificate type extension in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NSCertTypeExtConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_CRITICAL = "nsCertCritical";
+ public static final String CONFIG_SSL_CLIENT = "nsCertSSLClient";
+ public static final String CONFIG_SSL_SERVER = "nsCertSSLServer";
+ public static final String CONFIG_EMAIL = "nsCertEmail";
+ public static final String CONFIG_OBJECT_SIGNING = "nsCertObjectSigning";
+ public static final String CONFIG_SSL_CA = "nsCertSSLCA";
+ public static final String CONFIG_EMAIL_CA = "nsCertEmailCA";
+ public static final String CONFIG_OBJECT_SIGNING_CA = "nsCertObjectSigningCA";
+
+ public NSCertTypeExtConstraint() {
+ super();
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_SSL_CLIENT);
+ addConfigName(CONFIG_SSL_SERVER);
+ addConfigName(CONFIG_EMAIL);
+ addConfigName(CONFIG_OBJECT_SIGNING);
+ addConfigName(CONFIG_SSL_CA);
+ addConfigName(CONFIG_EMAIL_CA);
+ addConfigName(CONFIG_OBJECT_SIGNING_CA);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_SSL_CLIENT)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CLIENT"));
+ } else if (name.equals(CONFIG_SSL_SERVER)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_SERVER"));
+ } else if (name.equals(CONFIG_EMAIL)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL"));
+ } else if (name.equals(CONFIG_OBJECT_SIGNING)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OBJECT_SIGNING"));
+ } else if (name.equals(CONFIG_SSL_CA)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CA"));
+ } else if (name.equals(CONFIG_EMAIL_CA)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL_CA"));
+ } else if (name.equals(CONFIG_OBJECT_SIGNING_CA)) {
+ return new Descriptor(IDescriptor.CHOICE, "true,false,-",
+ "-",
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OBJECT_SIGNING_CA"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ NSCertTypeExtension ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+
+ if (ext == null) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_EXTENSION_NOT_FOUND",
+ NSCertTypeExtension.CertType_Id.toString()));
+ }
+
+ String value = getConfig(CONFIG_CRITICAL);
+
+ if (!isOptional(value)) {
+ boolean critical = getBoolean(value);
+
+ if (critical != ext.isCritical()) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_CRITICAL_NOT_MATCHED"));
+ }
+ }
+ value = getConfig(CONFIG_SSL_CLIENT);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(0)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SSL_CLIENT_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_SSL_SERVER);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(1)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SSL_SERVER_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_EMAIL);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(2)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_EMAIL_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_OBJECT_SIGNING);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(3)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_OBJECT_SIGNING_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_SSL_CA);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(4)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SSL_CA_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_EMAIL_CA);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(5)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_EMAIL_CA_NOT_MATCHED",
+ value));
+ }
+ }
+ value = getConfig(CONFIG_OBJECT_SIGNING_CA);
+ if (!isOptional(value)) {
+ boolean bit = getBoolean(value);
+
+ if (bit != ext.isSet(6)) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_OBJECT_SIGNING_CA_NOT_MATCHED",
+ value));
+ }
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_SSL_CLIENT),
+ getConfig(CONFIG_SSL_SERVER),
+ getConfig(CONFIG_EMAIL),
+ getConfig(CONFIG_OBJECT_SIGNING),
+ getConfig(CONFIG_SSL_CA),
+ getConfig(CONFIG_EMAIL_CA),
+ getConfig(CONFIG_OBJECT_SIGNING_CA)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_NS_CERT_EXT_TEXT", params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof NSCertTypeExtDefault)
+ return true;
+ if (def instanceof UserExtensionDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java
new file mode 100644
index 000000000..30e81e7e7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java
@@ -0,0 +1,96 @@
+// --- 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 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 com.netscape.cms.profile.def.*;
+
+
+/**
+ * This class implements no constraint.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NoConstraint implements IPolicyConstraint {
+
+ public static final String CONFIG_NAME = "name";
+
+ private IConfigStore mConfig = null;
+ private Vector mNames = new Vector();
+
+ public Enumeration getConfigNames() {
+ return mNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ }
+
+ public String getConfig(String name) {
+ return null;
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request)
+ throws ERejectException {
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_NO_CONSTRAINT_TEXT");
+ }
+
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(CONFIG_NAME);
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ return true;
+ }
+}
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..da2498b15
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
@@ -0,0 +1,162 @@
+// --- 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;
+ BigInteger renew_grace_before_BI = new BigInteger(renew_grace_before_s);
+ BigInteger renew_grace_after_BI= new BigInteger(renew_grace_after_s);
+
+ // -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);
+
+ if (renew_grace_before > 0)
+ renew_grace_before_BI = renew_grace_before_BI.multiply(BigInteger.valueOf(1000 * 86400));
+ if (renew_grace_after > 0)
+ renew_grace_after_BI = renew_grace_after_BI.multiply(BigInteger.valueOf(1000 * 86400));
+
+ Date current = CMS.getCurrentDate();
+ long millisDiff = origExpDate.getTime() - current.getTime();
+ CMS.debug("validateRenewGracePeriod: millisDiff=" + millisDiff + " origExpDate=" + origExpDate.getTime() + " current=" + current.getTime());
+
+ /*
+ * "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 (millisDiff >= 0) {
+ if ((renew_grace_before>0) && (millisDiff > renew_grace_before_BI.longValue())) {
+ 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-millisDiff) > renew_grace_after_BI.longValue())) {
+ 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/SigningAlgConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java
new file mode 100644
index 000000000..1e81bd682
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java
@@ -0,0 +1,153 @@
+// --- 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 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 implements the signing algorithm constraint.
+ * It checks if the signing algorithm in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SigningAlgConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_ALGORITHMS_ALLOWED = "signingAlgsAllowed";
+
+ private static StringBuffer sb = new StringBuffer("");
+ static {
+ for (int i = 0; i < AlgorithmId.ALL_SIGNING_ALGORITHMS.length; i++) {
+ if (i > 0) {
+ sb.append(",");
+ }
+ sb.append(AlgorithmId.ALL_SIGNING_ALGORITHMS[i]);
+ }
+ }
+ public static final String DEF_CONFIG_ALGORITHMS = new String(sb);
+
+ public SigningAlgConstraint() {
+ super();
+ addConfigName(CONFIG_ALGORITHMS_ALLOWED);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+
+ if (mConfig.getSubStore("params") == null) {
+ CMS.debug("SigningAlgConstraint: mConfig.getSubStore is null");
+ } else {
+ CMS.debug("SigningAlgConstraint: setConfig name=" + name +
+ " value=" + value);
+
+ if(name.equals(CONFIG_ALGORITHMS_ALLOWED))
+ {
+ StringTokenizer st = new StringTokenizer(value, ",");
+ while (st.hasMoreTokens()) {
+ String v = st.nextToken();
+ if (DEF_CONFIG_ALGORITHMS.indexOf(v) == -1) {
+ throw new EPropertyException(
+ CMS.getUserMessage("CMS_PROFILE_PROPERTY_ERROR", v));
+ }
+ }
+ }
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_ALGORITHMS_ALLOWED)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ DEF_CONFIG_ALGORITHMS,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SIGNING_ALGORITHMS_ALLOWED"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CertificateAlgorithmId algId = null;
+
+ try {
+ algId = (CertificateAlgorithmId) info.get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId id = (AlgorithmId)
+ algId.get(CertificateAlgorithmId.ALGORITHM);
+
+ Vector mCache = new Vector();
+ StringTokenizer st = new StringTokenizer(
+ getConfig(CONFIG_ALGORITHMS_ALLOWED), ",");
+
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+
+ mCache.addElement(token);
+ }
+
+ if (!mCache.contains(id.toString())) {
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_SIGNING_ALGORITHM_NOT_MATCHED", id.toString()));
+ }
+ } catch (Exception e) {
+ if (e instanceof ERejectException) {
+ throw (ERejectException) e;
+ }
+ CMS.debug("SigningAlgConstraint: " + e.toString());
+ throw new ERejectException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_SIGNING_ALGORITHM_NOT_FOUND"));
+ }
+
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_CONSTRAINT_SIGNING_ALG_TEXT", getConfig(CONFIG_ALGORITHMS_ALLOWED));
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UserSigningAlgDefault)
+ return true;
+ if (def instanceof SigningAlgDefault)
+ 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
new file mode 100644
index 000000000..4e9a9c34d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java
@@ -0,0 +1,130 @@
+// --- 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 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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements the subject name constraint.
+ * It checks if the subject name in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectNameConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_PATTERN = "pattern";
+
+ public SubjectNameConstraint() {
+ // configuration names
+ addConfigName(CONFIG_PATTERN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_PATTERN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME_PATTERN"));
+ } else {
+ return null;
+ }
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CMS.debug("SubjectNameConstraint: validate start");
+ CertificateSubjectName sn = null;
+
+ 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),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ }
+ X500Name sn500 = null;
+
+ try {
+ sn500 = (X500Name) sn.get(CertificateSubjectName.DN_NAME);
+ } catch (IOException e) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "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",
+ sn500.toString()));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_SUBJECT_NAME_TEXT",
+ getConfig(CONFIG_PATTERN));
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof SubjectNameDefault)
+ return true;
+ if (def instanceof UserSubjectNameDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
new file mode 100644
index 000000000..1770c13ef
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
@@ -0,0 +1,290 @@
+// --- 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 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 com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+
+import netscape.security.x509.*;
+//import netscape.security.provider.*;
+import netscape.security.util.*;
+import java.math.BigInteger;
+
+/**
+ * This constraint is to check for publickey uniqueness.
+ * The config param "allowSameKeyRenewal" enables the
+ * situation where if the publickey is not unique, and if
+ * the subject DN is the same, that is a "renewal".
+ *
+ * Another "feature" that is quoted out of this code is the
+ * "revokeDupKeyCert" option, which enables the revocation
+ * of certs that bear the same publickey as the enrolling
+ * request. Since this can potentially be abused, it is taken
+ * out and preserved in comments to allow future refinement.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UniqueKeyConstraint extends EnrollConstraint {
+ /*
+ public static final String CONFIG_REVOKE_DUPKEY_CERT =
+ "revokeDupKeyCert";
+ boolean mRevokeDupKeyCert = false;
+ */
+ public static final String CONFIG_ALLOW_SAME_KEY_RENEWAL =
+ "allowSameKeyRenewal";
+ boolean mAllowSameKeyRenewal = false;
+ public ICertificateAuthority mCA = null;
+
+ public UniqueKeyConstraint() {
+ super();
+ /*
+ addConfigName(CONFIG_REVOKE_DUPKEY_CERT);
+ */
+ addConfigName(CONFIG_ALLOW_SAME_KEY_RENEWAL);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ mCA = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name)
+ {
+ /*
+ if (name.equals(CONFIG_REVOKE_DUPKEY_CERT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CONFIG_REVOKE_DUPKEY_CERT"));
+ }
+ */
+ if (name.equals(CONFIG_ALLOW_SAME_KEY_RENEWAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CONFIG_ALLOW_SAME_KEY_RENEWAL"));
+ }
+ return null;
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ boolean rejected = false;
+ int size = 0;
+ ICertRecordList list;
+
+ /*
+ mRevokeDupKeyCert =
+ getConfigBoolean(CONFIG_REVOKE_DUPKEY_CERT);
+ */
+ mAllowSameKeyRenewal = getConfigBoolean(CONFIG_ALLOW_SAME_KEY_RENEWAL);
+
+ try {
+ CertificateX509Key infokey = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ X509Key key = (X509Key)
+ infokey.get(CertificateX509Key.KEY);
+
+ // check for key uniqueness
+ byte pub[] = key.getEncoded();
+ String pub_s = escapeBinaryData(pub);
+ String filter = "(" + ICertRecord.ATTR_X509CERT_PUBLIC_KEY_DATA +"=" + pub_s + ")";
+ list =
+ (ICertRecordList)
+ mCA.getCertificateRepository().findCertRecordsInList(filter, null, 10);
+ size = list.getSize();
+
+ } catch (Exception e) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_INTERNAL_ERROR",e.toString()));
+ }
+
+ /*
+ * It does not matter if the corresponding cert's status
+ * is valid or not, we don't want a key that was once
+ * generated before
+ */
+ if (size > 0) {
+ CMS.debug("UniqueKeyConstraint: found existing cert with duplicate key.");
+
+ /*
+ The following code revokes the existing certs that have
+ the same public key as the one submitted for enrollment
+ request. However, it is not a good idea due to possible
+ abuse. It is therefore commented out. It is still
+ however still maintained for possible utilization at later
+ time
+
+ // if configured to revoke duplicated key
+ // revoke cert
+ if (mRevokeDupKeyCert) {
+ try {
+ Enumeration e = list.getCertRecords(0, size-1);
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+
+ // revoke the cert
+ BigInteger serialNum = cert.getSerialNumber();
+ ICAService service = (ICAService) mCA.getCAService();
+
+ RevokedCertImpl crlEntry =
+ formCRLEntry(serialNum, RevocationReason.KEY_COMPROMISE);
+ service.revokeCert(crlEntry);
+ CMS.debug("UniqueKeyConstraint: certificate with duplicate publickey revoked successfully");
+ }
+ } catch (Exception ex) {
+ CMS.debug("UniqueKeyConstraint: error in revoke dupkey cert");
+ }
+ } // revoke dupkey cert turned on
+ */
+
+ if (mAllowSameKeyRenewal == true) {
+ X500Name sjname_in_db = null;
+ X500Name sjname_in_req = null;
+
+ try {
+ // get subject of request
+ CertificateSubjectName subName =
+ (CertificateSubjectName) info.get(X509CertInfo.SUBJECT);
+
+ if (subName != null) {
+
+ sjname_in_req =
+ (X500Name) subName.get(CertificateSubjectName.DN_NAME);
+ CMS.debug("UniqueKeyConstraint: cert request subject DN ="+ sjname_in_req.toString());
+ Enumeration e = list.getCertRecords(0, size-1);
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ String certDN =
+ cert.getSubjectDN().toString();
+ CMS.debug("UniqueKeyConstraint: cert retrieved from ldap has subject DN ="+ certDN);
+
+ sjname_in_db = new X500Name(certDN);
+
+ if (sjname_in_db.equals(sjname_in_req) == false) {
+ rejected = true;
+ break;
+ } else {
+ rejected = false;
+ }
+ } // while
+ } else { //subName is null
+ rejected = true;
+ }
+ } catch (Exception ex1) {
+ CMS.debug("UniqueKeyConstraint: error in allowSameKeyRenewal: "+ex1.toString());
+ rejected = true;
+ } // try
+
+ } else {
+ rejected = true;
+ }// allowSameKeyRenewal
+ } // (size > 0)
+
+ if (rejected == true) {
+ CMS.debug("UniqueKeyConstraint: rejected");
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_DUPLICATE_KEY"));
+ } else {
+ CMS.debug("UniqueKeyConstraint: approved");
+ }
+ }
+
+ /**
+ * make a CRL entry from a serial number and revocation reason.
+ * @return a RevokedCertImpl that can be entered in a CRL.
+
+ protected RevokedCertImpl formCRLEntry(
+ BigInteger serialNo, RevocationReason reason)
+ throws EBaseException {
+ CRLReasonExtension reasonExt = new CRLReasonExtension(reason);
+ CRLExtensions crlentryexts = new CRLExtensions();
+
+ try {
+ crlentryexts.set(CRLReasonExtension.NAME, reasonExt);
+ } catch (IOException e) {
+ CMS.debug("CMSGW_ERR_CRL_REASON "+e.toString());
+
+ // throw new ECMSGWException(
+ // CMS.getLogMessage("CMSGW_ERROR_SETTING_CRLREASON"));
+
+ }
+ RevokedCertImpl crlentry =
+ new RevokedCertImpl(serialNo, CMS.getCurrentDate(),
+ crlentryexts);
+
+ return crlentry;
+ }
+ */
+
+ public String getText(Locale locale) {
+ String params[] = {
+/*
+ getConfig(CONFIG_REVOKE_DUPKEY_CERT),
+*/
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_ALLOW_SAME_KEY_RENEWAL_TEXT", params);
+ }
+
+ public static String escapeBinaryData(byte data[]) {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < data.length; i++) {
+ int v = 0xff & data[i];
+ sb.append("\\");
+ sb.append((v < 16 ? "0" : ""));
+ sb.append(Integer.toHexString(v));
+ }
+ return sb.toString();
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UniqueKeyConstraint)
+ return true;
+
+ return false;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java
new file mode 100644
index 000000000..17a5d4bc4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java
@@ -0,0 +1,233 @@
+// --- 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 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 com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.profile.common.*;
+import com.netscape.cms.profile.def.*;
+import netscape.security.x509.*;
+
+/**
+ * This class implements the unique subject name constraint.
+ * It checks if the subject name in the certificate is
+ * unique in the internal database, ie, no two certificates
+ * have the same subject name.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UniqueSubjectNameConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_KEY_USAGE_EXTENSION_CHECKING =
+ "enableKeyUsageExtensionChecking";
+ private boolean mKeyUsageExtensionChecking = true;
+
+ public UniqueSubjectNameConstraint() {
+ addConfigName(CONFIG_KEY_USAGE_EXTENSION_CHECKING);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_KEY_USAGE_EXTENSION_CHECKING)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING"));
+ }
+ return null;
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ /**
+ * Checks if the key extension in the issued certificate
+ * is the same as the one in the certificate template.
+ */
+ private boolean sameKeyUsageExtension(ICertRecord rec,
+ X509CertInfo certInfo) {
+ X509CertImpl impl = rec.getCertificate();
+ boolean bits[] = impl.getKeyUsage();
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (java.security.cert.CertificateException e) {
+ }
+ KeyUsageExtension ext = null;
+
+ if (extensions == null) {
+ if (bits != null)
+ return false;
+ } else {
+ try {
+ ext = (KeyUsageExtension) extensions.get(
+ KeyUsageExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (ext == null) {
+ if (bits != null)
+ return false;
+ } else {
+ boolean[] InfoBits = ext.getBits();
+
+ if (InfoBits == null) {
+ if (bits != null)
+ return false;
+ } else {
+ if (bits == null)
+ return false;
+ if (InfoBits.length != bits.length) {
+ return false;
+ }
+ for (int i = 0; i < InfoBits.length; i++) {
+ if (InfoBits[i] != bits[i])
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ *
+ * Rules are as follows:
+ * If the subject name is not unique, then the request will be rejected unless:
+ * 1. the certificate is expired or expired_revoked
+ * 2. the certificate is revoked and the revocation reason is not "on hold"
+ * 3. the keyUsageExtension bits are different and enableKeyUsageExtensionChecking=true (default)
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CMS.debug("UniqueSubjectNameConstraint: validate start");
+ CertificateSubjectName sn = null;
+ IAuthority authority = (IAuthority)CMS.getSubsystem("ca");
+
+ mKeyUsageExtensionChecking = getConfigBoolean(CONFIG_KEY_USAGE_EXTENSION_CHECKING);
+ ICertificateRepository certdb = null;
+ if (authority != null && authority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority)authority;
+ certdb = ca.getCertificateRepository();
+ }
+
+ try {
+ sn = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT);
+ } catch (Exception e) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ }
+
+ String certsubjectname = null;
+ if (sn == null)
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ else {
+ certsubjectname = sn.toString();
+ String filter = "x509Cert.subject=" + certsubjectname;
+ Enumeration sameSubjRecords = null;
+ try {
+ sameSubjRecords = certdb.findCertRecords(filter);
+ } catch (EBaseException e) {
+ CMS.debug("UniqueSubjectNameConstraint exception: "+e.toString());
+ }
+ while (sameSubjRecords != null && sameSubjRecords.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) sameSubjRecords.nextElement();
+ String status = rec.getStatus();
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+ RevocationReason reason = null;
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enumx = crlExts.getElements();
+
+ while (enumx.hasMoreElements()) {
+ Extension ext = (Extension) enumx.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason();
+ }
+ }
+ }
+ }
+
+ if (status.equals(ICertRecord.STATUS_EXPIRED) || status.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ continue;
+ }
+
+ if (status.equals(ICertRecord.STATUS_REVOKED) && reason != null &&
+ (! reason.equals(RevocationReason.CERTIFICATE_HOLD))) {
+ continue;
+ }
+
+ if (mKeyUsageExtensionChecking && !sameKeyUsageExtension(rec, info)) {
+ continue;
+ }
+
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_UNIQUE",
+ certsubjectname));
+ }
+ }
+ CMS.debug("UniqueSubjectNameConstraint: validate end");
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_KEY_USAGE_EXTENSION_CHECKING)
+ };
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_UNIQUE_SUBJECT_NAME_TEXT",
+ params);
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof SubjectNameDefault)
+ return true;
+ if (def instanceof UserSubjectNameDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java
new file mode 100644
index 000000000..b4b37fcf0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java
@@ -0,0 +1,209 @@
+// --- 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 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 implements the validity constraint.
+ * It checks if the validity in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ValidityConstraint extends EnrollConstraint {
+
+ public static final String CONFIG_RANGE = "range";
+ public static final String CONFIG_NOT_BEFORE_GRACE_PERIOD = "notBeforeGracePeriod";
+ public static final String CONFIG_CHECK_NOT_BEFORE = "notBeforeCheck";
+ public static final String CONFIG_CHECK_NOT_AFTER = "notAfterCheck";
+ public final static long SECS_IN_MS = 1000L;
+
+ private Date mDefNotBefore = null;
+ private Date mDefNotAfter = null;
+
+ public ValidityConstraint() {
+ super();
+ addConfigName(CONFIG_RANGE);
+ addConfigName(CONFIG_NOT_BEFORE_GRACE_PERIOD);
+ addConfigName(CONFIG_CHECK_NOT_BEFORE);
+ addConfigName(CONFIG_CHECK_NOT_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_RANGE) ||
+ name.equals(CONFIG_NOT_BEFORE_GRACE_PERIOD)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", name));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_RANGE)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "365",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_RANGE"));
+ } else if (name.equals(CONFIG_NOT_BEFORE_GRACE_PERIOD)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "0",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_NOT_BEFORE_GRACE_PERIOD"));
+ } else if (name.equals(CONFIG_CHECK_NOT_BEFORE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_CHECK_NOT_BEFORE"));
+ } else if (name.equals(CONFIG_CHECK_NOT_AFTER)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_CHECK_NOT_AFTER"));
+ }
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ CertificateValidity v = null;
+
+ try {
+ v = (CertificateValidity) info.get(X509CertInfo.VALIDITY);
+ } catch (Exception e) {
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_VALIDITY_NOT_FOUND"));
+ }
+ Date notBefore = null;
+
+ try {
+ notBefore = (Date) v.get(CertificateValidity.NOT_BEFORE);
+ } catch (IOException e) {
+ CMS.debug("ValidityConstraint: not before not found");
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_VALIDITY_NOT_FOUND"));
+ }
+ Date notAfter = null;
+
+ try {
+ notAfter = (Date) v.get(CertificateValidity.NOT_AFTER);
+ } catch (IOException e) {
+ CMS.debug("ValidityConstraint: not after not found");
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_VALIDITY_NOT_FOUND"));
+ }
+
+ if (notAfter.getTime() < notBefore.getTime()) {
+ CMS.debug("ValidityConstraint: notAfter (" + notAfter + ") < notBefore (" + notBefore + ")");
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_NOT_AFTER_BEFORE_NOT_BEFORE"));
+ }
+
+ long millisDiff = notAfter.getTime() - notBefore.getTime();
+ CMS.debug("ValidityConstraint: millisDiff=" + millisDiff + " notAfter=" + notAfter.getTime() + " notBefore=" + notBefore.getTime());
+ long long_days = (millisDiff / 1000 ) / 86400;
+ CMS.debug("ValidityConstraint: long_days: "+long_days);
+ int days = (int)long_days;
+ CMS.debug("ValidityConstraint: days: "+days);
+
+ if (days > Integer.parseInt(getConfig(CONFIG_RANGE))) {
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_VALIDITY_OUT_OF_RANGE",
+ Integer.toString(days)));
+ }
+
+ // 613828
+ // The validity field shall specify a notBefore value
+ // that does not precede the current time and a notAfter
+ // value that does not precede the value specified in
+ // notBefore (test can be automated; try entering violating
+ // time values and check result).
+ String notBeforeCheckStr = getConfig(CONFIG_CHECK_NOT_BEFORE);
+ boolean notBeforeCheck;
+
+ if (notBeforeCheckStr == null || notBeforeCheckStr.equals("")) {
+ notBeforeCheckStr = "false";
+ }
+ notBeforeCheck = Boolean.valueOf(notBeforeCheckStr).booleanValue();
+
+ String notAfterCheckStr = getConfig(CONFIG_CHECK_NOT_AFTER);
+ boolean notAfterCheck;
+
+ if (notAfterCheckStr == null || notAfterCheckStr.equals("")) {
+ notAfterCheckStr = "false";
+ }
+ notAfterCheck = Boolean.valueOf(notAfterCheckStr).booleanValue();
+
+ String notBeforeGracePeriodStr = getConfig(CONFIG_NOT_BEFORE_GRACE_PERIOD);
+ if (notBeforeGracePeriodStr == null || notBeforeGracePeriodStr.equals("")) {
+ notBeforeGracePeriodStr = "0";
+ }
+ long notBeforeGracePeriod = Long.parseLong(notBeforeGracePeriodStr) * SECS_IN_MS;
+
+ Date current = CMS.getCurrentDate();
+ if (notBeforeCheck) {
+ if (notBefore.getTime() > (current.getTime() + notBeforeGracePeriod)) {
+ CMS.debug("ValidityConstraint: notBefore (" + notBefore + ") > current + "+
+ "gracePeriod (" + new Date(current.getTime() + notBeforeGracePeriod) + ")");
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_NOT_BEFORE_AFTER_CURRENT"));
+ }
+ }
+ if (notAfterCheck) {
+ if (notAfter.getTime() < current.getTime()) {
+ CMS.debug("ValidityConstraint: notAfter (" + notAfter + ") < current + (" + current + ")");
+ throw new ERejectException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_NOT_AFTER_BEFORE_CURRENT"));
+ }
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_CONSTRAINT_VALIDITY_TEXT", getConfig(CONFIG_RANGE));
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ if (def instanceof UserValidityDefault)
+ return true;
+ if (def instanceof ValidityDefault)
+ return true;
+ if (def instanceof CAValidityDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java
new file mode 100644
index 000000000..2c42841b4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java
@@ -0,0 +1,455 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+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 com.netscape.certsrv.common.*;
+
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Authuority Info Access extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthInfoAccessExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "authInfoAccessCritical";
+ public static final String CONFIG_NUM_ADS = "authInfoAccessNumADs";
+ public static final String CONFIG_AD_ENABLE = "authInfoAccessADEnable_";
+ public static final String CONFIG_AD_METHOD = "authInfoAccessADMethod_";
+ public static final String CONFIG_AD_LOCATIONTYPE = "authInfoAccessADLocationType_";
+ public static final String CONFIG_AD_LOCATION = "authInfoAccessADLocation_";
+
+ public static final String VAL_CRITICAL = "authInfoAccessCritical";
+ public static final String VAL_GENERAL_NAMES = "authInfoAccessGeneralNames";
+
+ private static final String AD_METHOD = "Method";
+ private static final String AD_LOCATION_TYPE = "Location Type";
+ private static final String AD_LOCATION = "Location";
+ private static final String AD_ENABLE = "Enable";
+
+ private static final int DEF_NUM_AD = 1;
+ private static final int MAX_NUM_AD = 100;
+
+ public AuthInfoAccessExtDefault() {
+ super();
+ }
+
+ protected int getNumAds() {
+ int num = DEF_NUM_AD;
+ String numAds = getConfig(CONFIG_NUM_ADS);
+
+ if (numAds != null) {
+ try {
+ num = Integer.parseInt(numAds);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num > MAX_NUM_AD) {
+ num = DEF_NUM_AD;
+ }
+
+ return num;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_ADS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_AD || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ADS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ADS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ //refesh our config name list
+
+ super.refreshConfigAndValueNames();
+ mConfigNames.removeAllElements();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_GENERAL_NAMES);
+
+ // register configuration names bases on num ads
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumAds();
+
+ addConfigName(CONFIG_NUM_ADS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_AD_METHOD + i);
+ addConfigName(CONFIG_AD_LOCATIONTYPE + i);
+ addConfigName(CONFIG_AD_LOCATION + i);
+ addConfigName(CONFIG_AD_ENABLE + i);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_AD_METHOD)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_METHOD"));
+ } else if (name.startsWith(CONFIG_AD_LOCATIONTYPE)) {
+ return new Descriptor(IDescriptor.CHOICE, "RFC822Name,DNSName,DirectoryName,EDIPartyName,URIName,IPAddress,OIDName",
+ "URIName",
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_LOCATIONTYPE"));
+ } else if (name.startsWith(CONFIG_AD_LOCATION)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_LOCATION"));
+ } else if (name.startsWith(CONFIG_AD_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_ADS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_ADS"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GENERAL_NAMES"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ AuthInfoAccessExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+
+ AuthInfoAccessExtension a = new AuthInfoAccessExtension(false);
+ ObjectIdentifier oid = a.getExtensionId();
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null)
+ {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ return;
+ }
+ boolean critical = ext.isCritical();
+
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ ext = new AuthInfoAccessExtension(critical);
+ String method = null;
+ String locationType = null;
+ String location = null;
+ String enable = null;
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(AD_METHOD)) {
+ method = nvps.getValue(name1);
+ } else if (name1.equals(AD_LOCATION_TYPE)) {
+ locationType = nvps.getValue(name1);
+ } else if (name1.equals(AD_LOCATION)) {
+ location = nvps.getValue(name1);
+ } else if (name1.equals(AD_ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable != null && enable.equals("true")) {
+ GeneralName gn = null;
+
+ if (locationType != null || location != null) {
+ GeneralNameInterface interface1 = parseGeneralName(locationType + ":" + location);
+ if (interface1 == null)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", locationType));
+ gn = new GeneralName(interface1);
+ }
+
+ if (method != null) {
+ try {
+ ext.addAccessDescription(new ObjectIdentifier(method), gn);
+ } catch (NumberFormatException ee) {
+ CMS.debug("AuthInfoAccessExtDefault: "+ee.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_DEF_AIA_OID", method));
+ }
+ }
+ }
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(ext.getExtensionId().toString(), ext, info);
+ } catch (IOException e) {
+ CMS.debug("AuthInfoAccessExtDefault: " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("AuthInfoAccessExtDefault: " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ AuthInfoAccessExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ AuthInfoAccessExtension a = new AuthInfoAccessExtension(false);
+ ObjectIdentifier oid = a.getExtensionId();
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ CMS.debug("AuthInfoAccessExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+
+ ext = (AuthInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ int num = getNumAds();
+
+ CMS.debug("AuthInfoAccess num=" + num);
+ Vector recs = new Vector();
+
+ for (int i = 0; i < num; i++) {
+ NameValuePairs np = new NameValuePairs();
+ AccessDescription des = null;
+
+ if (i < ext.numberOfAccessDescription()) {
+ des = ext.getAccessDescription(i);
+ }
+ if (des == null) {
+ np.add(AD_METHOD, "");
+ np.add(AD_LOCATION_TYPE, "");
+ np.add(AD_LOCATION, "");
+ np.add(AD_ENABLE, "false");
+ } else {
+ ObjectIdentifier methodOid = des.getMethod();
+ GeneralName gn = des.getLocation();
+
+ np.add(AD_METHOD, methodOid.toString());
+ np.add(AD_LOCATION_TYPE, getGeneralNameType(gn));
+ np.add(AD_LOCATION, getGeneralNameValue(gn));
+ np.add(AD_ENABLE, "true");
+ }
+ recs.addElement(np);
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer ads = new StringBuffer();
+ String numAds = getConfig(CONFIG_NUM_ADS);
+ int num = getNumAds();
+
+ for (int i = 0; i < num; i++) {
+ ads.append("Record #");
+ ads.append(i);
+ ads.append("{");
+ ads.append(AD_METHOD + ":");
+ ads.append(getConfig(CONFIG_AD_METHOD + i));
+ ads.append(",");
+ ads.append(AD_LOCATION_TYPE + ":");
+ ads.append(getConfig(CONFIG_AD_LOCATIONTYPE + i));
+ ads.append(",");
+ ads.append(AD_LOCATION + ":");
+ ads.append(getConfig(CONFIG_AD_LOCATION + i));
+ ads.append(",");
+ ads.append(AD_ENABLE + ":");
+ ads.append(getConfig(CONFIG_AD_ENABLE + i));
+ ads.append("}");
+ }
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_AIA_TEXT",
+ getConfig(CONFIG_CRITICAL), ads.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ AuthInfoAccessExtension ext = createExtension();
+
+ addExtension(ext.getExtensionId().toString(), ext, info);
+ }
+
+ public AuthInfoAccessExtension createExtension() {
+ AuthInfoAccessExtension ext = null;
+ int num = getNumAds();
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ ext = new AuthInfoAccessExtension(critical);
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_AD_ENABLE + i);
+ if (enable != null && enable.equals("true")) {
+ CMS.debug("AuthInfoAccess: createExtension i=" + i);
+ String method = getConfig(CONFIG_AD_METHOD + i);
+ String locationType = getConfig(CONFIG_AD_LOCATIONTYPE + i);
+ if (locationType == null || locationType.length() == 0)
+ locationType = "URIName";
+ String location = getConfig(CONFIG_AD_LOCATION + i);
+
+ if (location == null || location.equals("")) {
+ if (method.equals("1.3.6.1.5.5.7.48.1")) {
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ if (hostname != null && port != null)
+ // location = "http://"+hostname+":"+port+"/ocsp/ee/ocsp";
+ location = "http://"+hostname+":"+port+"/ca/ocsp";
+ }
+ }
+
+ String s = locationType + ":" + location;
+ GeneralNameInterface gn = parseGeneralName(s);
+ if (gn != null) {
+ ext.addAccessDescription(new ObjectIdentifier(method),
+ new GeneralName(gn));
+ }
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("AuthInfoAccessExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+}
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
new file mode 100644
index 000000000..a2a2b9da0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
@@ -0,0 +1,152 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy that
+ * populates subject name based on the attribute values
+ * in the authentication token (AuthToken) object.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthTokenSubjectNameDefault extends EnrollDefault {
+
+ public static final String VAL_NAME = "name";
+
+ public AuthTokenSubjectNameDefault() {
+ super();
+ addValueName(VAL_NAME);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ 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));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ 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));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("AuthTokenSubjectNameDefault: setValue " +
+ e.toString());
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(locale,
+ "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null)
+ throw new EPropertyException("Invalid name " + name);
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("AuthTokenSubjectNameDefault: getValue " +
+ e.toString());
+ }
+ throw new EPropertyException(CMS.getUserMessage(locale,
+ "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(locale,
+ "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_AUTHTOKEN_SUBJECT_NAME");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+
+ // authenticate the subject name and populate it
+ // to the certinfo
+ try {
+ 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
+ CMS.debug("AuthTokenSubjectNameDefault: " + e.toString());
+ throw new EProfileException(CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
new file mode 100644
index 000000000..520e7c0a6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
@@ -0,0 +1,191 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Authority Key Identifier extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthorityKeyIdentifierExtDefault extends CAEnrollDefault {
+
+ public static final String VAL_CRITICAL = "critical";
+ public static final String VAL_KEY_ID = "keyid";
+
+ public AuthorityKeyIdentifierExtDefault() {
+ super();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_KEY_ID);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_KEY_ID)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_KEY_ID"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ // do nothing for read only value
+ } else if (name.equals(VAL_KEY_ID)) {
+ // do nothing for read only value
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+
+ AuthorityKeyIdentifierExtension ext =
+ (AuthorityKeyIdentifierExtension) getExtension(
+ PKIXExtensions.AuthorityKey_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ CMS.debug("BasicConstraintsExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (AuthorityKeyIdentifierExtension) getExtension(
+ PKIXExtensions.AuthorityKey_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_KEY_ID)) {
+ ext =
+ (AuthorityKeyIdentifierExtension) getExtension(
+ PKIXExtensions.AuthorityKey_Id.toString(), info);
+
+ if (ext == null) {
+ // do something here
+ return "";
+ }
+ KeyIdentifier kid = null;
+
+ try {
+ kid = (KeyIdentifier)
+ ext.get(AuthorityKeyIdentifierExtension.KEY_ID);
+ } catch (IOException e) {
+ //
+ CMS.debug(e.toString());
+ }
+ if (kid == null)
+ return "";
+ return toHexString(kid.getIdentifier());
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_AKI_EXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ AuthorityKeyIdentifierExtension ext = createExtension(info);
+
+ addExtension(PKIXExtensions.AuthorityKey_Id.toString(), ext, info);
+ }
+
+ public AuthorityKeyIdentifierExtension createExtension(X509CertInfo info) {
+ KeyIdentifier kid = null;
+ String localKey = getConfig("localKey");
+ if (localKey != null && localKey.equals("true")) {
+ kid = getKeyIdentifier(info);
+ } else {
+ kid = getCAKeyIdentifier();
+ }
+
+ if (kid == null)
+ return null;
+ AuthorityKeyIdentifierExtension ext = null;
+
+ try {
+ ext = new AuthorityKeyIdentifierExtension(false, kid, null, null);
+ } catch (IOException e) {
+ CMS.debug("AuthorityKeyIdentifierExtDefault: createExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java
new file mode 100644
index 000000000..49b929fa1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java
@@ -0,0 +1,96 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that automatically assign request to agent.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AutoAssignDefault extends EnrollDefault {
+
+ public static final String CONFIG_ASSIGN_TO = "assignTo";
+
+ public AutoAssignDefault() {
+ super();
+ addConfigName(CONFIG_ASSIGN_TO);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_ASSIGN_TO)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, "admin", CMS.getUserMessage(locale,
+ "CMS_PROFILE_AUTO_ASSIGN"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ return null;
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_AUTO_ASSIGN",
+ getConfig(CONFIG_ASSIGN_TO));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ try {
+ request.setRequestOwner(
+ mapPattern(request, getConfig(CONFIG_ASSIGN_TO)));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("AutoAssignDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java
new file mode 100644
index 000000000..0995a142c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java
@@ -0,0 +1,301 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Basic Constraint extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class BasicConstraintsExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "basicConstraintsCritical";
+ public static final String CONFIG_IS_CA = "basicConstraintsIsCA";
+ public static final String CONFIG_PATH_LEN = "basicConstraintsPathLen";
+
+ public static final String VAL_CRITICAL = "basicConstraintsCritical";
+ public static final String VAL_IS_CA = "basicConstraintsIsCA";
+ public static final String VAL_PATH_LEN = "basicConstraintsPathLen";
+
+ public BasicConstraintsExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_IS_CA);
+ addValueName(VAL_PATH_LEN);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_IS_CA);
+ addConfigName(CONFIG_PATH_LEN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_IS_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_IS_CA"));
+ } else if (name.equals(CONFIG_PATH_LEN)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "-1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_PATH_LEN"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_IS_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_IS_CA"));
+ } else if (name.equals(VAL_PATH_LEN)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "-1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_PATH_LEN"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ BasicConstraintsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if(ext == null)
+ {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_IS_CA)) {
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean isCA = Boolean.valueOf(value);
+
+ ext.set(BasicConstraintsExtension.IS_CA, isCA);
+ } else if (name.equals(VAL_PATH_LEN)) {
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if(ext == null) {
+ return;
+ }
+ Integer pathLen = Integer.valueOf(value);
+
+ ext.set(BasicConstraintsExtension.PATH_LEN, pathLen);
+ } else {
+ throw new EPropertyException("Invalid name " + name);
+ }
+ replaceExtension(PKIXExtensions.BasicConstraints_Id.toString(),
+ ext, info);
+ } catch (IOException e) {
+ CMS.debug("BasicConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("BasicConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ try {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ BasicConstraintsExtension ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if(ext == null)
+ {
+ CMS.debug("BasicConstraintsExtDefault: getValue ext is null, populating a new one ");
+
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ CMS.debug("BasicConstraintsExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_IS_CA)) {
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ Boolean isCA = (Boolean) ext.get(BasicConstraintsExtension.IS_CA);
+
+ return isCA.toString();
+ } else if (name.equals(VAL_PATH_LEN)) {
+ ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ Integer pathLen = (Integer)
+ ext.get(BasicConstraintsExtension.PATH_LEN);
+
+
+ String pLen = null;
+
+ pLen = pathLen.toString();
+ if(pLen.equals("-2"))
+ {
+ //This is done for bug 621700. Profile constraints actually checks for -1
+ //The low level security class for some reason sets this to -2
+ //This will allow the request to be approved successfuly by the agent.
+
+ pLen = "-1";
+
+ }
+
+ CMS.debug("BasicConstriantsExtDefault getValue(pLen) " + pLen);
+
+ return pLen;
+
+
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (IOException e) {
+ CMS.debug("BasicConstraintsExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_IS_CA),
+ getConfig(CONFIG_PATH_LEN)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_BASIC_CONSTRAINTS_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ BasicConstraintsExtension ext = createExtension();
+
+ addExtension(PKIXExtensions.BasicConstraints_Id.toString(), ext,
+ info);
+ }
+
+ public BasicConstraintsExtension createExtension() {
+ BasicConstraintsExtension ext = null;
+
+ boolean critical = Boolean.valueOf(getConfig(CONFIG_CRITICAL)).booleanValue();
+ boolean isCA = Boolean.valueOf(getConfig(CONFIG_IS_CA)).booleanValue();
+ String pathLenStr = getConfig(CONFIG_PATH_LEN);
+
+ int pathLen = -2;
+
+
+ if(!pathLenStr.equals("") ) {
+
+ pathLen = Integer.valueOf(pathLenStr).intValue();
+ }
+
+ try {
+ ext = new BasicConstraintsExtension(isCA, critical, pathLen);
+ } catch (Exception e) {
+ CMS.debug("BasicConstraintsExtDefault: createExtension " +
+ e.toString());
+ return null;
+ }
+ ext.setCritical(critical);
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java
new file mode 100644
index 000000000..907a5830c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java
@@ -0,0 +1,106 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+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.ca.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * This class implements an abstract CA specific
+ * Enrollment default. This policy can only be
+ * used with CA subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class CAEnrollDefault extends EnrollDefault {
+ public CAEnrollDefault() {
+ }
+
+ public KeyIdentifier getKeyIdentifier(X509CertInfo info) {
+ try {
+ CertificateX509Key ckey = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ X509Key key = (X509Key) ckey.get(CertificateX509Key.KEY);
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getKey());
+ byte[] hash = md.digest();
+
+ return new KeyIdentifier(hash);
+ } catch (IOException e) {
+ CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
+ e.toString());
+ } catch (CertificateException e) {
+ CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
+ e.toString());
+ } catch (NoSuchAlgorithmException e) {
+ CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
+ e.toString());
+ }
+ return null;
+ }
+
+ public KeyIdentifier getCAKeyIdentifier() {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ X509CertImpl caCert = ca.getCACert();
+ if (caCert == null) {
+ // during configuration, we dont have the CA certificate
+ return null;
+ }
+ X509Key key = (X509Key) caCert.getPublicKey();
+
+ SubjectKeyIdentifierExtension subjKeyIdExt =
+ (SubjectKeyIdentifierExtension)
+ caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString());
+ if (subjKeyIdExt != null) {
+ try {
+ KeyIdentifier keyId = (KeyIdentifier) subjKeyIdExt.get(
+ SubjectKeyIdentifierExtension.KEY_ID);
+ return keyId;
+ } catch (IOException e) {
+ }
+ }
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getKey());
+ byte[] hash = md.digest();
+
+ return new KeyIdentifier(hash);
+ } catch (NoSuchAlgorithmException e) {
+ CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
+ e.toString());
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java
new file mode 100644
index 000000000..f298238b0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java
@@ -0,0 +1,342 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+import com.netscape.certsrv.ca.*;
+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 com.netscape.cms.profile.common.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements a CA signing cert enrollment default policy
+ * that populates a server-side configurable validity
+ * into the certificate template.
+ * It allows an agent to bypass the CA's signing cert's expiration constraint
+ */
+public class CAValidityDefault extends EnrollDefault {
+ public static final String CONFIG_RANGE = "range";
+ public static final String CONFIG_START_TIME = "startTime";
+ public static final String CONFIG_BYPASS_CA_NOTAFTER= "bypassCAnotafter";
+
+ public static final String VAL_NOT_BEFORE = "notBefore";
+ public static final String VAL_NOT_AFTER = "notAfter";
+ public static final String VAL_BYPASS_CA_NOTAFTER= "bypassCAnotafter";
+
+ public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+ private long mDefault = 86400000; // 1 days
+ public ICertificateAuthority mCA = null;
+
+ public CAValidityDefault() {
+ super();
+ addConfigName(CONFIG_RANGE);
+ addConfigName(CONFIG_START_TIME);
+ addConfigName(CONFIG_BYPASS_CA_NOTAFTER);
+
+ addValueName(VAL_NOT_BEFORE);
+ addValueName(VAL_NOT_AFTER);
+ addValueName(VAL_BYPASS_CA_NOTAFTER);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ mCA = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (name.equals(CONFIG_RANGE)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_RANGE));
+ }
+ } else if (name.equals(CONFIG_START_TIME)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_START_TIME));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_RANGE)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ "2922", /* 8 years */
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_VALIDITY_RANGE"));
+ } else if (name.equals(CONFIG_START_TIME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ "60", /* 1 minute */
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_VALIDITY_START_TIME"));
+ } else if (name.equals(CONFIG_BYPASS_CA_NOTAFTER)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_BYPASS_CA_NOTAFTER"));
+
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NOT_BEFORE)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_BEFORE"));
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_AFTER"));
+ } else if (name.equals(VAL_BYPASS_CA_NOTAFTER)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_BYPASS_CA_NOTAFTER"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (value == null || value.equals("")) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ CMS.debug("CAValidityDefault: setValue name= "+ name);
+
+ if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ validity.set(CertificateValidity.NOT_BEFORE,
+ date);
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ validity.set(CertificateValidity.NOT_AFTER,
+ date);
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_BYPASS_CA_NOTAFTER)) {
+ boolean bypassCAvalidity = Boolean.valueOf(value).booleanValue();
+ CMS.debug("CAValidityDefault: setValue: bypassCAvalidity="+ bypassCAvalidity);
+
+ BasicConstraintsExtension ext = (BasicConstraintsExtension)
+ getExtension(PKIXExtensions.BasicConstraints_Id.toString(), info);
+
+ if(ext == null) {
+ CMS.debug("CAValidityDefault: setValue: this default cannot be applied to non-CA cert.");
+ return;
+ }
+ try {
+ Boolean isCA = (Boolean) ext.get(BasicConstraintsExtension.IS_CA);
+ if(isCA.booleanValue() != true) {
+ CMS.debug("CAValidityDefault: setValue: this default cannot be aplied to non-CA cert.");
+ return;
+ }
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: setValue: this default cannot be aplied to non-CA cert."+ e.toString());
+ return;
+ }
+
+ CertificateValidity validity = null;
+ Date notAfter = null;
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ notAfter = (Date) validity.get(CertificateValidity.NOT_AFTER);
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ // not to exceed CA's expiration
+ Date caNotAfter =
+ mCA.getSigningUnit().getCertImpl().getNotAfter();
+
+ if (notAfter.after(caNotAfter)) {
+ if (bypassCAvalidity == false) {
+ notAfter = caNotAfter;
+ CMS.debug("CAValidityDefault: setValue: bypassCAvalidity off. reset notAfter to caNotAfter. reset ");
+ } else {
+ CMS.debug("CAValidityDefault: setValue: bypassCAvalidity on. notAfter is after caNotAfter. no reset");
+ }
+ }
+ try {
+ validity.set(CertificateValidity.NOT_AFTER,
+ notAfter);
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+
+ if (name == null)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+
+ CMS.debug("CAValidityDefault: getValue: name= "+ name);
+ if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ return formatter.format((Date)
+ validity.get(CertificateValidity.NOT_BEFORE));
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ return formatter.format((Date)
+ validity.get(CertificateValidity.NOT_AFTER));
+ } catch (Exception e) {
+ CMS.debug("CAValidityDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_BYPASS_CA_NOTAFTER)) {
+ return "false";
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_RANGE),
+ getConfig(CONFIG_BYPASS_CA_NOTAFTER)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_VALIDITY", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+
+ // always + 60 seconds
+ String startTimeStr = getConfig(CONFIG_START_TIME);
+ try {
+ startTimeStr = mapPattern(request, startTimeStr);
+ } catch (IOException e) {
+ CMS.debug("CAValidityDefault: populate " + e.toString());
+ }
+
+ if (startTimeStr == null || startTimeStr.equals("")) {
+ startTimeStr = "60";
+ }
+ int startTime = Integer.parseInt(startTimeStr);
+ Date notBefore = new Date(CMS.getCurrentDate().getTime() + (1000 * startTime));
+ long notAfterVal = 0;
+
+ try {
+ String rangeStr = getConfig(CONFIG_RANGE);
+ rangeStr = mapPattern(request, rangeStr);
+ notAfterVal = notBefore.getTime() +
+ (mDefault * Integer.parseInt(rangeStr));
+ } catch (Exception e) {
+ // configured value is not correct
+ CMS.debug("CAValidityDefault: populate " + e.toString());
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_INVALID_PROPERTY", CONFIG_RANGE));
+ }
+ Date notAfter = new Date(notAfterVal);
+
+ CertificateValidity validity =
+ new CertificateValidity(notBefore, notAfter);
+
+ try {
+ info.set(X509CertInfo.VALIDITY, validity);
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("CAValidityDefault: populate " + e.toString());
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_INVALID_PROPERTY", X509CertInfo.VALIDITY));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java
new file mode 100644
index 000000000..d0a42a816
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java
@@ -0,0 +1,696 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a CRL Distribution points extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CRLDistributionPointsExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "crlDistPointsCritical";
+ public static final String CONFIG_NUM_POINTS = "crlDistPointsNum";
+ public static final String CONFIG_POINT_TYPE = "crlDistPointsPointType_";
+ public static final String CONFIG_POINT_NAME = "crlDistPointsPointName_";
+ public static final String CONFIG_REASONS = "crlDistPointsReasons_";
+ public static final String CONFIG_ISSUER_TYPE = "crlDistPointsIssuerType_";
+ public static final String CONFIG_ISSUER_NAME = "crlDistPointsIssuerName_";
+ public static final String CONFIG_ENABLE = "crlDistPointsEnable_";
+
+ public static final String VAL_CRITICAL = "crlDistPointsCritical";
+ public static final String VAL_CRL_DISTRIBUTION_POINTS = "crlDistPointsValue";
+
+ private static final String REASONS = "Reasons";
+ private static final String POINT_TYPE = "Point Type";
+ private static final String POINT_NAME = "Point Name";
+ private static final String ISSUER_TYPE = "Issuer Type";
+ private static final String ISSUER_NAME = "Issuer Name";
+ private static final String ENABLE = "Enable";
+
+ private static final String RELATIVETOISSUER = "RelativeToIssuer";
+
+ private static final int DEF_NUM_POINTS = 1;
+ private static final int MAX_NUM_POINTS = 100;
+
+ public CRLDistributionPointsExtDefault() {
+ super();
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_POINTS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_POINTS || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POINTS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POINTS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_CRL_DISTRIBUTION_POINTS);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumPoints();
+
+ addConfigName(CONFIG_NUM_POINTS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_POINT_TYPE + i);
+ addConfigName(CONFIG_POINT_NAME + i);
+ addConfigName(CONFIG_REASONS + i);
+ addConfigName(CONFIG_ISSUER_TYPE + i);
+ addConfigName(CONFIG_ISSUER_NAME + i);
+ addConfigName(CONFIG_ENABLE + i);
+ }
+ }
+
+ protected int getNumPoints() {
+ int num = DEF_NUM_POINTS;
+ String val = getConfig(CONFIG_NUM_POINTS);
+
+ if (val != null) {
+ try {
+ num = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_POINTS)
+ num = DEF_NUM_POINTS;
+
+ return num;
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_POINT_TYPE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POINT_TYPE"));
+ } else if (name.startsWith(CONFIG_POINT_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POINT_NAME"));
+ } else if (name.startsWith(CONFIG_REASONS)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REASONS"));
+ } else if (name.startsWith(CONFIG_ISSUER_TYPE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ISSUER_TYPE"));
+ } else if (name.startsWith(CONFIG_ISSUER_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ISSUER_NAME"));
+ } else if (name.startsWith(CONFIG_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_POINTS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_DIST_POINTS"));
+
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRL_DISTRIBUTION_POINTS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ CRLDistributionPointsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+
+ if(ext == null) {
+ populate(locale,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null)
+ {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+
+ if(ext == null)
+ {
+ return;
+ }
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+ int i = 0;
+
+ for (; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+ String pointType = null;
+ String pointValue = null;
+ String issuerType = null;
+ String issuerValue = null;
+ String enable = null;
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(REASONS)) {
+ addReasons(locale, cdp, REASONS, nvps.getValue(name1));
+ } else if (name1.equals(POINT_TYPE)) {
+ pointType = nvps.getValue(name1);
+ } else if (name1.equals(POINT_NAME)) {
+ pointValue = nvps.getValue(name1);
+ } else if (name1.equals(ISSUER_TYPE)) {
+ issuerType = nvps.getValue(name1);
+ } else if (name1.equals(ISSUER_NAME)) {
+ issuerValue = nvps.getValue(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(locale, cdp, pointType, pointValue);
+ if (issuerType != null)
+ addIssuer(locale, cdp, issuerType, issuerValue);
+
+ // this is the first distribution point
+ if (i == 0) {
+ ext = new CRLDistributionPointsExtension(cdp);
+ ext.setCritical(critical);
+ } else {
+ ext.addPoint(cdp);
+ }
+ }
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("CRLDistributionPointsExtDefault: setValue " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ private void addCRLPoint(Locale locale, CRLDistributionPoint cdp, String type,
+ String value) throws EPropertyException {
+ try {
+ if (value == null || value.length() == 0)
+ return;
+
+ if (type.equals(RELATIVETOISSUER)) {
+ cdp.setRelativeName(new RDN(value));
+ } else if (isGeneralNameType(type)) {
+ GeneralNames gen = new GeneralNames();
+ gen.addElement(parseGeneralName(type,value));
+ cdp.setFullName(gen);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ } catch (IOException e) {
+ CMS.debug("CRLDistributionPointsExtDefault: addCRLPoint " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ } catch (GeneralNamesException e) {
+ CMS.debug("CRLDistributionPointsExtDefault: addCRLPoint " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ }
+
+ private void addIssuer(Locale locale, CRLDistributionPoint cdp, String type,
+ String value) throws EPropertyException {
+ if (value == null || value.length() == 0)
+ return;
+ try {
+ if (isGeneralNameType(type)) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(parseGeneralName(type, value));
+ cdp.setCRLIssuer(gen);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ } catch (IOException e) {
+ CMS.debug("CRLDistributionPointsExtDefault: addIssuer " +
+ e.toString());
+ } catch (GeneralNamesException e) {
+ CMS.debug("CRLDistributionPointsExtDefault: addIssuer " +
+ e.toString());
+ }
+ }
+
+ private void addReasons(Locale locale, CRLDistributionPoint cdp, String type,
+ String value) throws EPropertyException {
+ if (value == null || value.length() == 0)
+ return;
+ if (type.equals(REASONS)) {
+ if (value != null && !value.equals("")) {
+ StringTokenizer st = new StringTokenizer(value, ", \t");
+ byte reasonBits = 0;
+
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ Reason r = Reason.fromString(s);
+
+ if (r == null) {
+ CMS.debug("CRLDistributeionPointsExtDefault: addReasons Unknown reason: " + s);
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", s));
+ } else {
+ reasonBits |= r.getBitMask();
+ }
+ }
+
+ if (reasonBits != 0) {
+ BitArray ba = new BitArray(8, new byte[] {reasonBits}
+ );
+
+ cdp.setReasons(ba);
+ }
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ CRLDistributionPointsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+
+ if(ext == null)
+ {
+ try {
+ populate(locale,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ ext = (CRLDistributionPointsExtension)
+ getExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ StringBuffer sb = new StringBuffer();
+
+ Vector recs = new Vector();
+ int num = getNumPoints();
+
+ for (int i = 0; i < num; i++) {
+ NameValuePairs pairs = null;
+
+ if (i < ext.getNumPoints()) {
+ CRLDistributionPoint p = ext.getPointAt(i);
+ GeneralNames gns = p.getFullName();
+
+ pairs = buildGeneralNames(gns, p);
+ recs.addElement(pairs);
+ } else {
+ pairs = buildEmptyGeneralNames();
+ recs.addElement(pairs);
+ }
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ protected NameValuePairs buildEmptyGeneralNames() {
+ NameValuePairs pairs = new NameValuePairs();
+
+ pairs.add(POINT_TYPE, "");
+ pairs.add(POINT_NAME, "");
+ pairs.add(REASONS, "");
+ pairs.add(ISSUER_TYPE, "");
+ pairs.add(ISSUER_NAME, "");
+ pairs.add(ENABLE, "false");
+ return pairs;
+ }
+
+ protected NameValuePairs buildGeneralNames(GeneralNames gns, CRLDistributionPoint p)
+ throws EPropertyException {
+
+ NameValuePairs pairs = new NameValuePairs();
+
+ RDN rdn = null;
+ boolean hasFullName = false;
+
+ pairs.add(ENABLE, "true");
+ if (gns == null) {
+ rdn = p.getRelativeName();
+ if (rdn != null) {
+ hasFullName = true;
+ pairs.add(POINT_TYPE, RELATIVETOISSUER);
+ pairs.add(POINT_NAME, rdn.toString());
+ } else {
+ pairs.add(POINT_TYPE, "");
+ pairs.add(POINT_NAME, "");
+ }
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+ int type = gn.getType();
+
+ pairs.add(POINT_TYPE, getGeneralNameType(gn));
+ pairs.add(POINT_NAME, getGeneralNameValue(gn));
+ }
+ }
+
+ if (!hasFullName) {
+ pairs.add(POINT_TYPE, GN_DIRECTORY_NAME);
+ pairs.add(POINT_NAME, "");
+ }
+
+ BitArray reasons = p.getReasons();
+ String s = convertBitArrayToReasonNames(reasons);
+
+ if (s.length() > 0) {
+ pairs.add(REASONS, s);
+ } else {
+ pairs.add(REASONS, "");
+ }
+
+ gns = p.getCRLIssuer();
+
+ if (gns == null) {
+ pairs.add(ISSUER_TYPE, GN_DIRECTORY_NAME);
+ pairs.add(ISSUER_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+ int type = gn.getType();
+
+ pairs.add(ISSUER_TYPE, getGeneralNameType(gn));
+ pairs.add(ISSUER_NAME, getGeneralNameValue(gn));
+ }
+ }
+ return pairs;
+ }
+
+ private String convertBitArrayToReasonNames(BitArray reasons) {
+ StringBuffer sb = new StringBuffer();
+
+ if (reasons != null) {
+ byte[] b = reasons.toByteArray();
+ Reason[] reasonArray = Reason.bitArrayToReasonArray(b);
+
+ for (int i = 0; i < reasonArray.length; i++) {
+ if (sb.length() > 0)
+ sb.append(",");
+ sb.append(reasonArray[i].getName());
+ }
+ }
+
+ return sb.toString();
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ int num = getNumPoints();
+
+ for (int i = 0; i < num; i++) {
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(POINT_TYPE + ":");
+ sb.append(getConfig(CONFIG_POINT_TYPE + i));
+ sb.append(",");
+ sb.append(POINT_NAME + ":");
+ sb.append(getConfig(CONFIG_POINT_NAME + i));
+ sb.append(",");
+ sb.append(REASONS + ":");
+ sb.append(getConfig(CONFIG_REASONS + i));
+ sb.append(",");
+ sb.append(ISSUER_TYPE + ":");
+ sb.append(getConfig(CONFIG_ISSUER_TYPE + i));
+ sb.append(",");
+ sb.append(ISSUER_NAME + ":");
+ sb.append(getConfig(CONFIG_ISSUER_NAME + i));
+ sb.append(",");
+ sb.append(ENABLE + ":");
+ sb.append(getConfig(CONFIG_ENABLE + i));
+ sb.append("}");
+ }
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_CRL_DIST_POINTS_EXT",
+ getConfig(CONFIG_CRITICAL),
+ sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ private void populate(Locale locale, X509CertInfo info)
+ throws EProfileException {
+ CRLDistributionPointsExtension ext = createExtension(locale);
+
+ if (ext == null)
+ return;
+ addExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ ext, info);
+ }
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CRLDistributionPointsExtension ext = createExtension(request);
+
+ if (ext == null)
+ return;
+ addExtension(PKIXExtensions.CRLDistributionPoints_Id.toString(),
+ ext, info);
+ }
+
+ public CRLDistributionPointsExtension createExtension(IRequest request) {
+ CRLDistributionPointsExtension ext = null;
+ int num = 0;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ num = getNumPoints();
+ for (int i = 0; i < num; i++) {
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ String enable = getConfig(CONFIG_ENABLE + i);
+ String pointType = getConfig(CONFIG_POINT_TYPE + i);
+ String pointName = getConfig(CONFIG_POINT_NAME + i);
+ String reasons = getConfig(CONFIG_REASONS + i);
+ String issuerType = getConfig(CONFIG_ISSUER_TYPE + i);
+ String issuerName = getConfig(CONFIG_ISSUER_NAME + i);
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(getLocale(request), cdp, pointType, pointName);
+ if (issuerType != null)
+ addIssuer(getLocale(request), cdp, issuerType, issuerName);
+ if (reasons != null)
+ addReasons(getLocale(request), cdp, REASONS, reasons);
+
+ if (i == 0) {
+ ext = new CRLDistributionPointsExtension(cdp);
+ ext.setCritical(critical);
+ } else {
+ ext.addPoint(cdp);
+ }
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("CRLDistribtionPointsExtDefault: createExtension " +
+ e.toString());
+ CMS.debug(e);
+ }
+
+ return ext;
+ }
+
+ private CRLDistributionPointsExtension createExtension(Locale locale) {
+ CRLDistributionPointsExtension ext = null;
+ int num = 0;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ num = getNumPoints();
+ for (int i = 0; i < num; i++) {
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ String enable = getConfig(CONFIG_ENABLE + i);
+ String pointType = getConfig(CONFIG_POINT_TYPE + i);
+ String pointName = getConfig(CONFIG_POINT_NAME + i);
+ String reasons = getConfig(CONFIG_REASONS + i);
+ String issuerType = getConfig(CONFIG_ISSUER_TYPE + i);
+ String issuerName = getConfig(CONFIG_ISSUER_NAME + i);
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(locale, cdp, pointType, pointName);
+ if (issuerType != null)
+ addIssuer(locale, cdp, issuerType, issuerName);
+ addReasons(locale, cdp, REASONS, reasons);
+
+ if (i == 0) {
+ ext = new CRLDistributionPointsExtension(cdp);
+ ext.setCritical(critical);
+ } else {
+ ext.addPoint(cdp);
+ }
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("CRLDistribtionPointsExtDefault: createExtension " +
+ e.toString());
+ CMS.debug(e);
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java
new file mode 100644
index 000000000..7cb5e72b1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java
@@ -0,0 +1,760 @@
+
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a policy mappings extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertificatePoliciesExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "Critical";
+ public static final String CONFIG_PREFIX = "PoliciesExt.certPolicy";
+ public static final String CONFIG_PREFIX1 = "PolicyQualifiers";
+ public static final String CONFIG_POLICY_ENABLE = "enable";
+ public static final String CONFIG_POLICY_NUM = "PoliciesExt.num";
+ public static final String CONFIG_POLICY_ID = "policyId";
+ public static final String CONFIG_POLICY_QUALIFIERS_NUM = "PolicyQualifiers.num";
+ public static final String CONFIG_CPSURI_ENABLE = "CPSURI.enable";
+ public static final String CONFIG_USERNOTICE_ENABLE = "usernotice.enable";
+ public static final String CONFIG_CPSURI_VALUE = "CPSURI.value";
+ public static final String CONFIG_USERNOTICE_ORG = "usernotice.noticeReference.organization";
+ public static final String CONFIG_USERNOTICE_NUMBERS = "usernotice.noticeReference.noticeNumbers";
+ public static final String CONFIG_USERNOTICE_TEXT = "usernotice.explicitText.value";
+
+ public static final String VAL_CRITICAL = "Critical";
+ public static final String VAL_POLICY_QUALIFIERS = "policyQualifiers";
+
+ private static final String SEPARATOR = ".";
+ private static final int DEF_NUM_POLICIES = 5;
+ private static final int DEF_NUM_QUALIFIERS = 1;
+ private static final int MAX_NUM_POLICIES = 20;
+ private static final String POLICY_ID_ENABLE = "Enable";
+ private static final String POLICY_ID = "Policy Id";
+ private static final String POLICY_QUALIFIER_CPSURI_ENABLE = "CPSuri Enable";
+ private static final String POLICY_QUALIFIER_USERNOTICE_ENABLE = "UserNotice Enable";
+ private static final String USERNOTICE_REF_ORG = "UserNoticeReference Organization";
+ private static final String USERNOTICE_REF_NUMBERS = "UserNoticeReference Numbers";
+ private static final String USERNOTICE_EXPLICIT_TEXT = "UserNoticeReference Explicit Text";
+ private static final String CPSURI = "CPS uri";
+
+ public CertificatePoliciesExtDefault() {
+ super();
+ }
+
+ protected int getNumPolicies() {
+ int num = DEF_NUM_POLICIES;
+ String numPolicies = getConfig(CONFIG_POLICY_NUM);
+
+ if (numPolicies != null) {
+ try {
+ num = Integer.parseInt(numPolicies);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_POLICIES)
+ num = DEF_NUM_POLICIES;
+ return num;
+ }
+
+ protected int getNumQualifiers() {
+ int num = DEF_NUM_QUALIFIERS;
+ String numQualifiers = getConfig(CONFIG_POLICY_QUALIFIERS_NUM);
+ if (numQualifiers != null) {
+ try {
+ num = Integer.parseInt(numQualifiers);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return num;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ refreshConfigAndValueNames();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_POLICY_NUM)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_POLICIES || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_POLICY_NUM));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_POLICY_NUM));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_POLICY_QUALIFIERS);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumPolicies();
+ int numQualifiers = getNumQualifiers();
+
+ addConfigName(CONFIG_POLICY_NUM);
+
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ID);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ENABLE);
+ for (int j=0; j<numQualifiers; j++) {
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_ENABLE);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ENABLE);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_VALUE);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ORG);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_NUMBERS);
+ addConfigName(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_TEXT);
+ }
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.indexOf(CONFIG_POLICY_ID) >= 0) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_ID"));
+ } else if (name.indexOf(CONFIG_CPSURI_ENABLE) >= 0) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_QUALIFIER_CPSURI_ENABLE"));
+ } else if (name.indexOf(CONFIG_USERNOTICE_ENABLE) >= 0) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_QUALIFIER_USERNOTICE_ENABLE"));
+ } else if (name.indexOf(CONFIG_POLICY_ENABLE) >= 0) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CERTIFICATE_POLICY_ENABLE"));
+ } else if (name.indexOf(CONFIG_POLICY_QUALIFIERS_NUM) >= 0) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_QUALIFIER_NUM"));
+ } else if (name.indexOf(CONFIG_USERNOTICE_ORG) >= 0) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_USERNOTICE_REF_ORG"));
+ } else if (name.indexOf(CONFIG_USERNOTICE_NUMBERS) >= 0) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_USERNOTICE_REF_NUMBERS"));
+ } else if (name.indexOf(CONFIG_USERNOTICE_TEXT) >= 0) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_USERNOTICE_EXPLICIT_TEXT"));
+ } else if (name.indexOf(CONFIG_CPSURI_VALUE) >= 0) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_CPSURI"));
+ } else if (name.indexOf(CONFIG_POLICY_NUM) >= 0) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "5",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_POLICIES"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_POLICY_QUALIFIERS)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POLICY_QUALIFIERS"));
+ }
+ return null;
+ }
+
+ private Hashtable buildRecords(String value) throws EPropertyException {
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+ Hashtable table = new Hashtable();
+ while (st.hasMoreTokens()) {
+ String token = (String) st.nextToken();
+ int index = token.indexOf(":");
+ if (index <= 0)
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", token));
+ String name = token.substring(0, index);
+ String val = "";
+ if ((token.length()-1) > index) {
+ val = token.substring(index+1);
+ }
+ table.put(name, val);
+ }
+
+ return table;
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ CertificatePoliciesExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (CertificatePoliciesExtension)
+ getExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ ext.setCritical(val);
+ } else if (name.equals(VAL_POLICY_QUALIFIERS)) {
+ ext = (CertificatePoliciesExtension)
+ getExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ info);
+
+ Hashtable h = buildRecords(value);
+
+ String numStr = (String)h.get(CONFIG_POLICY_NUM);
+ int size = Integer.parseInt(numStr);
+
+ Vector certificatePolicies = new Vector();
+ for (int i = 0; i < size; i++) {
+ String enable = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ENABLE);
+ CertificatePolicyInfo cinfo = null;
+ if (enable != null && enable.equals("true")) {
+ String policyId = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ID);
+
+ if (policyId == null || policyId.length() == 0)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_CERTIFICATE_POLICIES_EMPTY_POLICYID"));
+ CertificatePolicyId cpolicyId = getPolicyId(policyId);
+
+ String qualifersNum = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_QUALIFIERS_NUM);
+ PolicyQualifiers policyQualifiers = new PolicyQualifiers();
+ int num = 0;
+ if (qualifersNum != null && qualifersNum.length() > 0)
+ num = Integer.parseInt(qualifersNum);
+ for (int j=0; j<num; j++) {
+ String cpsuriEnable = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_ENABLE);
+ String usernoticeEnable = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ENABLE);
+ if (cpsuriEnable != null && cpsuriEnable.equals("true")) {
+ String cpsuri = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_VALUE);
+ netscape.security.x509.PolicyQualifierInfo qualifierInfo = createCPSuri(cpsuri);
+ if (qualifierInfo != null)
+ policyQualifiers.add(qualifierInfo);
+ } else if (usernoticeEnable != null && enable.equals("true")) {
+ String org = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ORG);
+ String noticenumbers = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_NUMBERS);
+ String explicitText = (String)h.get(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_TEXT);
+ netscape.security.x509.PolicyQualifierInfo qualifierInfo = createUserNotice(org,
+ noticenumbers, explicitText);
+ if (qualifierInfo != null)
+ policyQualifiers.add(qualifierInfo);
+ }
+ }
+
+ if (policyQualifiers.size() <= 0) {
+ cinfo =
+ new CertificatePolicyInfo(cpolicyId);
+ } else {
+ cinfo =
+ new CertificatePolicyInfo(cpolicyId, policyQualifiers);
+ }
+ if (cinfo != null)
+ certificatePolicies.addElement(cinfo);
+ }
+ }
+
+ ext.set(CertificatePoliciesExtension.INFOS, certificatePolicies);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("CertificatePoliciesExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (IOException e) {
+ CMS.debug("CertificatePoliciesExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ CertificatePoliciesExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (CertificatePoliciesExtension)
+ getExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_POLICY_QUALIFIERS)) {
+ ext = (CertificatePoliciesExtension)
+ getExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ StringBuffer sb = new StringBuffer();
+ int num_policies = getNumPolicies();
+ int num_qualifiers = DEF_NUM_QUALIFIERS;
+ sb.append(CONFIG_POLICY_NUM);
+ sb.append(":");
+ sb.append(num_policies);
+ sb.append("\n");
+ Vector infos = null;
+ try {
+ infos = (Vector)(ext.get(CertificatePoliciesExtension.INFOS));
+ } catch (IOException ee) {
+ }
+ Enumeration policies = ext.getElements();
+
+ for (int i = 0; i < num_policies; i++) {
+ int qSize = 0;
+ String policyId = "";
+ String policyEnable = "false";
+ PolicyQualifiers qualifiers = null;
+ if (infos.size() > 0) {
+ CertificatePolicyInfo cinfo =
+ (CertificatePolicyInfo) infos.elementAt(0);
+
+ CertificatePolicyId id1 = cinfo.getPolicyIdentifier();
+ policyId = id1.getIdentifier().toString();
+ policyEnable = "true";
+ qualifiers = cinfo.getPolicyQualifiers();
+ if (qualifiers != null)
+ qSize = qualifiers.size();
+ infos.removeElementAt(0);
+ }
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ENABLE);
+ sb.append(":");
+ sb.append(policyEnable);
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_ID);
+ sb.append(":");
+ sb.append(policyId);
+ sb.append("\n");
+
+ if (qSize == 0) {
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_QUALIFIERS_NUM);
+ sb.append(":");
+ sb.append(DEF_NUM_QUALIFIERS);
+ sb.append("\n");
+ } else {
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_POLICY_QUALIFIERS_NUM);
+ sb.append(":");
+ sb.append(qSize);
+ sb.append("\n");
+ }
+ if (qSize == 0) {
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_CPSURI_ENABLE);
+ sb.append(":");
+ sb.append("false");
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_CPSURI_VALUE);
+ sb.append(":");
+ sb.append("");
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_USERNOTICE_ENABLE);
+ sb.append(":");
+ sb.append("false");
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_USERNOTICE_ORG);
+ sb.append(":");
+ sb.append("");
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_USERNOTICE_NUMBERS);
+ sb.append(":");
+ sb.append("");
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+"0"+SEPARATOR+CONFIG_USERNOTICE_TEXT);
+ sb.append(":");
+ sb.append("");
+ sb.append("\n");
+ }
+
+ for (int j=0; j<qSize; j++) {
+ netscape.security.x509.PolicyQualifierInfo qinfo = qualifiers.getInfoAt(j);
+ ObjectIdentifier oid = qinfo.getId();
+ Qualifier qualifier = qinfo.getQualifier();
+
+ String cpsuriEnable = "false";
+ String usernoticeEnable = "false";
+ String cpsuri = "";
+ String org = "";
+ StringBuffer noticeNum = new StringBuffer();
+ String explicitText = "";
+
+ if (oid.toString().equals(netscape.security.x509.PolicyQualifierInfo.QT_CPS.toString())) {
+ cpsuriEnable = "true";
+ CPSuri content = (CPSuri)qualifier;
+ cpsuri = content.getURI();
+ } else if (oid.toString().equals(netscape.security.x509.PolicyQualifierInfo.QT_UNOTICE.toString())) {
+ usernoticeEnable = "true";
+ UserNotice content = (UserNotice)qualifier;
+ NoticeReference ref = content.getNoticeReference();
+ if (ref != null) {
+ org = ref.getOrganization().getText();
+ int[] nums = ref.getNumbers();
+ for (int k=0; k<nums.length; k++) {
+ if (k != 0) {
+ noticeNum.append(",");
+ noticeNum.append(nums[k]);
+ } else
+ noticeNum.append(nums[k]);
+ }
+ }
+ DisplayText displayText = content.getDisplayText();
+ if (displayText != null)
+ explicitText = displayText.getText();
+ }
+
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_ENABLE);
+ sb.append(":");
+ sb.append(cpsuriEnable);
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_CPSURI_VALUE);
+ sb.append(":");
+ sb.append(cpsuri);
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ENABLE);
+ sb.append(":");
+ sb.append(usernoticeEnable);
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_ORG);
+ sb.append(":");
+ sb.append(org);
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_NUMBERS);
+ sb.append(":");
+ sb.append(noticeNum.toString());
+ sb.append("\n");
+ sb.append(CONFIG_PREFIX+i+SEPARATOR+CONFIG_PREFIX1+j+SEPARATOR+CONFIG_USERNOTICE_TEXT);
+ sb.append(":");
+ sb.append(explicitText);
+ sb.append("\n");
+ }
+ } // end of for loop
+ return sb.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ String numPolicies = getConfig(CONFIG_POLICY_NUM);
+ int num = getNumPolicies();
+ int num1 = getNumQualifiers();
+
+ try {
+ IConfigStore basesubstore = getConfigStore().getSubStore("params");
+ sb.append("{");
+ sb.append(CONFIG_POLICY_NUM + ":");
+ sb.append(num);
+ sb.append(",");
+ for (int i = 0; i < num; i++) {
+ sb.append("{");
+ IConfigStore substore = basesubstore.getSubStore(CONFIG_PREFIX+i);
+ String enable = substore.getString(CONFIG_POLICY_ENABLE, "");
+ sb.append(POLICY_ID_ENABLE + ":");
+ sb.append(enable);
+ sb.append(",");
+ String policyId = substore.getString(CONFIG_POLICY_ID, "");
+ sb.append(POLICY_ID + ":");
+ sb.append(policyId);
+ sb.append(",");
+ String qualifiersNum = substore.getString(CONFIG_POLICY_QUALIFIERS_NUM, "");
+ sb.append(CONFIG_POLICY_QUALIFIERS_NUM+":");
+ sb.append(qualifiersNum);
+ sb.append(",");
+ for (int j=0; j<num1; j++) {
+ IConfigStore substore1 = substore.getSubStore(CONFIG_PREFIX1+j);
+ sb.append("{");
+ String cpsuriEnable = substore1.getString(CONFIG_CPSURI_ENABLE, "");
+ sb.append(POLICY_QUALIFIER_CPSURI_ENABLE + ":");
+ sb.append(cpsuriEnable);
+ sb.append(",");
+ String usernoticeEnable = substore1.getString(CONFIG_USERNOTICE_ENABLE, "");
+ sb.append(POLICY_QUALIFIER_USERNOTICE_ENABLE+ ":");
+ sb.append(usernoticeEnable);
+ sb.append(",");
+ String org = substore1.getString(CONFIG_USERNOTICE_ORG, "");
+ sb.append(USERNOTICE_REF_ORG + ":");
+ sb.append(org);
+ sb.append(",");
+ String refNums = substore1.getString(CONFIG_USERNOTICE_NUMBERS, "");
+ sb.append(USERNOTICE_REF_NUMBERS + ":");
+ sb.append(refNums);
+ sb.append(",");
+ String explicitText = substore1.getString(CONFIG_USERNOTICE_TEXT, "");
+ sb.append(USERNOTICE_EXPLICIT_TEXT + ":");
+ sb.append(explicitText);
+ sb.append(",");
+ String cpsuri = substore1.getString(CONFIG_CPSURI_VALUE, "");
+ sb.append(CPSURI + ":");
+ sb.append(cpsuri);
+ sb.append("}");
+ }
+ sb.append("}");
+ }
+ sb.append("}");
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_CERTIFICATE_POLICIES_EXT",
+ getConfig(CONFIG_CRITICAL), sb.toString());
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CertificatePoliciesExtension ext = createExtension();
+
+ if (ext == null)
+ return;
+ addExtension(PKIXExtensions.CertificatePolicies_Id.toString(),
+ ext, info);
+ }
+
+ public CertificatePoliciesExtension createExtension()
+ throws EProfileException {
+ CertificatePoliciesExtension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ Vector certificatePolicies = new Vector();
+ int num = getNumPolicies();
+ CMS.debug("CertificatePoliciesExtension: createExtension: number of policies="+num);
+ IConfigStore config = getConfigStore();
+
+ for (int i = 0; i < num; i++) {
+ IConfigStore basesubstore = config.getSubStore("params");
+ IConfigStore substore = basesubstore.getSubStore(CONFIG_PREFIX+i);
+ String enable = substore.getString(CONFIG_POLICY_ENABLE);
+
+ CMS.debug("CertificatePoliciesExtension: createExtension: CertificatePolicy "+i+" enable="+enable);
+ if (enable != null && enable.equals("true")) {
+ String policyId = substore.getString(CONFIG_POLICY_ID);
+ CertificatePolicyId cpolicyId = getPolicyId(policyId);
+ CMS.debug("CertificatePoliciesExtension: createExtension: CertificatePolicy "+i+" policyId="+policyId);
+ int qualifierNum = getNumQualifiers();
+ PolicyQualifiers policyQualifiers = new PolicyQualifiers();
+ for (int j=0; j<qualifierNum; j++) {
+ IConfigStore substore1 = substore.getSubStore(CONFIG_PREFIX1+j);
+ String cpsuriEnable = substore1.getString(CONFIG_CPSURI_ENABLE);
+ String usernoticeEnable = substore1.getString(CONFIG_USERNOTICE_ENABLE);
+
+ if (cpsuriEnable != null && cpsuriEnable.equals("true")) {
+ String cpsuri = substore1.getString(CONFIG_CPSURI_VALUE, "");
+ netscape.security.x509.PolicyQualifierInfo qualifierInfo = createCPSuri(cpsuri);
+ if (qualifierInfo != null)
+ policyQualifiers.add(qualifierInfo);
+ } else if (usernoticeEnable != null &&
+ usernoticeEnable.equals("true")) {
+
+ String org = substore1.getString(CONFIG_USERNOTICE_ORG);
+ String noticenumbers = substore1.getString(CONFIG_USERNOTICE_NUMBERS);
+ String explicitText = substore1.getString(CONFIG_USERNOTICE_TEXT);
+ netscape.security.x509.PolicyQualifierInfo qualifierInfo = createUserNotice(org,
+ noticenumbers, explicitText);
+ if (qualifierInfo != null)
+ policyQualifiers.add(qualifierInfo);
+ }
+ }
+
+ CertificatePolicyInfo info = null;
+ if (policyQualifiers.size() <= 0) {
+ info =
+ new CertificatePolicyInfo(cpolicyId);
+ } else {
+ info =
+ new CertificatePolicyInfo(cpolicyId, policyQualifiers);
+ }
+
+ if (info != null)
+ certificatePolicies.addElement(info);
+ }
+ }
+
+ ext = new CertificatePoliciesExtension(critical, certificatePolicies);
+ } catch (EPropertyException e) {
+ throw new EProfileException(e.toString());
+ } catch (EProfileException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("CertificatePoliciesExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+
+ private CertificatePolicyId getPolicyId (String policyId) throws EPropertyException {
+ if (policyId == null || policyId.length() == 0)
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_PROFILE_CERTIFICATE_POLICIES_EMPTY_POLICYID"));
+
+ CertificatePolicyId cpolicyId = null;
+ try {
+ cpolicyId = new CertificatePolicyId(
+ ObjectIdentifier.getObjectIdentifier(policyId));
+ return cpolicyId;
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_PROFILE_CERTIFICATE_POLICIES_POLICYID_ERROR", policyId));
+ }
+ }
+
+ private netscape.security.x509.PolicyQualifierInfo createCPSuri(String uri) throws EPropertyException {
+ if (uri == null || uri.length() == 0)
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_PROFILE_CERTIFICATE_POLICIES_EMPTY_CPSURI"));
+
+ CPSuri cpsURI = new CPSuri(uri);
+ netscape.security.x509.PolicyQualifierInfo policyQualifierInfo2 =
+ new netscape.security.x509.PolicyQualifierInfo(netscape.security.x509.PolicyQualifierInfo.QT_CPS, cpsURI);
+
+ return policyQualifierInfo2;
+ }
+
+ private netscape.security.x509.PolicyQualifierInfo createUserNotice(String organization,
+ String noticeText, String noticeNums) throws EPropertyException {
+
+ if ((organization == null || organization.length() == 0) &&
+ (noticeNums == null || noticeNums.length() == 0) &&
+ (noticeText == null || noticeText.length() == 0))
+ return null;
+
+ DisplayText explicitText = null;
+ if (noticeText != null && noticeText.length() > 0)
+ explicitText = new DisplayText(DisplayText.tag_VisibleString, noticeText);
+
+ int nums[] = null;
+ if (noticeNums != null && noticeNums.length() > 0) {
+ Vector numsVector = new Vector();
+ StringTokenizer tokens = new StringTokenizer(noticeNums, ";");
+ while (tokens.hasMoreTokens()) {
+ String num = tokens.nextToken().trim();
+ numsVector.addElement(num);
+ }
+
+ nums = new int[numsVector.size()];
+ try {
+ for (int i = 0; i < numsVector.size(); i++) {
+ Integer ii = new Integer((String) numsVector.elementAt(i));
+ nums[i] = ii.intValue();
+ }
+ } catch (Exception e) {
+ throw new EPropertyException("Wrong notice numbers");
+ }
+ }
+
+ DisplayText orgName = null;
+ if (organization != null && organization.length() > 0) {
+ orgName =
+ new DisplayText(DisplayText.tag_VisibleString, organization);
+ }
+
+ NoticeReference noticeReference = null;
+
+ if (orgName != null)
+ noticeReference = new NoticeReference(orgName, nums);
+
+ UserNotice userNotice = null;
+ if (explicitText != null || noticeReference != null) {
+ userNotice = new UserNotice (noticeReference, explicitText);
+
+ netscape.security.x509.PolicyQualifierInfo policyQualifierInfo1 =
+ new netscape.security.x509.PolicyQualifierInfo(netscape.security.x509.PolicyQualifierInfo.QT_UNOTICE, userNotice);
+ return policyQualifierInfo1;
+ }
+
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java
new file mode 100644
index 000000000..f80e98a4a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java
@@ -0,0 +1,191 @@
+// --- 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.def;
+
+import java.io.*;
+import java.security.cert.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Netscape comment extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertificateVersionDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_VERSION = "certVersionNum";
+
+ public static final String VAL_VERSION = "certVersionNum";
+
+ public CertificateVersionDefault() {
+ super();
+ addValueName(VAL_VERSION);
+
+ addConfigName(CONFIG_VERSION);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_VERSION)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "3",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VERSION"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (name.equals(CONFIG_VERSION)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_VERSION));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_VERSION)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "3",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VERSION"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_VERSION)) {
+ if (value == null || value.equals(""))
+ throw new EPropertyException(name+" cannot be empty");
+ else {
+ int version = Integer.valueOf(value).intValue()-1;
+
+ if (version == CertificateVersion.V1)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V1));
+ else if (version == CertificateVersion.V2)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V2));
+ else if (version == CertificateVersion.V3)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (IOException e) {
+ CMS.debug("CertificateVersionDefault: setValue " + e.toString());
+ } catch (CertificateException e) {
+ CMS.debug("CertificateVersionDefault: setValue " + e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ if (name.equals(VAL_VERSION)) {
+ CertificateVersion v = null;
+ try {
+ v = (CertificateVersion)info.get(
+ X509CertInfo.VERSION);
+ } catch (Exception e) {
+ }
+
+ if (v == null)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ int version = v.compare(0);
+
+ return ""+(version+1);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_VERSION)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_CERT_VERSION", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ String v = getConfig(CONFIG_VERSION);
+ int version = Integer.valueOf(v).intValue()-1;
+
+ try {
+ if (version == CertificateVersion.V1)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V1));
+ else if (version == CertificateVersion.V2)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V2));
+ else if (version == CertificateVersion.V3)
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ else {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_INVALID_PROPERTY", CONFIG_VERSION));
+ }
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
new file mode 100644
index 000000000..20c124dbc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
@@ -0,0 +1,783 @@
+// --- 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.def;
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.CertificateException;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.pattern.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cms.profile.common.EnrollProfile;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements an enrollment default policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDefault {
+
+ public static final String PROP_NAME = "name";
+
+ public static final String GN_RFC822_NAME = "RFC822Name";
+ public static final String GN_DNS_NAME = "DNSName";
+ public static final String GN_URI_NAME = "URIName";
+ public static final String GN_IP_NAME = "IPAddressName";
+ public static final String GN_DIRECTORY_NAME = "DirectoryName";
+ public static final String GN_EDI_NAME = "EDIPartyName";
+ public static final String GN_ANY_NAME = "OtherName";
+ public static final String GN_OID_NAME = "OIDName";
+
+ protected IConfigStore mConfig = null;
+ protected Vector mConfigNames = new Vector();
+ protected Vector mValueNames = new Vector();
+
+ public EnrollDefault() {
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void addConfigName(String name) {
+ mConfigNames.addElement(name);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (mConfig.getSubStore("params") == null) {
+ //
+ } else {
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public String getConfig(String name) {
+ try {
+ if (mConfig == null)
+ return null;
+ if (mConfig.getSubStore("params") != null) {
+ return mConfig.getSubStore("params").getString(name);
+ }
+ } catch (EBaseException e) {
+ }
+ return "";
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale locale of the end user
+ * @return localized description of this default policy
+ */
+ public abstract String getText(Locale locale);
+
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(PROP_NAME);
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Populates attributes into the certificate template.
+ *
+ * @param request enrollment request
+ * @param info certificate template
+ * @exception EProfileException failed to populate attributes
+ * into request
+ */
+ public abstract void populate(IRequest request, X509CertInfo info)
+ throws EProfileException;
+
+ /**
+ * Sets values from the approval page into certificate template.
+ *
+ * @param name name of the attribute
+ * @param locale user locale
+ * @param info certificate template
+ * @param value attribute value
+ * @exception EProfileException failed to set attributes
+ * into request
+ */
+ public abstract void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException;
+
+ /**
+ * Retrieves certificate template values and returns them to
+ * the approval page.
+ *
+ * @param name name of the attribute
+ * @param locale user locale
+ * @param info certificate template
+ * @exception EProfileException failed to get attributes
+ * from request
+ */
+ public abstract String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException;
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the populate() method of the subclass.
+ *
+ * @param request request to be populated
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IRequest request)
+ throws EProfileException {
+ String name = getClass().getName();
+
+ name = name.substring(name.lastIndexOf('.') + 1);
+ CMS.debug(name + ": populate start");
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ populate(request, info);
+
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ CMS.debug(name + ": populate end");
+ }
+
+ public void addValueName(String name) {
+ mValueNames.addElement(name);
+ }
+
+ public Enumeration getValueNames() {
+ return mValueNames.elements();
+ }
+
+ public IDescriptor getValueDescriptor(String name) {
+ return null;
+ }
+
+ /**
+ * Sets the value of the given value property by name.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the setValue() method of the subclass.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @param value value to be set in the given request
+ * @exception EPropertyException failed to set property
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value)
+ throws EPropertyException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ setValue(name, locale, info, value);
+
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the value of the given value
+ * property by name.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the getValue() method of the subclass.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @exception EPropertyException failed to get property
+ */
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EPropertyException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ String value = getValue(name, locale, info);
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ return value;
+ }
+
+ public String toHexString(byte data[]) {
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+ String s = pp.toHexString(data, 0, 16);
+ StringTokenizer st = new StringTokenizer(s, "\n");
+ StringBuffer buffer = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ buffer.append(st.nextToken());
+ buffer.append("\\n");
+ }
+ return buffer.toString();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ mConfigNames.removeAllElements();
+ mValueNames.removeAllElements();
+ }
+
+ protected void deleteExtension(String name, X509CertInfo info) {
+ CertificateExtensions exts = null;
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ if (exts == null)
+ return;
+ Enumeration e = exts.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ Extension ext = (Extension) exts.get(n);
+
+ if (ext.getExtensionId().toString().equals(name)) {
+ exts.delete(n);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ protected Extension getExtension(String name, X509CertInfo info) {
+ CertificateExtensions exts = null;
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ CMS.debug("EnrollDefault: getExtension " + e.toString());
+ }
+ if (exts == null)
+ return null;
+ return getExtension(name, exts);
+ }
+
+ protected Extension getExtension(String name, CertificateExtensions exts) {
+ if (exts == null)
+ return null;
+ Enumeration e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+
+ if (ext.getExtensionId().toString().equals(name)) {
+ return ext;
+ }
+ }
+ return null;
+ }
+
+ protected void addExtension(String name, Extension ext, X509CertInfo info)
+ throws EProfileException {
+ if (ext == null) {
+ throw new EProfileException("extension not found");
+ }
+ CertificateExtensions exts = null;
+
+ Extension alreadyPresentExtension = getExtension(name,info);
+
+ if (alreadyPresentExtension != null) {
+ String eName = ext.toString();
+ CMS.debug("EnrollDefault.addExtension: duplicate extension attempted! Name: " + eName);
+ throw new EProfileException(CMS.getUserMessage("CMS_PROFILE_DUPLICATE_EXTENSION",eName));
+ }
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ CMS.debug("EnrollDefault: " + e.toString());
+ }
+ if (exts == null) {
+ throw new EProfileException("extensions not found");
+ }
+ try {
+ exts.set(name, ext);
+ } catch (IOException e) {
+ CMS.debug("EnrollDefault: " + e.toString());
+ }
+ }
+
+ protected void replaceExtension(String name, Extension ext, X509CertInfo info)
+ throws EProfileException {
+ deleteExtension(name, info);
+ addExtension(name, ext, info);
+ }
+
+ protected boolean isOptional(String value) {
+ return value.equals("");
+ }
+
+ protected boolean getBoolean(String value) {
+ return Boolean.valueOf(value).booleanValue();
+ }
+
+ protected int getInt(String value) {
+ return Integer.valueOf(value).intValue();
+ }
+
+ protected boolean getConfigBoolean(String value) {
+ return getBoolean(getConfig(value));
+ }
+
+ protected int getConfigInt(String value) {
+ return getInt(getConfig(value));
+ }
+
+ protected boolean isGeneralNameValid(String name)
+ {
+ if (name == null)
+ return false;
+ int pos = name.indexOf(':');
+ if (pos == -1)
+ return false;
+ String nameType = name.substring(0, pos).trim();
+ String nameValue = name.substring(pos + 1).trim();
+ if (nameValue.equals(""))
+ return false;
+ return true;
+ }
+
+ protected GeneralNameInterface parseGeneralName(String name)
+ throws IOException {
+ int pos = name.indexOf(':');
+ if (pos == -1)
+ return null;
+ String nameType = name.substring(0, pos).trim();
+ String nameValue = name.substring(pos + 1).trim();
+ return parseGeneralName(nameType, nameValue);
+ }
+
+ protected boolean isGeneralNameType(String nameType)
+ {
+ if (nameType.equalsIgnoreCase("RFC822Name")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("DNSName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("x400")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("DirectoryName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("EDIPartyName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("URIName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("IPAddress")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("OIDName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("OtherName")) {
+ return true;
+ }
+ return false;
+ }
+
+ protected GeneralNameInterface parseGeneralName(String nameType, String nameValue)
+ throws IOException
+ {
+ if (nameType.equalsIgnoreCase("RFC822Name")) {
+ return new RFC822Name(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("DNSName")) {
+ return new DNSName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("x400")) {
+ // XXX
+ }
+ if (nameType.equalsIgnoreCase("DirectoryName")) {
+ return new X500Name(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("EDIPartyName")) {
+ return new EDIPartyName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("URIName")) {
+ return new URIName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("IPAddress")) {
+ CMS.debug("IP Value:" + nameValue);
+ if (nameValue.indexOf('/') != -1) {
+ // CIDR support for NameConstraintsExt
+ StringTokenizer st = new StringTokenizer(nameValue, "/");
+ String addr = st.nextToken();
+ String netmask = st.nextToken();
+ CMS.debug("addr:" + addr +" netmask: "+netmask);
+ return new IPAddressName(addr, netmask);
+ } else {
+ return new IPAddressName(nameValue);
+ }
+ }
+ if (nameType.equalsIgnoreCase("OIDName")) {
+ try {
+ // check if OID
+ ObjectIdentifier oid = new ObjectIdentifier(nameValue);
+ } catch (Exception e) {
+ return null;
+ }
+ return new OIDName(nameValue);
+ }
+ if (nameType.equals("OtherName")) {
+ if (nameValue == null || nameValue.length() == 0)
+ nameValue = " ";
+ if (nameValue.startsWith("(PrintableString)")) {
+ // format: OtherName: (PrintableString)oid,value
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_PrintableString, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(KerberosName)")) {
+ // Syntax: (KerberosName)Realm|NameType|NameString(s)
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf('|');
+ int pos2 = nameValue.lastIndexOf('|');
+ String realm = nameValue.substring(pos0 + 1, pos1).trim();
+ String name_type = nameValue.substring(pos1 + 1, pos2).trim();
+ String name_strings = nameValue.substring(pos2 + 1).trim();
+ Vector strings = new Vector();
+ StringTokenizer st = new StringTokenizer(name_strings, ",");
+ while (st.hasMoreTokens()) {
+ strings.addElement(st.nextToken());
+ }
+ KerberosName name = new KerberosName(realm,
+ Integer.parseInt(name_type), strings);
+ // krb5 OBJECT IDENTIFIER ::= { iso (1)
+ // org (3)
+ // dod (6)
+ // internet (1)
+ // security (5)
+ // kerberosv5 (2) }
+ // krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 }
+ return new OtherName(KerberosName.KRB5_PRINCIPAL_NAME,
+ name.toByteArray());
+ } else if (nameValue.startsWith("(IA5String)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_IA5String, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(UTF8String)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_UTF8String, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(BMPString)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_BMPString, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(Any)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ CMS.debug("OID: " + on_oid + " Value:" + on_value);
+ return new OtherName(new ObjectIdentifier(on_oid), getBytes(on_value));
+ } else {
+ CMS.debug("Invalid OID " + on_oid);
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Converts string containing pairs of characters in the range of '0'
+ * to '9', 'a' to 'f' to an array of bytes such that each pair of
+ * characters in the string represents an individual byte
+ */
+ public byte[] getBytes(String string) {
+ if (string == null)
+ return null;
+ int stringLength = string.length();
+ if ((stringLength == 0) || ((stringLength % 2) != 0))
+ return null;
+ byte[] bytes = new byte[ (stringLength / 2) ];
+ for (int i = 0, b = 0; i < stringLength; i += 2, ++b) {
+ String nextByte = string.substring(i, (i + 2));
+ bytes[b] = (byte)Integer.parseInt(nextByte, 0x10);
+ }
+ return bytes;
+ }
+
+ /**
+ * Check if a object identifier in string form is valid,
+ * that is a string in the form n.n.n.n and der encode and decode-able.
+ * @param oid object identifier string.
+ * @return true if the oid is valid
+ */
+ public boolean isValidOID(String oid)
+ {
+ ObjectIdentifier v = null;
+ try {
+ v = ObjectIdentifier.getObjectIdentifier(oid);
+ } catch (Exception e) {
+ return false;
+ }
+ if (v == null)
+ return false;
+
+ // if the OID isn't valid (ex. n.n) the error isn't caught til
+ // encoding time leaving a bad request in the request queue.
+ try {
+ DerOutputStream derOut = new DerOutputStream();
+
+ derOut.putOID(v);
+ new ObjectIdentifier(new DerInputStream(derOut.toByteArray()));
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ protected String buildRecords(Vector recs) throws EPropertyException {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < recs.size(); i++) {
+ NameValuePairs pairs = (NameValuePairs) recs.elementAt(i);
+
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("\r\n");
+ Enumeration e = pairs.getNames();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String val = pairs.getValue(key);
+
+ sb.append(key);
+ sb.append(":");
+ sb.append(val);
+ sb.append("\r\n");
+ }
+ sb.append("\r\n");
+
+ }
+ return sb.toString();
+ }
+
+ protected Vector parseRecords(String value) throws EPropertyException {
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+ int num = 0;
+ Vector v = new Vector();
+ NameValuePairs nvps = null;
+
+ while (st.hasMoreTokens()) {
+ String token = (String) st.nextToken();
+
+ if (token.equals("Record #" + num)) {
+ CMS.debug("parseRecords: Record" + num);
+ nvps = new NameValuePairs();
+ v.addElement(nvps);
+ try {
+ token = (String) st.nextToken();
+ } catch (NoSuchElementException e) {
+ v.removeElementAt(num);
+ CMS.debug(e.toString());
+ return v;
+ }
+ num++;
+ }
+
+ if (nvps == null)
+ throw new EPropertyException("Bad Input Format");
+
+ int pos = token.indexOf(":");
+
+ if (pos <= 0) {
+ CMS.debug("parseRecords: No colon found in the input line");
+ throw new EPropertyException("Bad Input Format");
+ } else {
+ if (pos == (token.length() - 1)) {
+ nvps.add(token.substring(0, pos), "");
+ } else {
+ nvps.add(token.substring(0, pos), token.substring(pos + 1));
+ }
+ }
+ }
+
+ return v;
+ }
+
+ protected String getGeneralNameType(GeneralName gn)
+ throws EPropertyException {
+ int type = gn.getType();
+
+ if (type == GeneralNameInterface.NAME_RFC822)
+ return "RFC822Name";
+ else if (type == GeneralNameInterface.NAME_DNS)
+ return "DNSName";
+ else if (type == GeneralNameInterface.NAME_URI)
+ return "URIName";
+ else if (type == GeneralNameInterface.NAME_IP)
+ return "IPAddress";
+ else if (type == GeneralNameInterface.NAME_DIRECTORY)
+ return "DirectoryName";
+ else if (type == GeneralNameInterface.NAME_EDI)
+ return "EDIPartyName";
+ else if (type == GeneralNameInterface.NAME_ANY)
+ return "OtherName";
+ else if (type == GeneralNameInterface.NAME_OID)
+ return "OIDName";
+
+ throw new EPropertyException("Unsupported type: " + type);
+ }
+
+ protected String getGeneralNameValue(GeneralName gn) throws EPropertyException {
+ String s = gn.toString();
+ int type = gn.getType();
+
+ if (type == GeneralNameInterface.NAME_DIRECTORY)
+ return s;
+ else {
+ int pos = s.indexOf(":");
+
+ if (pos <= 0)
+ throw new EPropertyException("Badly formatted general name: " + s);
+ else {
+ return s.substring(pos + 1).trim();
+ }
+ }
+ }
+
+ public Locale getLocale(IRequest request) {
+ Locale locale = null;
+
+ if (request == null)
+ return null;
+
+ String language = request.getExtDataInString(
+ EnrollProfile.REQUEST_LOCALE);
+ if (language != null) {
+ locale = new Locale(language);
+ }
+ return locale;
+ }
+
+ public String toGeneralNameString(GeneralName gn) {
+ int type = gn.getType();
+ // Sun's General Name is not consistent, so we need
+ // to do a special case for directory string
+ if (type == GeneralNameInterface.NAME_DIRECTORY) {
+ return "DirectoryName: " + gn.toString();
+ }
+ return gn.toString();
+ }
+
+ protected String mapPattern(IRequest request, String pattern)
+ throws IOException {
+ Pattern p = new Pattern(pattern);
+ IAttrSet attrSet = null;
+ if (request != null) {
+ attrSet = request.asIAttrSet();
+ }
+ return p.substitute2("request", attrSet);
+ }
+
+ protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape)
+ {
+ StringBuffer result = new StringBuffer();
+
+ // Do we need to escape any characters
+ for (int i = 0; i < v.length(); i++) {
+ int c = v.charAt(i);
+ if (c == ',' || c == '=' || c == '+' || c == '<' ||
+ c == '>' || c == '#' || c == ';' || c == '\r' ||
+ c == '\n' || c == '\\' || c == '"') {
+ result.append('\\');
+ if (doubleEscape) result.append('\\');
+ }
+ if (c == '\r') {
+ result.append("0D");
+ } else if (c == '\n') {
+ result.append("0A");
+ } else {
+ result.append((char)c);
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java
new file mode 100644
index 000000000..e51c03b40
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java
@@ -0,0 +1,42 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.common.EnrollProfile;
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements an enrollment extension
+ * default policy that extension into the certificate
+ * template.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollExtDefault extends EnrollDefault {
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java
new file mode 100644
index 000000000..ddc0403c9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java
@@ -0,0 +1,253 @@
+// --- 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.def;
+
+
+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.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Extended Key Usage extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtendedKeyUsageExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "exKeyUsageCritical";
+ public static final String CONFIG_OIDS = "exKeyUsageOIDs";
+
+ public static final String VAL_CRITICAL = "exKeyUsageCritical";
+ public static final String VAL_OIDS = "exKeyUsageOIDs";
+
+ public ExtendedKeyUsageExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_OIDS);
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_OIDS);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_OIDS)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_OIDS"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_OIDS)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_OIDS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ ExtendedKeyUsageExtension ext = null;
+
+
+ ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_OIDS)) {
+ ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+ // ext.deleteAllOIDs();
+ StringTokenizer st = new StringTokenizer(value, ",");
+
+ if(ext == null) {
+ return;
+ }
+ while (st.hasMoreTokens()) {
+ String oid = st.nextToken();
+
+ ext.addOID(new ObjectIdentifier(oid));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ try {
+ replaceExtension(ExtendedKeyUsageExtension.OID, ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("ExtendedKeyUsageExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ExtendedKeyUsageExtension ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_OIDS)) {
+ ext = (ExtendedKeyUsageExtension)
+ getExtension(ExtendedKeyUsageExtension.OID, info);
+ StringBuffer sb = new StringBuffer();
+ if(ext == null) {
+ return "";
+ }
+ Enumeration e = ext.getOIDs();
+
+ while (e.hasMoreElements()) {
+ ObjectIdentifier oid = (ObjectIdentifier)
+ e.nextElement();
+
+ if (!sb.toString().equals("")) {
+ sb.append(",");
+ }
+ sb.append(oid.toString());
+ }
+ return sb.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_OIDS)
+ };
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_EXTENDED_KEY_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ ExtendedKeyUsageExtension ext = createExtension();
+
+ addExtension(ExtendedKeyUsageExtension.OID, ext, info);
+ }
+
+ public ExtendedKeyUsageExtension createExtension() {
+ ExtendedKeyUsageExtension ext = null;
+
+ try {
+ ext = new ExtendedKeyUsageExtension();
+ } catch (Exception e) {
+ CMS.debug("ExtendedKeyUsageExtDefault: createExtension " +
+ e.toString());
+ }
+ if (ext == null)
+ return null;
+ boolean critical = getBoolean(getConfig(CONFIG_CRITICAL));
+
+ ext.setCritical(critical);
+ StringTokenizer st = new StringTokenizer(getConfig(CONFIG_OIDS), ",");
+
+ while (st.hasMoreTokens()) {
+ String oid = st.nextToken();
+
+ ext.addOID(new ObjectIdentifier(oid));
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java
new file mode 100644
index 000000000..773182e11
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java
@@ -0,0 +1,588 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Freshest CRL extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class FreshestCRLExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "freshestCRLCritical";
+ public static final String CONFIG_NUM_POINTS = "freshestCRLPointNum";
+ public static final String CONFIG_POINT_TYPE = "freshestCRLPointType_";
+ public static final String CONFIG_POINT_NAME = "freshestCRLPointName_";
+ public static final String CONFIG_ISSUER_TYPE = "freshestCRLPointIssuerType_";
+ public static final String CONFIG_ISSUER_NAME = "freshestCRLPointIssuerName_";
+ public static final String CONFIG_ENABLE = "freshestCRLPointEnable_";
+
+ public static final String VAL_CRITICAL = "freshestCRLCritical";
+ public static final String VAL_CRL_DISTRIBUTION_POINTS =
+ "freshestCRLPointsValue";
+
+ private static final String POINT_TYPE = "Point Type";
+ private static final String POINT_NAME = "Point Name";
+ private static final String ISSUER_TYPE = "Issuer Type";
+ private static final String ISSUER_NAME = "Issuer Name";
+ private static final String ENABLE = "Enable";
+
+ private static final int DEF_NUM_POINTS = 1;
+ private static final int MAX_NUM_POINTS = 100;
+
+ public FreshestCRLExtDefault() {
+ super();
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+
+ protected int getNumPoints() {
+ int num = DEF_NUM_POINTS;
+ String val = getConfig(CONFIG_NUM_POINTS);
+
+ if (val != null) {
+ try {
+ num = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_POINTS)
+ num = DEF_NUM_POINTS;
+
+ return num;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_POINTS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_POINTS || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POINTS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POINTS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ //refesh our config name list
+
+ super.refreshConfigAndValueNames();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_CRL_DISTRIBUTION_POINTS);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumPoints();
+
+ addConfigName(CONFIG_NUM_POINTS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_POINT_TYPE + i);
+ addConfigName(CONFIG_POINT_NAME + i);
+ addConfigName(CONFIG_ISSUER_TYPE + i);
+ addConfigName(CONFIG_ISSUER_NAME + i);
+ addConfigName(CONFIG_ENABLE + i);
+ }
+
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_POINT_TYPE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POINT_TYPE"));
+ } else if (name.startsWith(CONFIG_POINT_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_POINT_NAME"));
+ } else if (name.startsWith(CONFIG_ISSUER_TYPE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ISSUER_TYPE"));
+ } else if (name.startsWith(CONFIG_ISSUER_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ISSUER_NAME"));
+ } else if (name.startsWith(CONFIG_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_POINTS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_DIST_POINTS"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRL_DISTRIBUTION_POINTS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ FreshestCRLExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+
+ if(ext == null) {
+ populate(locale,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ ext.setCritical(val);
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+ int i = 0;
+
+ for (; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+ String pointType = null;
+ String pointValue = null;
+ String issuerType = null;
+ String issuerValue = null;
+ String enable = null;
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(POINT_TYPE)) {
+ pointType = nvps.getValue(name1);
+ } else if (name1.equals(POINT_NAME)) {
+ pointValue = nvps.getValue(name1);
+ } else if (name1.equals(ISSUER_TYPE)) {
+ issuerType = nvps.getValue(name1);
+ } else if (name1.equals(ISSUER_NAME)) {
+ issuerValue = nvps.getValue(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(locale, cdp, pointType, pointValue);
+ if (issuerType != null)
+ addIssuer(locale, cdp, issuerType, issuerValue);
+
+ // this is the first distribution point
+ if (i == 0) {
+ ext = new FreshestCRLExtension(cdp);
+ ext.setCritical(critical);
+ } else {
+ ext.addPoint(cdp);
+ }
+ }
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.FreshestCRL_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("FreshestCRLExtDefault: setValue " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ private void addCRLPoint(Locale locale, CRLDistributionPoint cdp, String type,
+ String value) throws EPropertyException {
+ try {
+ if (value == null || value.length() == 0)
+ return;
+
+ if (isGeneralNameType(type)) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(parseGeneralName(type,value));
+ cdp.setFullName(gen);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ } catch (IOException e) {
+ CMS.debug("FreshestCRLExtDefault: addCRLPoint " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ } catch (GeneralNamesException e) {
+ CMS.debug("FreshestCRLExtDefault: addCRLPoint " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ }
+
+ private void addIssuer(Locale locale, CRLDistributionPoint cdp, String type,
+ String value) throws EPropertyException {
+ if (value == null || value.length() == 0)
+ return;
+ try {
+ if (isGeneralNameType(type)) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(parseGeneralName(type,value));
+ cdp.setCRLIssuer(gen);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", type));
+ }
+ } catch (IOException e) {
+ CMS.debug("FreshestCRLExtDefault: addIssuer " +
+ e.toString());
+ } catch (GeneralNamesException e) {
+ CMS.debug("FreshestCRLExtDefault: addIssuer " +
+ e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ FreshestCRLExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+ if(ext == null)
+ {
+ try {
+ populate(locale,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_CRL_DISTRIBUTION_POINTS)) {
+ ext = (FreshestCRLExtension)
+ getExtension(FreshestCRLExtension.OID,
+ info);
+
+ if (ext == null)
+ return "";
+
+ StringBuffer sb = new StringBuffer();
+
+ Vector recs = new Vector();
+ int num = getNumPoints();
+ for (int i = 0; i < num; i++) {
+ NameValuePairs pairs = null;
+
+ if (i < ext.getNumPoints()) {
+ CRLDistributionPoint p = ext.getPointAt(i);
+ GeneralNames gns = p.getFullName();
+
+ pairs = buildGeneralNames(gns, p);
+ } else {
+ pairs = buildEmptyGeneralNames();
+ }
+ recs.addElement(pairs);
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ protected NameValuePairs buildEmptyGeneralNames() {
+ NameValuePairs pairs = new NameValuePairs();
+
+ pairs.add(POINT_TYPE, "");
+ pairs.add(POINT_NAME, "");
+ pairs.add(ISSUER_TYPE, "");
+ pairs.add(ISSUER_NAME, "");
+ pairs.add(ENABLE, "false");
+ return pairs;
+ }
+
+ protected NameValuePairs buildGeneralNames(GeneralNames gns, CRLDistributionPoint p)
+ throws EPropertyException {
+
+ NameValuePairs pairs = new NameValuePairs();
+
+ RDN rdn = null;
+ boolean hasFullName = false;
+
+ pairs.add(ENABLE, "true");
+ if (gns == null) {
+ pairs.add(POINT_TYPE, "");
+ pairs.add(POINT_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+ int type = gn.getType();
+
+ pairs.add(POINT_TYPE, getGeneralNameType(gn));
+ pairs.add(POINT_NAME, getGeneralNameValue(gn));
+ }
+ }
+
+ if (!hasFullName) {
+ pairs.add(POINT_TYPE, GN_DIRECTORY_NAME);
+ pairs.add(POINT_NAME, "");
+ }
+
+ gns = p.getCRLIssuer();
+
+ if (gns == null) {
+ pairs.add(ISSUER_TYPE, GN_DIRECTORY_NAME);
+ pairs.add(ISSUER_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+ int type = gn.getType();
+
+ pairs.add(ISSUER_TYPE, getGeneralNameType(gn));
+ pairs.add(ISSUER_NAME, getGeneralNameValue(gn));
+ }
+ }
+ return pairs;
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ int num = getNumPoints();
+
+ for (int i = 0; i < num; i++) {
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(POINT_TYPE + ":");
+ sb.append(getConfig(CONFIG_POINT_TYPE + i));
+ sb.append(",");
+ sb.append(POINT_NAME + ":");
+ sb.append(getConfig(CONFIG_POINT_NAME + i));
+ sb.append(",");
+ sb.append(ISSUER_TYPE + ":");
+ sb.append(getConfig(CONFIG_ISSUER_TYPE + i));
+ sb.append(",");
+ sb.append(ISSUER_NAME + ":");
+ sb.append(getConfig(CONFIG_ISSUER_NAME + i));
+ sb.append(",");
+ sb.append(ENABLE + ":");
+ sb.append(getConfig(CONFIG_ENABLE + i));
+ sb.append("}");
+ }
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_FRESHEST_CRL_EXT",
+ getConfig(CONFIG_CRITICAL),
+ sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ FreshestCRLExtension ext = createExtension(request);
+
+ if (ext == null)
+ return;
+ addExtension(FreshestCRLExtension.OID, ext, info);
+ }
+
+ public FreshestCRLExtension createExtension(IRequest request) {
+ FreshestCRLExtension ext = new FreshestCRLExtension();
+ int num = 0;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ ext.setCritical(critical);
+
+ num = getNumPoints();
+ for (int i = 0; i < num; i++) {
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ String enable = getConfig(CONFIG_ENABLE + i);
+ String pointType = getConfig(CONFIG_POINT_TYPE + i);
+ String pointName = getConfig(CONFIG_POINT_NAME + i);
+ String issuerType = getConfig(CONFIG_ISSUER_TYPE + i);
+ String issuerName = getConfig(CONFIG_ISSUER_NAME + i);
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(getLocale(request), cdp, pointType, pointName);
+ if (issuerType != null)
+ addIssuer(getLocale(request), cdp, issuerType, issuerName);
+
+ ext.addPoint(cdp);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("FreshestCRLExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ private void populate(Locale locale, X509CertInfo info)
+ throws EProfileException {
+ FreshestCRLExtension ext = createExtension(locale);
+
+ if (ext == null)
+ return;
+ addExtension(FreshestCRLExtension.OID, ext, info);
+ }
+
+ public FreshestCRLExtension createExtension(Locale locale) {
+ FreshestCRLExtension ext = new FreshestCRLExtension();
+ int num = 0;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ ext.setCritical(critical);
+
+ num = getNumPoints();
+ for (int i = 0; i < num; i++) {
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ String enable = getConfig(CONFIG_ENABLE + i);
+ String pointType = getConfig(CONFIG_POINT_TYPE + i);
+ String pointName = getConfig(CONFIG_POINT_NAME + i);
+ String issuerType = getConfig(CONFIG_ISSUER_TYPE + i);
+ String issuerName = getConfig(CONFIG_ISSUER_NAME + i);
+
+ if (enable != null && enable.equals("true")) {
+ if (pointType != null)
+ addCRLPoint(locale, cdp, pointType, pointName);
+ if (issuerType != null)
+ addIssuer(locale, cdp, issuerType, issuerName);
+
+ ext.addPoint(cdp);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("FreshestCRLExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java
new file mode 100644
index 000000000..3403767b7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java
@@ -0,0 +1,260 @@
+// --- 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.def;
+
+
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Netscape comment extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenericExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "genericExtCritical";
+ public static final String CONFIG_OID = "genericExtOID";
+ public static final String CONFIG_DATA = "genericExtData";
+
+ public static final String VAL_CRITICAL = "genericExtCritical";
+ public static final String VAL_DATA = "genericExtData";
+
+ public GenericExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_DATA);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_OID);
+ addConfigName(CONFIG_DATA);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_OID)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "Comment Here...",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OID"));
+ } else if (name.equals(CONFIG_DATA)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "Comment Here...",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXT_VALUE"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_DATA)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXT_VALUE"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ Extension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = new ObjectIdentifier(getConfig(CONFIG_OID));
+
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+ if (ext == null) {
+ return;
+ }
+ boolean val = Boolean.valueOf(value).booleanValue();
+ ext.setCritical(val);
+ } else if (name.equals(VAL_DATA)) {
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+ if (ext == null) {
+ return;
+ }
+ byte data[] = getBytes(value);
+ ext.setExtensionValue(data);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(ext.getExtensionId().toString(), ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("GenericExtDefault: setValue " + e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ Extension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = new ObjectIdentifier(getConfig(CONFIG_OID));
+
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_DATA)) {
+
+ ext = (Extension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ byte data[] = ext.getExtensionValue();
+
+ if (data == null)
+ return "";
+
+ return toStr(data);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_OID),
+ getConfig(CONFIG_DATA)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_GENERIC_EXT", params);
+ }
+
+ public String toStr(byte data[]) {
+ StringBuffer b = new StringBuffer();
+ for (int i = 0; i < data.length; i++) {
+ if ((data[i] & 0xff) < 16) {
+ b.append("0");
+ }
+ b.append(Integer.toString((int)(data[i] & 0xff), 0x10));
+ }
+ return b.toString();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ Extension ext = createExtension(request);
+
+ addExtension(ext.getExtensionId().toString(), ext, info);
+ }
+
+ public Extension createExtension(IRequest request) {
+ Extension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ ObjectIdentifier oid = new ObjectIdentifier(getConfig(CONFIG_OID));
+ byte data[] = null;
+
+ if (request == null) {
+ data = getBytes(getConfig(CONFIG_DATA));
+ } else {
+ data = getBytes(mapPattern(request, getConfig(CONFIG_DATA)));
+ }
+
+ DerOutputStream out = new DerOutputStream();
+ out.putOctetString(data);
+
+ ext = new Extension(oid, critical, out.toByteArray());
+ } catch (Exception e) {
+ CMS.debug("GenericExtDefault: createExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/ImageDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/ImageDefault.java
new file mode 100644
index 000000000..95f670386
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/ImageDefault.java
@@ -0,0 +1,106 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.text.*;
+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 com.netscape.cms.profile.common.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that shows an image in the approval page.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ImageDefault extends EnrollDefault {
+
+ public static final String INPUT_IMAGE_URL = "image_url";
+
+ public static final String VAL_IMAGE_URL = "pd_image_url";
+
+ public ImageDefault() {
+ super();
+ addValueName(VAL_IMAGE_URL);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_IMAGE_URL)) {
+ return new Descriptor(IDescriptor.IMAGE_URL, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_IMAGE"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EPropertyException {
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ if (name.equals(VAL_IMAGE_URL)) {
+ return request.getExtDataInString(INPUT_IMAGE_URL);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ return null;
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_IMAGE" );
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java
new file mode 100644
index 000000000..493383b3e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java
@@ -0,0 +1,272 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+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.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an inhibit Any-Policy extension
+ *
+ * @version $Revision$, $Date$
+ */
+public class InhibitAnyPolicyExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "critical";
+ public static final String CONFIG_SKIP_CERTS = "skipCerts";
+
+ public static final String VAL_CRITICAL = "critical";
+ public static final String VAL_SKIP_CERTS = "skipCerts";
+
+ private static final String SKIP_CERTS = "Skip Certs";
+ private static final String GN_PATTERN = "Pattern";
+
+ public InhibitAnyPolicyExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_SKIP_CERTS);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_SKIP_CERTS);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_SKIP_CERTS)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "0",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SKIP_CERTS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (name.equals(CONFIG_SKIP_CERTS)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_SKIP_CERTS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null, "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_SKIP_CERTS)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "0",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SKIP_CERTS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ InhibitAnyPolicyExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ boolean critical = Boolean.valueOf(value).booleanValue();
+
+ ext.setCritical(critical);
+ } else if (name.equals(VAL_SKIP_CERTS)) {
+ ext = (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ boolean critical = ext.isCritical();
+ if (value.equals("")) {
+ // if value is empty, do not add this extension
+ deleteExtension(InhibitAnyPolicyExtension.OID, info);
+ return;
+ }
+ BigInt num = null;
+ try {
+ BigInteger l = new BigInteger(value);
+ num = new BigInt(l);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ ext = new InhibitAnyPolicyExtension(critical,
+ num);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ replaceExtension(InhibitAnyPolicyExtension.OID, ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("InhibitAnyPolicyExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ InhibitAnyPolicyExtension ext =
+ (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_SKIP_CERTS)) {
+ ext = (InhibitAnyPolicyExtension)
+ getExtension(InhibitAnyPolicyExtension.OID, info);
+ if (ext == null) {
+ return null;
+ }
+
+ BigInt n = ext.getSkipCerts();
+ return ""+n.toInt();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ /*
+ * returns text that goes into description for this extension on
+ * a profile
+ */
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(SKIP_CERTS + ":");
+ sb.append(getConfig(CONFIG_SKIP_CERTS));
+
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_INHIBIT_ANY_POLICY_EXT",
+ getConfig(CONFIG_CRITICAL), sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ InhibitAnyPolicyExtension ext = null;
+
+ ext = createExtension(request);
+ addExtension(InhibitAnyPolicyExtension.OID, ext, info);
+ }
+
+ public InhibitAnyPolicyExtension createExtension(IRequest request)
+ throws EProfileException {
+ InhibitAnyPolicyExtension ext = null;
+
+ boolean critical = Boolean.valueOf(
+ getConfig(CONFIG_CRITICAL)).booleanValue();
+
+ String str = getConfig(CONFIG_SKIP_CERTS);
+ if (str == null || str.equals("")) {
+ ext = new InhibitAnyPolicyExtension();
+ ext.setCritical(critical);
+ } else {
+ BigInt val = null;
+ try {
+ BigInteger b = new BigInteger(str);
+ val = new BigInt(b);
+ } catch (NumberFormatException e) {
+ throw new EProfileException(
+ CMS.getUserMessage("CMS_PROFILE_INHIBIT_ANY_POLICY_WRONG_SKIP_CERTS"));
+ }
+
+ try {
+ ext = new InhibitAnyPolicyExtension(critical, val);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java
new file mode 100644
index 000000000..16a5fe2be
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java
@@ -0,0 +1,313 @@
+// --- 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.def;
+
+
+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.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a issuer alternative name extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class IssuerAltNameExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "issuerAltNameExtCritical";
+ public static final String CONFIG_TYPE = "issuerAltExtType";
+ public static final String CONFIG_PATTERN = "issuerAltExtPattern";
+
+ public static final String VAL_CRITICAL = "issuerAltNameExtCritical";
+ public static final String VAL_GENERAL_NAMES = "issuerAltNames";
+
+ public IssuerAltNameExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_GENERAL_NAMES);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_TYPE);
+ addConfigName(CONFIG_PATTERN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_TYPE)) {
+ return new Descriptor(IDescriptor.CHOICE, "RFC822Name,DNSName,DirectoryName,EDIPartyName,URIName,IPAddress,OIDName",
+ "RFC822Name",
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_ISSUER_ALT_NAME_TYPE"));
+ } else if (name.equals(CONFIG_PATTERN)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_ISSUER_ALT_NAME_PATTERN"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GENERAL_NAMES"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ IssuerAlternativeNameExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ boolean critical = Boolean.valueOf(value).booleanValue();
+
+ ext.setCritical(critical);
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ if (value.equals("")) {
+ // if value is empty, do not add this extension
+ deleteExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+ return;
+ }
+ GeneralNames gn = new GeneralNames();
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+
+ while (st.hasMoreTokens()) {
+ String gname = (String) st.nextToken();
+
+ GeneralNameInterface n = parseGeneralName(gname);
+ if (n != null) {
+ gn.addElement(n);
+ }
+ }
+ ext.set(IssuerAlternativeNameExtension.ISSUER_NAME, gn);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ replaceExtension(
+ PKIXExtensions.IssuerAlternativeName_Id.toString(),
+ ext, info);
+ } catch (IOException e) {
+ CMS.debug("IssuerAltNameExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("IssuerAltNameExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ try {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ IssuerAlternativeNameExtension ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+
+ if(ext == null)
+ {
+
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ ext =
+ (IssuerAlternativeNameExtension)
+ getExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(), info);
+ if(ext == null)
+ {
+ return "";
+ }
+
+ GeneralNames names = (GeneralNames)
+ ext.get(IssuerAlternativeNameExtension.ISSUER_NAME);
+ StringBuffer sb = new StringBuffer();
+ Enumeration e = names.elements();
+
+ while (e.hasMoreElements()) {
+ GeneralName gn = (GeneralName) e.nextElement();
+
+ if (!sb.toString().equals("")) {
+ sb.append("\r\n");
+ }
+ sb.append(toGeneralNameString(gn));
+ }
+ return sb.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (IOException e) {
+ CMS.debug("IssuerAltNameExtDefault: getValue " +
+ e.toString());
+ }
+ return null;
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_PATTERN),
+ getConfig(CONFIG_TYPE)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_ISSUER_ALT_NAME_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ IssuerAlternativeNameExtension ext = null;
+
+ try {
+ ext = createExtension(request);
+
+ } catch (IOException e) {
+ CMS.debug("IssuerAltNameExtDefault: populate " + e.toString());
+ }
+ addExtension(PKIXExtensions.IssuerAlternativeName_Id.toString(),
+ ext, info);
+ }
+
+ public IssuerAlternativeNameExtension createExtension(IRequest request)
+ throws IOException {
+ IssuerAlternativeNameExtension ext = null;
+
+ try {
+ ext = new IssuerAlternativeNameExtension();
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ throw new IOException( e.toString() );
+ }
+ boolean critical = Boolean.valueOf(
+ getConfig(CONFIG_CRITICAL)).booleanValue();
+ String pattern = getConfig(CONFIG_PATTERN);
+
+ if (!pattern.equals("")) {
+ GeneralNames gn = new GeneralNames();
+
+ String gname = "";
+
+ if(request != null) {
+ gname = mapPattern(request, pattern);
+ }
+
+ gn.addElement(parseGeneralName(
+ getConfig(CONFIG_TYPE) + ":" + gname));
+ ext.set(IssuerAlternativeNameExtension.ISSUER_NAME, gn);
+ }
+ ext.setCritical(critical);
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java
new file mode 100644
index 000000000..286913c5a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java
@@ -0,0 +1,509 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Key Usage extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyUsageExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "keyUsageCritical";
+ public static final String CONFIG_DIGITAL_SIGNATURE =
+ "keyUsageDigitalSignature";
+ public static final String CONFIG_NON_REPUDIATION =
+ "keyUsageNonRepudiation";
+ public static final String CONFIG_KEY_ENCIPHERMENT =
+ "keyUsageKeyEncipherment";
+ public static final String CONFIG_DATA_ENCIPHERMENT =
+ "keyUsageDataEncipherment";
+ public static final String CONFIG_KEY_AGREEMENT = "keyUsageKeyAgreement";
+ public static final String CONFIG_KEY_CERTSIGN = "keyUsageKeyCertSign";
+ public static final String CONFIG_CRL_SIGN = "keyUsageCrlSign";
+ public static final String CONFIG_ENCIPHER_ONLY = "keyUsageEncipherOnly";
+ public static final String CONFIG_DECIPHER_ONLY = "keyUsageDecipherOnly";
+
+ public static final String VAL_CRITICAL = "keyUsageCritical";
+ public static final String VAL_DIGITAL_SIGNATURE =
+ "keyUsageDigitalSignature";
+ public static final String VAL_NON_REPUDIATION =
+ "keyUsageNonRepudiation";
+ public static final String VAL_KEY_ENCIPHERMENT =
+ "keyUsageKeyEncipherment";
+ public static final String VAL_DATA_ENCIPHERMENT =
+ "keyUsageDataEncipherment";
+ public static final String VAL_KEY_AGREEMENT = "keyUsageKeyAgreement";
+ public static final String VAL_KEY_CERTSIGN = "keyUsageKeyCertSign";
+ public static final String VAL_CRL_SIGN = "keyUsageCrlSign";
+ public static final String VAL_ENCIPHER_ONLY = "keyUsageEncipherOnly";
+ public static final String VAL_DECIPHER_ONLY = "keyUsageDecipherOnly";
+
+ public KeyUsageExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_DIGITAL_SIGNATURE);
+ addValueName(VAL_NON_REPUDIATION);
+ addValueName(VAL_KEY_ENCIPHERMENT);
+ addValueName(VAL_DATA_ENCIPHERMENT);
+ addValueName(VAL_KEY_AGREEMENT);
+ addValueName(VAL_KEY_CERTSIGN);
+ addValueName(VAL_CRL_SIGN);
+ addValueName(VAL_ENCIPHER_ONLY);
+ addValueName(VAL_DECIPHER_ONLY);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_DIGITAL_SIGNATURE);
+ addConfigName(CONFIG_NON_REPUDIATION);
+ addConfigName(CONFIG_KEY_ENCIPHERMENT);
+ addConfigName(CONFIG_DATA_ENCIPHERMENT);
+ addConfigName(CONFIG_KEY_AGREEMENT);
+ addConfigName(CONFIG_KEY_CERTSIGN);
+ addConfigName(CONFIG_CRL_SIGN);
+ addConfigName(CONFIG_ENCIPHER_ONLY);
+ addConfigName(CONFIG_DECIPHER_ONLY);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_DIGITAL_SIGNATURE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DIGITAL_SIGNATURE"));
+ } else if (name.equals(CONFIG_NON_REPUDIATION)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NON_REPUDIATION"));
+ } else if (name.equals(CONFIG_KEY_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_ENCIPHERMENT"));
+ } else if (name.equals(CONFIG_DATA_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DATA_ENCIPHERMENT"));
+ } else if (name.equals(CONFIG_KEY_AGREEMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_AGREEMENT"));
+ } else if (name.equals(CONFIG_KEY_CERTSIGN)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_CERTSIGN"));
+ } else if (name.equals(CONFIG_CRL_SIGN)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRL_SIGN"));
+ } else if (name.equals(CONFIG_ENCIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENCIPHER_ONLY"));
+ } else if (name.equals(CONFIG_DECIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DECIPHER_ONLY"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_DIGITAL_SIGNATURE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DIGITAL_SIGNATURE"));
+ } else if (name.equals(VAL_NON_REPUDIATION)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NON_REPUDIATION"));
+ } else if (name.equals(VAL_KEY_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_ENCIPHERMENT"));
+ } else if (name.equals(VAL_DATA_ENCIPHERMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DATA_ENCIPHERMENT"));
+ } else if (name.equals(VAL_KEY_AGREEMENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_AGREEMENT"));
+ } else if (name.equals(VAL_KEY_CERTSIGN)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_CERTSIGN"));
+ } else if (name.equals(VAL_CRL_SIGN)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRL_SIGN"));
+ } else if (name.equals(VAL_ENCIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENCIPHER_ONLY"));
+ } else if (name.equals(VAL_DECIPHER_ONLY)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_DECIPHER_ONLY"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ KeyUsageExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_DIGITAL_SIGNATURE)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.DIGITAL_SIGNATURE, val);
+ } else if (name.equals(VAL_NON_REPUDIATION)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.NON_REPUDIATION, val);
+ } else if (name.equals(VAL_KEY_ENCIPHERMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.KEY_ENCIPHERMENT, val);
+ } else if (name.equals(VAL_DATA_ENCIPHERMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.DATA_ENCIPHERMENT, val);
+ } else if (name.equals(VAL_KEY_AGREEMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.KEY_AGREEMENT, val);
+ } else if (name.equals(VAL_KEY_CERTSIGN)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.KEY_CERTSIGN, val);
+ } else if (name.equals(VAL_CRL_SIGN)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.CRL_SIGN, val);
+ } else if (name.equals(VAL_ENCIPHER_ONLY)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.ENCIPHER_ONLY, val);
+ } else if (name.equals(VAL_DECIPHER_ONLY)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if(ext == null) {
+ return;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(KeyUsageExtension.DECIPHER_ONLY, val);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.KeyUsage_Id.toString(), ext, info);
+ } catch (IOException e) {
+ CMS.debug("KeyUsageExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("KeyUsageExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ try {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ KeyUsageExtension ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_DIGITAL_SIGNATURE)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.DIGITAL_SIGNATURE);
+
+ return val.toString();
+ } else if (name.equals(VAL_NON_REPUDIATION)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.NON_REPUDIATION);
+
+ return val.toString();
+ } else if (name.equals(VAL_KEY_ENCIPHERMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.KEY_ENCIPHERMENT);
+
+ return val.toString();
+ } else if (name.equals(VAL_DATA_ENCIPHERMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.DATA_ENCIPHERMENT);
+
+ return val.toString();
+ } else if (name.equals(VAL_KEY_AGREEMENT)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.KEY_AGREEMENT);
+
+ return val.toString();
+ } else if (name.equals(VAL_KEY_CERTSIGN)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.KEY_CERTSIGN);
+
+ return val.toString();
+ } else if (name.equals(VAL_CRL_SIGN)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.CRL_SIGN);
+
+ return val.toString();
+ } else if (name.equals(VAL_ENCIPHER_ONLY)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.ENCIPHER_ONLY);
+
+ return val.toString();
+ } else if (name.equals(VAL_DECIPHER_ONLY)) {
+ ext = (KeyUsageExtension)
+ getExtension(PKIXExtensions.KeyUsage_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean)
+ ext.get(KeyUsageExtension.DECIPHER_ONLY);
+
+ return val.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (IOException e) {
+ CMS.debug("KeyUsageExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_DIGITAL_SIGNATURE),
+ getConfig(CONFIG_NON_REPUDIATION),
+ getConfig(CONFIG_KEY_ENCIPHERMENT),
+ getConfig(CONFIG_DATA_ENCIPHERMENT),
+ getConfig(CONFIG_KEY_AGREEMENT),
+ getConfig(CONFIG_KEY_CERTSIGN),
+ getConfig(CONFIG_CRL_SIGN),
+ getConfig(CONFIG_ENCIPHER_ONLY),
+ getConfig(CONFIG_DECIPHER_ONLY)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_KEY_USAGE_EXT", params);
+
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ KeyUsageExtension ext = createKeyUsageExtension();
+
+ addExtension(PKIXExtensions.KeyUsage_Id.toString(), ext, info);
+ }
+
+ public KeyUsageExtension createKeyUsageExtension() {
+ KeyUsageExtension ext = null;
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ bits[0] = getConfigBoolean(CONFIG_DIGITAL_SIGNATURE);
+ bits[1] = getConfigBoolean(CONFIG_NON_REPUDIATION);
+ bits[2] = getConfigBoolean(CONFIG_KEY_ENCIPHERMENT);
+ bits[3] = getConfigBoolean(CONFIG_DATA_ENCIPHERMENT);
+ bits[4] = getConfigBoolean(CONFIG_KEY_AGREEMENT);
+ bits[5] = getConfigBoolean(CONFIG_KEY_CERTSIGN);
+ bits[6] = getConfigBoolean(CONFIG_CRL_SIGN);
+ bits[7] = getConfigBoolean(CONFIG_ENCIPHER_ONLY);
+ bits[8] = getConfigBoolean(CONFIG_DECIPHER_ONLY);
+ try {
+ ext = new KeyUsageExtension(critical, bits);
+ } catch (Exception e) {
+ CMS.debug("KeyUsageExtDefault: createKeyUsageExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java
new file mode 100644
index 000000000..05449eec2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java
@@ -0,0 +1,247 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Netscape comment extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NSCCommentExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "nscCommentCritical";
+ public static final String CONFIG_COMMENT = "nscCommentContent";
+
+ public static final String VAL_CRITICAL = "nscCommentCritical";
+ public static final String VAL_COMMENT = "nscCommentContent";
+
+ public NSCCommentExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_COMMENT);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_COMMENT);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_COMMENT)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "Comment Here...",
+ CMS.getUserMessage(locale, "CMS_PROFILE_COMMENT"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_COMMENT)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_COMMENT"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ NSCCommentExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = NSCCommentExtension.OID;
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if (ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_COMMENT)) {
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return;
+ }
+ boolean critical = ext.isCritical();
+
+ if (value == null || value.equals(""))
+ ext = new NSCCommentExtension(critical, "");
+ // throw new EPropertyException(name+" cannot be empty");
+ else
+ ext = new NSCCommentExtension(critical, value);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(ext.getExtensionId().toString(), ext, info);
+ } catch (IOException e) {
+ CMS.debug("NSCCommentExtDefault: setValue " + e.toString());
+ } catch (EProfileException e) {
+ CMS.debug("NSCCommentExtDefault: setValue " + e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ NSCCommentExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = NSCCommentExtension.OID;
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_COMMENT)) {
+
+ ext = (NSCCommentExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ String comment = ext.getComment();
+
+ if (comment == null)
+ comment = "";
+
+ return comment;
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_COMMENT)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_NS_COMMENT_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ NSCCommentExtension ext = createExtension();
+
+ addExtension(ext.getExtensionId().toString(), ext, info);
+ }
+
+ public NSCCommentExtension createExtension() {
+ NSCCommentExtension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ String comment = getConfig(CONFIG_COMMENT);
+
+ if (comment == null || comment.equals(""))
+ ext = new NSCCommentExtension(critical, "");
+ else
+ ext = new NSCCommentExtension(critical, comment);
+ } catch (Exception e) {
+ CMS.debug("NSCCommentExtension: createExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java
new file mode 100644
index 000000000..1c38dedce
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java
@@ -0,0 +1,421 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+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.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Netscape Certificate Type extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NSCertTypeExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "nsCertCritical";
+ public static final String CONFIG_SSL_CLIENT = "nsCertSSLClient";
+ public static final String CONFIG_SSL_SERVER = "nsCertSSLServer";
+ public static final String CONFIG_EMAIL = "nsCertEmail";
+ public static final String CONFIG_OBJECT_SIGNING = "nsCertObjectSigning";
+ public static final String CONFIG_SSL_CA = "nsCertSSLCA";
+ public static final String CONFIG_EMAIL_CA = "nsCertEmailCA";
+ public static final String CONFIG_OBJECT_SIGNING_CA = "nsCertObjectSigningCA";
+
+ public static final String VAL_CRITICAL = "nsCertCritical";
+ public static final String VAL_SSL_CLIENT = "nsCertSSLClient";
+ public static final String VAL_SSL_SERVER = "nsCertSSLServer";
+ public static final String VAL_EMAIL = "nsCertEmail";
+ public static final String VAL_OBJECT_SIGNING = "nsCertObjectSigning";
+ public static final String VAL_SSL_CA = "nsCertSSLCA";
+ public static final String VAL_EMAIL_CA = "nsCertEmailCA";
+ public static final String VAL_OBJECT_SIGNING_CA = "nsCertObjectSigningCA";
+
+ public NSCertTypeExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_SSL_CLIENT);
+ addValueName(VAL_SSL_SERVER);
+ addValueName(VAL_EMAIL);
+ addValueName(VAL_OBJECT_SIGNING);
+ addValueName(VAL_SSL_CA);
+ addValueName(VAL_EMAIL_CA);
+ addValueName(VAL_OBJECT_SIGNING_CA);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_SSL_CLIENT);
+ addConfigName(CONFIG_SSL_SERVER);
+ addConfigName(CONFIG_EMAIL);
+ addConfigName(CONFIG_OBJECT_SIGNING);
+ addConfigName(CONFIG_SSL_CA);
+ addConfigName(CONFIG_EMAIL_CA);
+ addConfigName(CONFIG_OBJECT_SIGNING_CA);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_SSL_CLIENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CLIENT"));
+ } else if (name.equals(CONFIG_SSL_SERVER)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_SERVER"));
+ } else if (name.equals(CONFIG_EMAIL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL"));
+ } else if (name.equals(CONFIG_OBJECT_SIGNING)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OBJECT_SIGNING"));
+ } else if (name.equals(CONFIG_SSL_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CA"));
+ } else if (name.equals(CONFIG_EMAIL_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL_CA"));
+ } else if (name.equals(CONFIG_OBJECT_SIGNING_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OBJECT_SIGNING_CA"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_SSL_CLIENT)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CLIENT"));
+ } else if (name.equals(VAL_SSL_SERVER)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_SERVER"));
+ } else if (name.equals(VAL_EMAIL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL"));
+ } else if (name.equals(VAL_OBJECT_SIGNING)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OBJECT_SIGNING"));
+ } else if (name.equals(VAL_SSL_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SSL_CA"));
+ } else if (name.equals(VAL_EMAIL_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_EMAIL_CA"));
+ } else if (name.equals(VAL_OBJECT_SIGNING_CA)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OBJECT_SIGNING_CA"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ NSCertTypeExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return ;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_SSL_CLIENT)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.SSL_CLIENT, val);
+ } else if (name.equals(VAL_SSL_SERVER)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.SSL_SERVER, val);
+ } else if (name.equals(VAL_EMAIL)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.EMAIL, val);
+ } else if (name.equals(VAL_OBJECT_SIGNING)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING, val);
+ } else if (name.equals(VAL_SSL_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.SSL_CA, val);
+ } else if (name.equals(VAL_EMAIL_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.EMAIL_CA, val);
+ } else if (name.equals(VAL_OBJECT_SIGNING_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if(ext == null) {
+ return ;
+ }
+ Boolean val = Boolean.valueOf(value);
+
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING_CA, val);
+ } else {
+ throw new EPropertyException("Invalid name " + name);
+ }
+ replaceExtension(NSCertTypeExtension.CertType_Id.toString(), ext, info);
+ } catch (CertificateException e) {
+ CMS.debug("NSCertTypeExtDefault: setValue " + e.toString());
+ } catch (EProfileException e) {
+ CMS.debug("NSCertTypeExtDefault: setValue " + e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ try {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ NSCertTypeExtension ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_SSL_CLIENT)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.SSL_CLIENT);
+
+ return val.toString();
+ } else if (name.equals(VAL_SSL_SERVER)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.SSL_SERVER);
+
+ return val.toString();
+ } else if (name.equals(VAL_EMAIL)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.EMAIL);
+
+ return val.toString();
+ } else if (name.equals(VAL_OBJECT_SIGNING)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.OBJECT_SIGNING);
+
+ return val.toString();
+ } else if (name.equals(VAL_SSL_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.SSL_CA);
+
+ return val.toString();
+ } else if (name.equals(VAL_EMAIL_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.EMAIL_CA);
+
+ return val.toString();
+ } else if (name.equals(VAL_OBJECT_SIGNING_CA)) {
+ ext = (NSCertTypeExtension)
+ getExtension(NSCertTypeExtension.CertType_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+ Boolean val = (Boolean) ext.get(NSCertTypeExtension.OBJECT_SIGNING_CA);
+
+ return val.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (CertificateException e) {
+ CMS.debug("NSCertTypeExtDefault: setValue " + e.toString());
+ }
+ return null;
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_SSL_CLIENT),
+ getConfig(CONFIG_SSL_SERVER),
+ getConfig(CONFIG_EMAIL),
+ getConfig(CONFIG_OBJECT_SIGNING),
+ getConfig(CONFIG_SSL_CA),
+ getConfig(CONFIG_EMAIL_CA),
+ getConfig(CONFIG_OBJECT_SIGNING_CA)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_NS_CERT_TYPE_EXT", params);
+
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ NSCertTypeExtension ext = createExtension();
+
+ addExtension(NSCertTypeExtension.CertType_Id.toString(), ext, info);
+ }
+
+ public NSCertTypeExtension createExtension() {
+ NSCertTypeExtension ext = null;
+ boolean[] bits = new boolean[NSCertTypeExtension.NBITS];
+
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ bits[0] = getConfigBoolean(CONFIG_SSL_CLIENT);
+ bits[1] = getConfigBoolean(CONFIG_SSL_SERVER);
+ bits[2] = getConfigBoolean(CONFIG_EMAIL);
+ bits[3] = getConfigBoolean(CONFIG_OBJECT_SIGNING);
+ bits[4] = getConfigBoolean(CONFIG_SSL_CA);
+ bits[5] = getConfigBoolean(CONFIG_EMAIL_CA);
+ bits[6] = getConfigBoolean(CONFIG_OBJECT_SIGNING_CA);
+ try {
+ ext = new NSCertTypeExtension(critical, bits);
+ } catch (Exception e) {
+ CMS.debug("NSCertTypeExtDefault: createExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java
new file mode 100644
index 000000000..21208b032
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java
@@ -0,0 +1,658 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a name constraint extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NameConstraintsExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "nameConstraintsCritical";
+ public static final String CONFIG_NUM_PERMITTED_SUBTREES =
+ "nameConstraintsNumPermittedSubtrees";
+ public static final String CONFIG_PERMITTED_MIN_VAL = "nameConstraintsPermittedSubtreeMinValue_";
+ public static final String CONFIG_PERMITTED_MAX_VAL = "nameConstraintsPermittedSubtreeMaxValue_";
+ public static final String CONFIG_PERMITTED_NAME_CHOICE = "nameConstraintsPermittedSubtreeNameChoice_";
+ public static final String CONFIG_PERMITTED_NAME_VAL = "nameConstraintsPermittedSubtreeNameValue_";
+ public static final String CONFIG_PERMITTED_ENABLE = "nameConstraintsPermittedSubtreeEnable_";
+
+ public static final String CONFIG_NUM_EXCLUDED_SUBTREES = "nameConstraintsNumExcludedSubtrees";
+ public static final String CONFIG_EXCLUDED_MIN_VAL = "nameConstraintsExcludedSubtreeMinValue_";
+ public static final String CONFIG_EXCLUDED_MAX_VAL = "nameConstraintsExcludedSubtreeMaxValue_";
+ public static final String CONFIG_EXCLUDED_NAME_CHOICE = "nameConstraintsExcludedSubtreeNameChoice_";
+ public static final String CONFIG_EXCLUDED_NAME_VAL = "nameConstraintsExcludedSubtreeNameValue_";
+ public static final String CONFIG_EXCLUDED_ENABLE = "nameConstraintsExcludedSubtreeEnable_";
+
+ public static final String VAL_CRITICAL = "nameConstraintsCritical";
+ public static final String VAL_PERMITTED_SUBTREES = "nameConstraintsPermittedSubtreesValue";
+ public static final String VAL_EXCLUDED_SUBTREES = "nameConstraintsExcludedSubtreesValue";
+
+ private static final String GENERAL_NAME_CHOICE = "GeneralNameChoice";
+ private static final String GENERAL_NAME_VALUE = "GeneralNameValue";
+ private static final String MIN_VALUE = "Min Value";
+ private static final String MAX_VALUE = "Max Value";
+ private static final String ENABLE = "Enable";
+
+ protected static final int DEF_NUM_PERMITTED_SUBTREES = 1;
+ protected static final int DEF_NUM_EXCLUDED_SUBTREES = 1;
+ protected static final int MAX_NUM_EXCLUDED_SUBTREES = 100;
+ protected static final int MAX_NUM_PERMITTED_SUBTREES = 100;
+
+ public NameConstraintsExtDefault() {
+ super();
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+
+ }
+
+ protected int getNumPermitted() {
+ int num = DEF_NUM_PERMITTED_SUBTREES;
+ String val = getConfig(CONFIG_NUM_PERMITTED_SUBTREES);
+
+ if (val != null) {
+ try {
+ num = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_PERMITTED_SUBTREES)
+ num = DEF_NUM_PERMITTED_SUBTREES;
+ return num;
+ }
+
+ protected int getNumExcluded() {
+ int num = DEF_NUM_EXCLUDED_SUBTREES;
+ String val = getConfig(CONFIG_NUM_EXCLUDED_SUBTREES);
+
+ if (val != null) {
+ try {
+ num = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_EXCLUDED_SUBTREES)
+ num = DEF_NUM_EXCLUDED_SUBTREES;
+
+ return num;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_PERMITTED_SUBTREES)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_PERMITTED_SUBTREES || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_PERMITTED_SUBTREES));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_PERMITTED_SUBTREES));
+ }
+ } else if(name.equals(CONFIG_NUM_EXCLUDED_SUBTREES)) {
+
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_EXCLUDED_SUBTREES || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_EXCLUDED_SUBTREES));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_EXCLUDED_SUBTREES));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ //refesh our config name list
+
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_PERMITTED_SUBTREES);
+ addValueName(VAL_EXCLUDED_SUBTREES);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumPermitted();
+
+ addConfigName(CONFIG_NUM_PERMITTED_SUBTREES);
+
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_PERMITTED_MIN_VAL + i);
+ addConfigName(CONFIG_PERMITTED_MAX_VAL + i);
+ addConfigName(CONFIG_PERMITTED_NAME_CHOICE + i);
+ addConfigName(CONFIG_PERMITTED_NAME_VAL + i);
+ addConfigName(CONFIG_PERMITTED_ENABLE + i);
+ }
+
+ num = getNumExcluded();
+
+ addConfigName(CONFIG_NUM_EXCLUDED_SUBTREES);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_EXCLUDED_MIN_VAL + i);
+ addConfigName(CONFIG_EXCLUDED_MAX_VAL + i);
+ addConfigName(CONFIG_EXCLUDED_NAME_CHOICE + i);
+ addConfigName(CONFIG_EXCLUDED_NAME_VAL + i);
+ addConfigName(CONFIG_EXCLUDED_ENABLE + i);
+ }
+
+ }
+
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_PERMITTED_MIN_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_PERMITTED_MIN_VAL"));
+ } else if (name.startsWith(CONFIG_PERMITTED_MAX_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_PERMITTED_MAX_VAL"));
+ } else if (name.startsWith(CONFIG_PERMITTED_NAME_CHOICE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_PERMITTED_NAME_CHOICE"));
+ } else if (name.startsWith(CONFIG_PERMITTED_NAME_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_PERMITTED_NAME_VAL"));
+ } else if (name.startsWith(CONFIG_PERMITTED_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_EXCLUDED_MIN_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXCLUDED_MIN_VAL"));
+ } else if (name.startsWith(CONFIG_EXCLUDED_MAX_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXCLUDED_MAX_VAL"));
+ } else if (name.startsWith(CONFIG_EXCLUDED_NAME_CHOICE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXCLUDED_NAME_CHOICE"));
+ } else if (name.startsWith(CONFIG_EXCLUDED_NAME_VAL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXCLUDED_NAME_VAL"));
+ } else if (name.startsWith(CONFIG_EXCLUDED_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_EXCLUDED_SUBTREES)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_EXCLUDED_SUBTREES"));
+ } else if (name.startsWith(CONFIG_NUM_PERMITTED_SUBTREES)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_PERMITTED_SUBTREES"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_PERMITTED_SUBTREES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_PERMITTED_SUBTREES"));
+ } else if (name.equals(VAL_EXCLUDED_SUBTREES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_EXCLUDED_SUBTREES"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ NameConstraintsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_PERMITTED_SUBTREES)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if(ext == null) {
+ return;
+ }
+ Vector v = parseRecords(value);
+
+ Vector permittedSubtrees = createSubtrees(locale, v);
+
+ ext.set(NameConstraintsExtension.PERMITTED_SUBTREES,
+ new GeneralSubtrees(permittedSubtrees));
+ } else if (name.equals(VAL_EXCLUDED_SUBTREES)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if(ext == null) {
+ return;
+ }
+ Vector v = parseRecords(value);
+
+ Vector excludedSubtrees = createSubtrees(locale, v);
+
+ ext.set(NameConstraintsExtension.EXCLUDED_SUBTREES,
+ new GeneralSubtrees(excludedSubtrees));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.NameConstraints_Id.toString(), ext, info);
+ } catch (IOException e) {
+ CMS.debug("NameConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("NameConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ private Vector createSubtrees(Locale locale, Vector v) throws EPropertyException {
+ int size = v.size();
+ String choice = null;
+ String val = "";
+ String minS = null;
+ String maxS = null;
+
+ Vector subtrees = new Vector();
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(GENERAL_NAME_CHOICE)) {
+ choice = nvps.getValue(name1);
+ } else if (name1.equals(GENERAL_NAME_VALUE)) {
+ val = nvps.getValue(name1);
+ } else if (name1.equals(MIN_VALUE)) {
+ minS = nvps.getValue(name1);
+ } else if (name1.equals(MAX_VALUE)) {
+ maxS = nvps.getValue(name1);
+ }
+ }
+
+ if (choice == null || choice.length() == 0) {
+ throw new EPropertyException(CMS.getUserMessage(locale,
+ "CMS_PROFILE_GENERAL_NAME_NOT_FOUND"));
+ }
+
+ if (val == null)
+ val = "";
+
+ int min = 0;
+ int max = -1;
+
+ if (minS != null && minS.length() > 0)
+ min = Integer.parseInt(minS);
+ if (maxS != null && maxS.length() > 0)
+ max = Integer.parseInt(maxS);
+
+ GeneralName gn = null;
+ GeneralNameInterface gnI = null;
+
+ try {
+ gnI = parseGeneralName(choice + ":" + val);
+ } catch (IOException e) {
+ CMS.debug("NameConstraintsExtDefault: createSubtress " +
+ e.toString());
+ }
+
+ if (gnI != null) {
+ gn = new GeneralName(gnI);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(locale,
+ "CMS_PROFILE_GENERAL_NAME_NOT_FOUND"));
+ }
+ GeneralSubtree subtree = new GeneralSubtree(
+ gn, min, max);
+
+ subtrees.addElement(subtree);
+ }
+
+ return subtrees;
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ NameConstraintsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_PERMITTED_SUBTREES)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ GeneralSubtrees subtrees = null;
+
+ try {
+ subtrees = (GeneralSubtrees)
+ ext.get(NameConstraintsExtension.PERMITTED_SUBTREES);
+ } catch (IOException e) {
+ CMS.debug("NameConstraintExtDefault: getValue " + e.toString());
+ }
+
+ if( subtrees == null ) {
+ CMS.debug( "NameConstraintsExtDefault::getValue() VAL_PERMITTED_SUBTREES is null!" );
+ throw new EPropertyException( "subtrees is null" );
+ }
+
+ return getSubtreesInfo(ext, subtrees);
+ } else if (name.equals(VAL_EXCLUDED_SUBTREES)) {
+ ext = (NameConstraintsExtension)
+ getExtension(PKIXExtensions.NameConstraints_Id.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ GeneralSubtrees subtrees = null;
+
+ try {
+ subtrees = (GeneralSubtrees)
+ ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES);
+ } catch (IOException e) {
+ CMS.debug("NameConstraintExtDefault: getValue " + e.toString());
+ }
+
+ if( subtrees == null ) {
+ CMS.debug( "NameConstraintsExtDefault::getValue() VAL_EXCLUDED_SUBTREES is null!" );
+ throw new EPropertyException( "subtrees is null" );
+ }
+
+ return getSubtreesInfo(ext, subtrees);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ private String getSubtreesInfo(NameConstraintsExtension ext,
+ GeneralSubtrees subtrees) throws EPropertyException {
+ Vector trees = subtrees.getSubtrees();
+ int size = trees.size();
+
+ Vector recs = new Vector();
+
+ for (int i = 0; i < size; i++) {
+ GeneralSubtree tree = (GeneralSubtree) trees.elementAt(i);
+
+ GeneralName gn = tree.getGeneralName();
+ String type = getGeneralNameType(gn);
+ int max = tree.getMaxValue();
+ int min = tree.getMinValue();
+
+ NameValuePairs pairs = new NameValuePairs();
+
+ pairs.add(GENERAL_NAME_CHOICE, type);
+ pairs.add(GENERAL_NAME_VALUE, getGeneralNameValue(gn));
+ pairs.add(MIN_VALUE, Integer.toString(min));
+ pairs.add(MAX_VALUE, Integer.toString(max));
+ pairs.add(ENABLE, "true");
+
+ recs.addElement(pairs);
+ }
+
+ return buildRecords(recs);
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ int num = getNumPermitted();
+
+ for (int i = 0; i < num; i++) {
+ sb.append("Permitted #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(GENERAL_NAME_CHOICE + ":");
+ sb.append(getConfig(CONFIG_PERMITTED_NAME_CHOICE + i));
+ sb.append(",");
+ sb.append(GENERAL_NAME_VALUE + ":");
+ sb.append(getConfig(CONFIG_PERMITTED_NAME_VAL + i));
+ sb.append(",");
+ sb.append(MIN_VALUE + ":");
+ sb.append(getConfig(CONFIG_PERMITTED_MIN_VAL + i));
+ sb.append(",");
+ sb.append(MAX_VALUE + ":");
+ sb.append(getConfig(CONFIG_PERMITTED_MAX_VAL + i));
+ sb.append("}");
+ }
+ num = getNumExcluded();
+ for (int i = 0; i < num; i++) {
+ sb.append("Exluded #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(GENERAL_NAME_CHOICE + ":");
+ sb.append(getConfig(CONFIG_EXCLUDED_NAME_CHOICE + i));
+ sb.append(",");
+ sb.append(GENERAL_NAME_VALUE + ":");
+ sb.append(getConfig(CONFIG_EXCLUDED_NAME_VAL + i));
+ sb.append(",");
+ sb.append(MIN_VALUE + ":");
+ sb.append(getConfig(CONFIG_EXCLUDED_MIN_VAL + i));
+ sb.append(",");
+ sb.append(MAX_VALUE + ":");
+ sb.append(getConfig(CONFIG_EXCLUDED_MAX_VAL + i));
+ sb.append("}");
+ }
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_NAME_CONSTRAINTS_EXT",
+ getConfig(CONFIG_CRITICAL), sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ NameConstraintsExtension ext = createExtension();
+
+ addExtension(PKIXExtensions.NameConstraints_Id.toString(), ext, info);
+ }
+
+ public NameConstraintsExtension createExtension() {
+ NameConstraintsExtension ext = null;
+
+ try {
+ int num = getNumPermitted();
+
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ Vector v = new Vector();
+
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_PERMITTED_ENABLE + i);
+
+ if (enable != null && enable.equals("true")) {
+ String choice = getConfig(CONFIG_PERMITTED_NAME_CHOICE + i);
+ String value = getConfig(CONFIG_PERMITTED_NAME_VAL + i);
+ String minS = getConfig(CONFIG_PERMITTED_MIN_VAL + i);
+ String maxS = getConfig(CONFIG_PERMITTED_MAX_VAL + i);
+
+ v.addElement(createSubtree(choice, value, minS, maxS));
+ }
+ }
+
+ Vector v1 = new Vector();
+
+ num = getNumExcluded();
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_EXCLUDED_ENABLE + i);
+
+ if (enable != null && enable.equals("true")) {
+ String choice = getConfig(CONFIG_EXCLUDED_NAME_CHOICE + i);
+ String value = getConfig(CONFIG_EXCLUDED_NAME_VAL + i);
+ String minS = getConfig(CONFIG_EXCLUDED_MIN_VAL + i);
+ String maxS = getConfig(CONFIG_EXCLUDED_MAX_VAL + i);
+
+ v1.addElement(createSubtree(choice, value, minS, maxS));
+ }
+ }
+
+ ext = new NameConstraintsExtension(critical,
+ new GeneralSubtrees(v), new GeneralSubtrees(v1));
+ } catch (Exception e) {
+ CMS.debug("NameConstraintsExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+
+ private GeneralSubtree createSubtree(String choice, String value,
+ String minS, String maxS) {
+ GeneralName gn = null;
+ GeneralNameInterface gnI = null;
+
+ try {
+ gnI = parseGeneralName(choice + ":" + value);
+ } catch (IOException e) {
+ CMS.debug(e.toString());
+ }
+ if (gnI != null)
+ gn = new GeneralName(gnI);
+ else
+ //throw new EPropertyException("GeneralName must not be null");
+ return null;
+
+ int min = 0;
+
+ if (minS != null && minS.length() > 0)
+ min = Integer.parseInt(minS);
+ int max = -1;
+
+ if (maxS != null && maxS.length() > 0)
+ max = Integer.parseInt(maxS);
+
+ return (new GeneralSubtree(gn, min, max));
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/NoDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/NoDefault.java
new file mode 100644
index 000000000..c3ea31211
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/NoDefault.java
@@ -0,0 +1,106 @@
+// --- 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.def;
+
+
+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.*;
+
+
+/**
+ * This class implements no default policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NoDefault implements IPolicyDefault {
+
+ public static final String PROP_NAME = "name";
+
+ protected Vector mValues = new Vector();
+ protected Vector mNames = new Vector();
+ protected IConfigStore mConfig = null;
+
+ public Enumeration getConfigNames() {
+ return mNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ public String getConfig(String name) {
+ return null;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request)
+ throws EProfileException {
+ }
+
+ public Enumeration getValueNames() {
+ return mValues.elements();
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setValue(String name, Locale locale, IRequest request,
+ String value)
+ throws EPropertyException {
+ }
+
+ public String getValue(String name, Locale locale, IRequest request) {
+ return null;
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_NO_DEFAULT");
+ }
+
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(PROP_NAME);
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java
new file mode 100644
index 000000000..fb6518043
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java
@@ -0,0 +1,189 @@
+// --- 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.def;
+
+
+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.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates an OCSP No Check extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSPNoCheckExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "ocspNoCheckCritical";
+
+ public static final String VAL_CRITICAL = "ocspNoCheckCritical";
+
+ public OCSPNoCheckExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addConfigName(CONFIG_CRITICAL);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ OCSPNoCheckExtension ext = (OCSPNoCheckExtension)
+ getExtension(OCSPNoCheckExtension.OID, info);
+
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (OCSPNoCheckExtension)
+ getExtension(OCSPNoCheckExtension.OID, info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ OCSPNoCheckExtension ext = (OCSPNoCheckExtension)
+ getExtension(OCSPNoCheckExtension.OID, info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (OCSPNoCheckExtension)
+ getExtension(OCSPNoCheckExtension.OID, info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_OCSP_NO_CHECK_EXT",
+ getConfig(CONFIG_CRITICAL));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ OCSPNoCheckExtension ext = createExtension();
+
+ addExtension(OCSPNoCheckExtension.OID, ext, info);
+ }
+
+ public OCSPNoCheckExtension createExtension() {
+ OCSPNoCheckExtension ext = null;
+
+ try {
+ ext = new OCSPNoCheckExtension();
+ } catch (Exception e) {
+ CMS.debug("OCSPNoCheckExtDefault: createExtension " +
+ e.toString());
+ return null;
+ }
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ ext.setCritical(critical);
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java
new file mode 100644
index 000000000..72d076ca5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java
@@ -0,0 +1,289 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a policy constraints extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PolicyConstraintsExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "policyConstraintsCritical";
+ public static final String CONFIG_REQ_EXPLICIT_POLICY = "policyConstraintsReqExplicitPolicy";
+ public static final String CONFIG_INHIBIT_POLICY_MAPPING = "policyConstraintsInhibitPolicyMapping";
+
+ public static final String VAL_CRITICAL = "policyConstraintsCritical";
+ public static final String VAL_REQ_EXPLICIT_POLICY = "policyConstraintsReqExplicitPolicy";
+ public static final String VAL_INHIBIT_POLICY_MAPPING = "policyConstraintsInhibitPolicyMapping";
+
+ public PolicyConstraintsExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_REQ_EXPLICIT_POLICY);
+ addValueName(VAL_INHIBIT_POLICY_MAPPING);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_REQ_EXPLICIT_POLICY);
+ addConfigName(CONFIG_INHIBIT_POLICY_MAPPING);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_REQ_EXPLICIT_POLICY)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REQUIRED_EXPLICIT_POLICY"));
+ } else if (name.equals(CONFIG_INHIBIT_POLICY_MAPPING)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INHIBIT_POLICY_MAPPING"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_REQ_EXPLICIT_POLICY)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REQUIRED_EXPLICIT_POLICY"));
+ } else if (name.equals(VAL_INHIBIT_POLICY_MAPPING)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INHIBIT_POLICY_MAPPING"));
+ }
+ return null;
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ PolicyConstraintsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_REQ_EXPLICIT_POLICY)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if(ext == null) {
+ return;
+ }
+ Integer num = new Integer(value);
+
+ ext.set(PolicyConstraintsExtension.REQUIRE, num);
+ } else if (name.equals(VAL_INHIBIT_POLICY_MAPPING)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if(ext == null) {
+ return;
+ }
+ Integer num = new Integer(value);
+
+ ext.set(PolicyConstraintsExtension.INHIBIT, num);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("PolicyConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (IOException e) {
+ CMS.debug("PolicyConstraintsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ PolicyConstraintsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+ if(ext == null)
+ {
+
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_REQ_EXPLICIT_POLICY)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ int num = ext.getRequireExplicitMapping();
+
+ return "" + num;
+ } else if (name.equals(VAL_INHIBIT_POLICY_MAPPING)) {
+ ext = (PolicyConstraintsExtension)
+ getExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ int num = ext.getInhibitPolicyMapping();
+
+ return "" + num;
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_REQ_EXPLICIT_POLICY),
+ getConfig(CONFIG_INHIBIT_POLICY_MAPPING)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_POLICY_CONSTRAINTS_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ PolicyConstraintsExtension ext = createExtension();
+
+ if (ext == null)
+ return;
+ addExtension(PKIXExtensions.PolicyConstraints_Id.toString(),
+ ext, info);
+ }
+
+ public PolicyConstraintsExtension createExtension() {
+ PolicyConstraintsExtension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ int reqNum = -1;
+ int inhibitNum = -1;
+ String req = getConfig(CONFIG_REQ_EXPLICIT_POLICY);
+
+ if (req != null && req.length() > 0) {
+ reqNum = Integer.parseInt(req);
+ }
+ String inhibit = getConfig(CONFIG_INHIBIT_POLICY_MAPPING);
+
+ if (inhibit != null && inhibit.length() > 0) {
+ inhibitNum = Integer.parseInt(inhibit);
+ }
+ ext = new PolicyConstraintsExtension(critical, reqNum, inhibitNum);
+ } catch (Exception e) {
+ CMS.debug("PolicyConstraintsExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java
new file mode 100644
index 000000000..d9ef59c11
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java
@@ -0,0 +1,422 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a policy mappings extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PolicyMappingsExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "policyMappingsCritical";
+ public static final String CONFIG_NUM_POLICY_MAPPINGS = "policyMappingsNum";
+ public static final String CONFIG_ISSUER_DOMAIN_POLICY = "policyMappingsIssuerDomainPolicy_";
+ public static final String CONFIG_SUBJECT_DOMAIN_POLICY = "policyMappingsSubjectDomainPolicy_";
+ public static final String CONFIG_ENABLE = "policyMappingsEnable_";
+
+ public static final String VAL_CRITICAL = "policyMappingsCritical";
+ public static final String VAL_DOMAINS = "policyMappingsDomains";
+
+ private static final String ISSUER_POLICY_ID = "Issuer Policy Id";
+ private static final String SUBJECT_POLICY_ID = "Subject Policy Id";
+ private static final String POLICY_ID_ENABLE = "Enable";
+
+ private static final int DEF_NUM_MAPPINGS = 1;
+ private static final int MAX_NUM_MAPPINGS = 100;
+
+ public PolicyMappingsExtDefault() {
+ super();
+ }
+
+ protected int getNumMappings() {
+ int num = DEF_NUM_MAPPINGS;
+ String numMappings = getConfig(CONFIG_NUM_POLICY_MAPPINGS);
+
+ if (numMappings != null) {
+ try {
+ num = Integer.parseInt(numMappings);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return num;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_POLICY_MAPPINGS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_MAPPINGS || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POLICY_MAPPINGS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_POLICY_MAPPINGS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_DOMAINS);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumMappings();
+
+ addConfigName(CONFIG_NUM_POLICY_MAPPINGS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_ISSUER_DOMAIN_POLICY + i);
+ addConfigName(CONFIG_SUBJECT_DOMAIN_POLICY + i);
+ addConfigName(CONFIG_ENABLE + i);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_ISSUER_DOMAIN_POLICY)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ISSUER_DOMAIN_POLICY"));
+ } else if (name.startsWith(CONFIG_SUBJECT_DOMAIN_POLICY)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_DOMAIN_POLICY"));
+ } else if (name.startsWith(CONFIG_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_POLICY_MAPPINGS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_POLICY_MAPPINGS"));
+ }
+
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_DOMAINS)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_DOMAINS"));
+ }
+ return null;
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ PolicyMappingsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+
+ if(ext == null) {
+ populate(null,info);
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_DOMAINS)) {
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+
+ if(ext == null) {
+ return;
+ }
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ String issuerPolicyId = null;
+ String subjectPolicyId = null;
+ String enable = null;
+ Vector policyMaps = new Vector();
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(ISSUER_POLICY_ID)) {
+ issuerPolicyId = nvps.getValue(name1);
+ } else if (name1.equals(SUBJECT_POLICY_ID)) {
+ subjectPolicyId = nvps.getValue(name1);
+ } else if (name1.equals(POLICY_ID_ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable != null && enable.equals("true")) {
+ if (issuerPolicyId == null ||
+ issuerPolicyId.length() == 0 || subjectPolicyId == null ||
+ subjectPolicyId.length() == 0)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_POLICY_ID_NOT_FOUND"));
+ CertificatePolicyMap map = new CertificatePolicyMap(
+ new CertificatePolicyId(new ObjectIdentifier(issuerPolicyId)),
+ new CertificatePolicyId(new ObjectIdentifier(subjectPolicyId)));
+
+ policyMaps.addElement(map);
+ }
+ }
+ ext.set(PolicyMappingsExtension.MAP, policyMaps);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("PolicyMappingsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (IOException e) {
+ CMS.debug("PolicyMappingsExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ PolicyMappingsExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_DOMAINS)) {
+ ext = (PolicyMappingsExtension)
+ getExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ int num_mappings = getNumMappings();
+
+ Enumeration maps = ext.getMappings();
+
+ int num = 0;
+ StringBuffer sb = new StringBuffer();
+
+ Vector recs = new Vector();
+
+ for (int i = 0; i < num_mappings; i++) {
+ NameValuePairs pairs = new NameValuePairs();
+
+ if (maps.hasMoreElements()) {
+ CertificatePolicyMap map =
+ (CertificatePolicyMap) maps.nextElement();
+
+ CertificatePolicyId i1 = map.getIssuerIdentifier();
+ CertificatePolicyId s1 = map.getSubjectIdentifier();
+
+ pairs.add(ISSUER_POLICY_ID, i1.getIdentifier().toString());
+ pairs.add(SUBJECT_POLICY_ID, s1.getIdentifier().toString());
+ pairs.add(POLICY_ID_ENABLE, "true");
+ } else {
+ pairs.add(ISSUER_POLICY_ID, "");
+ pairs.add(SUBJECT_POLICY_ID, "");
+ pairs.add(POLICY_ID_ENABLE, "false");
+
+ }
+ recs.addElement(pairs);
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ String numMappings = getConfig(CONFIG_NUM_POLICY_MAPPINGS);
+ int num = getNumMappings();
+
+ for (int i = 0; i < num; i++) {
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(ISSUER_POLICY_ID + ":");
+ sb.append(getConfig(CONFIG_ISSUER_DOMAIN_POLICY + i));
+ sb.append(",");
+ sb.append(SUBJECT_POLICY_ID + ":");
+ sb.append(getConfig(CONFIG_SUBJECT_DOMAIN_POLICY + i));
+ sb.append(",");
+ sb.append(POLICY_ID_ENABLE + ":");
+ sb.append(getConfig(CONFIG_ENABLE + i));
+ sb.append("}");
+ }
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_POLICY_MAPPINGS_EXT",
+ getConfig(CONFIG_CRITICAL), sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ PolicyMappingsExtension ext = createExtension();
+
+ if (ext == null)
+ return;
+ addExtension(PKIXExtensions.PolicyMappings_Id.toString(),
+ ext, info);
+ }
+
+ public PolicyMappingsExtension createExtension() {
+ PolicyMappingsExtension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+ Vector policyMaps = new Vector();
+ int num = getNumMappings();
+
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_ENABLE + i);
+
+ if (enable != null && enable.equals("true")) {
+ String issuerID = getConfig(CONFIG_ISSUER_DOMAIN_POLICY + i);
+
+ if (issuerID == null || issuerID.length() == 0) {
+ return null;
+ }
+
+ String subjectID = getConfig(CONFIG_SUBJECT_DOMAIN_POLICY + i);
+
+ if (subjectID == null || subjectID.length() == 0) {
+ return null;
+ }
+
+ CertificatePolicyMap map = new CertificatePolicyMap(
+ new CertificatePolicyId(new ObjectIdentifier(issuerID)),
+ new CertificatePolicyId(new ObjectIdentifier(subjectID)));
+
+ policyMaps.addElement(map);
+ }
+ }
+
+ ext = new PolicyMappingsExtension(critical, policyMaps);
+ } catch (Exception e) {
+ CMS.debug("PolicyMappingsExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java
new file mode 100644
index 000000000..46fd5be18
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java
@@ -0,0 +1,315 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import java.text.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a Private Key Usage Period extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PrivateKeyUsagePeriodExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "puCritical";
+ public static final String CONFIG_START_TIME = "puStartTime";
+ public static final String CONFIG_DURATION = "puDurationInDays"; // in days
+
+ public static final String VAL_CRITICAL = "puCritical";
+ public static final String VAL_NOT_BEFORE = "puNotBefore";
+ public static final String VAL_NOT_AFTER = "puNotAfter";
+
+ public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ private long mDefault = 86400000; // 1 days
+
+ public PrivateKeyUsagePeriodExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_NOT_BEFORE);
+ addValueName(VAL_NOT_AFTER);
+
+ addConfigName(CONFIG_CRITICAL);
+ addConfigName(CONFIG_START_TIME);
+ addConfigName(CONFIG_DURATION);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(CONFIG_START_TIME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "0",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_START_TIME"));
+ } else if (name.equals(CONFIG_DURATION)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "365",
+ CMS.getUserMessage(locale, "CMS_PROFILE_VALIDITY_RANGE"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (name.equals(CONFIG_START_TIME)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_START_TIME));
+ }
+ } else if (name.equals(CONFIG_DURATION)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_DURATION));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_NOT_BEFORE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "0",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_BEFORE"));
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "30",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_AFTER"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ PrivateKeyUsageExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = PKIXExtensions.PrivateKeyUsage_Id;
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if (ext == null) {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return;
+ }
+ ext.set(PrivateKeyUsageExtension.NOT_BEFORE, date);
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return;
+ }
+ ext.set(PrivateKeyUsageExtension.NOT_AFTER, date);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(ext.getExtensionId().toString(), ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("PrivateKeyUsageExtension: setValue " + e.toString());
+ } catch (Exception e) {
+ CMS.debug("PrivateKeyUsageExtension: setValue " + e.toString());
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ PrivateKeyUsageExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ObjectIdentifier oid = PKIXExtensions.PrivateKeyUsage_Id;
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ return formatter.format(ext.getNotBefore());
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+
+ ext = (PrivateKeyUsageExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ return formatter.format(ext.getNotAfter());
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ String params[] = {
+ getConfig(CONFIG_CRITICAL),
+ getConfig(CONFIG_START_TIME),
+ getConfig(CONFIG_DURATION)
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_PRIVATE_KEY_EXT", params);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ PrivateKeyUsageExtension ext = createExtension();
+
+ addExtension(ext.getExtensionId().toString(), ext, info);
+ }
+
+ public PrivateKeyUsageExtension createExtension() {
+ PrivateKeyUsageExtension ext = null;
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ // always + 60 seconds
+ String startTimeStr = getConfig(CONFIG_START_TIME);
+
+ if (startTimeStr == null || startTimeStr.equals("")) {
+ startTimeStr = "60";
+ }
+ int startTime = Integer.parseInt(startTimeStr);
+ Date notBefore = new Date(CMS.getCurrentDate().getTime() +
+ (1000 * startTime));
+ long notAfterVal = 0;
+
+ notAfterVal = notBefore.getTime() +
+ (mDefault * Integer.parseInt(getConfig(CONFIG_DURATION)));
+ Date notAfter = new Date(notAfterVal);
+
+ ext = new PrivateKeyUsageExtension(notBefore, notAfter);
+ ext.setCritical(critical);
+ } catch (Exception e) {
+ CMS.debug("PrivateKeyUsagePeriodExt: createExtension " +
+ e.toString());
+ }
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java
new file mode 100644
index 000000000..b3061837a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java
@@ -0,0 +1,184 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.text.*;
+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 com.netscape.cms.profile.common.*;
+import com.netscape.certsrv.ca.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a signing algorithm
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SigningAlgDefault extends EnrollDefault {
+
+ public static final String CONFIG_ALGORITHM = "signingAlg";
+
+ public static final String VAL_ALGORITHM = "signingAlg";
+ public static final String DEF_CONFIG_ALGORITHMS =
+ "-,MD5withRSA,MD2withRSA,SHA1withRSA,SHA256withRSA,SHA512withRSA";
+
+ public SigningAlgDefault() {
+ super();
+ addConfigName(CONFIG_ALGORITHM);
+ addValueName(VAL_ALGORITHM);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_ALGORITHM)) {
+ return new Descriptor(IDescriptor.CHOICE, DEF_CONFIG_ALGORITHMS,
+ "SHA256withRSA",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SIGNING_ALGORITHM"));
+ } else {
+ return null;
+ }
+ }
+
+ public String getSigningAlg()
+ {
+ String signingAlg = getConfig(CONFIG_ALGORITHM);
+ // if specified, use the specified one. Otherwise, pick
+ // the best selection for the user
+ if (signingAlg == null || signingAlg.equals("") ||
+ signingAlg.equals("-")) {
+ // best pick for the user
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ return ca.getDefaultAlgorithm();
+ } else {
+ return signingAlg;
+ }
+ }
+
+ public String getDefSigningAlgorithms()
+ {
+ StringBuffer allowed = new StringBuffer();
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ String algos[] = ca.getCASigningAlgorithms();
+ for (int i = 0; i < algos.length; i++) {
+ if (allowed.length()== 0) {
+ allowed.append(algos[i]);
+ } else {
+ allowed.append(",");
+ allowed.append(algos[i]);
+ }
+ }
+ return allowed.toString();
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_ALGORITHM)) {
+ String allowed = getDefSigningAlgorithms();
+ return new Descriptor(IDescriptor.CHOICE,
+ allowed, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SIGNING_ALGORITHM"));
+ }
+ return null;
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_ALGORITHM)) {
+ try {
+ info.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(
+ AlgorithmId.getAlgorithmId(value)));
+ } catch (Exception e) {
+ CMS.debug("SigningAlgDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+
+ if (name == null)
+ throw new EPropertyException("Invalid name " + name);
+
+ if (name.equals(VAL_ALGORITHM)) {
+ CertificateAlgorithmId algId = null;
+
+ try {
+ algId = (CertificateAlgorithmId)
+ info.get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId id = (AlgorithmId)
+ algId.get(CertificateAlgorithmId.ALGORITHM);
+
+ return id.toString();
+ } catch (Exception e) {
+ CMS.debug("SigningAlgDefault: getValue " + e.toString());
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SIGNING_ALGORITHM",
+ getSigningAlg());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ try {
+ info.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(
+ AlgorithmId.getAlgorithmId(getSigningAlg())));
+ } catch (Exception e) {
+ CMS.debug("SigningAlgDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
new file mode 100644
index 000000000..7da63e71e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
@@ -0,0 +1,536 @@
+// --- 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.def;
+
+
+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.pattern.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a subject alternative name extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectAltNameExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "subjAltNameExtCritical";
+ public static final String CONFIG_NUM_GNS = "subjAltNameNumGNs";
+ public static final String CONFIG_GN_ENABLE = "subjAltExtGNEnable_";
+ public static final String CONFIG_TYPE = "subjAltExtType_";
+ public static final String CONFIG_PATTERN = "subjAltExtPattern_";
+ public static final String CONFIG_SOURCE = "subjAltExtSource_";
+ public static final String CONFIG_SOURCE_UUID4 = "UUID4";
+
+ public static final String CONFIG_OLD_TYPE = "subjAltExtType";
+ public static final String CONFIG_OLD_PATTERN = "subjAltExtPattern";
+
+ public static final String VAL_CRITICAL = "subjAltNameExtCritical";
+ public static final String VAL_GENERAL_NAMES = "subjAltNames";
+
+ private static final String GN_ENABLE = "Enable";
+ private static final String GN_TYPE = "Pattern Type";
+ private static final String GN_PATTERN = "Pattern";
+
+ private static final int DEF_NUM_GN = 1;
+ private static final int MAX_NUM_GN = 100;
+
+ public SubjectAltNameExtDefault() {
+ super();
+ }
+
+ protected int getNumGNs() {
+ int num = DEF_NUM_GN;
+ String numGNs = getConfig(CONFIG_NUM_GNS);
+
+ if (numGNs != null) {
+ try {
+ num = Integer.parseInt(numGNs);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_GN)
+ num = DEF_NUM_GN;
+ return num;
+ }
+
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+
+ super.init(profile,config);
+ refreshConfigAndValueNames();
+ // migrate old parameters to new parameters
+ String old_type = null;
+ String old_pattern = null;
+ IConfigStore paramConfig = config.getSubStore("params");
+ try {
+ if (paramConfig != null) {
+ old_type = paramConfig.getString(CONFIG_OLD_TYPE);
+ }
+ } catch (EBaseException e) {
+ // nothing to do here
+ }
+ CMS.debug("SubjectAltNameExtDefault: Upgrading old_type=" +
+ old_type);
+ try {
+ if (paramConfig != null) {
+ old_pattern = paramConfig.getString(CONFIG_OLD_PATTERN);
+ }
+ } catch (EBaseException e) {
+ // nothing to do here
+ }
+ CMS.debug("SubjectAltNameExtDefault: Upgrading old_pattern=" +
+ old_pattern);
+ if (old_type != null && old_pattern != null) {
+ CMS.debug("SubjectAltNameExtDefault: Upgrading");
+ try {
+ paramConfig.putString(CONFIG_NUM_GNS, "1");
+ paramConfig.putString(CONFIG_GN_ENABLE + "0", "true");
+ paramConfig.putString(CONFIG_TYPE + "0", old_type);
+ paramConfig.putString(CONFIG_PATTERN + "0", old_pattern);
+ paramConfig.remove(CONFIG_OLD_TYPE);
+ paramConfig.remove(CONFIG_OLD_PATTERN);
+ profile.getConfigStore().commit(true);
+ } catch (Exception e) {
+ CMS.debug("SubjectAltNameExtDefault: Failed to upgrade " + e);
+ }
+ }
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_GNS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_GN || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_GNS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_GNS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_GENERAL_NAMES);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumGNs();
+ addConfigName(CONFIG_NUM_GNS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_TYPE + i);
+ addConfigName(CONFIG_PATTERN + i);
+ addConfigName(CONFIG_GN_ENABLE + i);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_TYPE)) {
+ return new Descriptor(IDescriptor.CHOICE, "RFC822Name,DNSName,DirectoryName,EDIPartyName,URIName,IPAddress,OIDName,OtherName",
+ "RFC822Name",
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_ALT_NAME_TYPE"));
+ } else if (name.startsWith(CONFIG_PATTERN)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_ALT_NAME_PATTERN"));
+ } else if (name.startsWith(CONFIG_GN_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_GN_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_GNS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_GNS"));
+ }
+
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GENERAL_NAMES"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ SubjectAlternativeNameExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ boolean critical = Boolean.valueOf(value).booleanValue();
+
+ ext.setCritical(critical);
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ // it is ok, the extension is never populated or delted
+ return;
+ }
+ if (value.equals("")) {
+ // if value is empty, do not add this extension
+ deleteExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+ return;
+ }
+ GeneralNames gn = new GeneralNames();
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+
+ while (st.hasMoreTokens()) {
+ String gname = (String) st.nextToken();
+ CMS.debug("SubjectAltNameExtDefault: setValue GN:" + gname);
+
+ if (!isGeneralNameValid(gname)) {
+ continue;
+ }
+ GeneralNameInterface n = parseGeneralName(gname);
+ if (n != null) {
+ gn.addElement(n);
+ }
+ }
+ if (gn.size() == 0) {
+ CMS.debug("GN size is zero");
+ deleteExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+ return;
+ } else {
+ CMS.debug("GN size is non zero (" + gn.size() + ")");
+ ext.set(SubjectAlternativeNameExtension.SUBJECT_NAME, gn);
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ replaceExtension(
+ PKIXExtensions.SubjectAlternativeName_Id.toString(),
+ ext, info);
+ } catch (IOException e) {
+ CMS.debug("SubjectAltNameExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("SubjectAltNameExtDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ try {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ SubjectAlternativeNameExtension ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ ext =
+ (SubjectAlternativeNameExtension)
+ getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info);
+ if (ext == null) {
+ return null;
+ }
+
+ GeneralNames names = (GeneralNames)
+ ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+ StringBuffer sb = new StringBuffer();
+ Enumeration e = names.elements();
+
+ while (e.hasMoreElements()) {
+ Object o = (Object) e.nextElement();
+ if (!(o instanceof GeneralName))
+ continue;
+ GeneralName gn = (GeneralName) o;
+
+ if (!sb.toString().equals("")) {
+ sb.append("\r\n");
+ }
+ sb.append(toGeneralNameString(gn));
+ CMS.debug("SubjectAltNameExtDefault: getValue append GN:" + toGeneralNameString(gn));
+ }
+ return sb.toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } catch (IOException e) {
+ CMS.debug("SubjectAltNameExtDefault: getValue " +
+ e.toString());
+ }
+ return null;
+ }
+
+ /*
+ * returns text that goes into description for this extension on
+ * a profile
+ */
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ String numGNs = getConfig(CONFIG_NUM_GNS);
+ int num = getNumGNs();
+
+ for (int i= 0; i< num; i++) {
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(GN_PATTERN + ":");
+ sb.append(getConfig(CONFIG_PATTERN + i));
+ sb.append(",");
+ sb.append(GN_TYPE +":");
+ sb.append(getConfig(CONFIG_TYPE +i));
+ sb.append(",");
+ sb.append(GN_ENABLE + ":");
+ sb.append(getConfig(CONFIG_GN_ENABLE + i));
+ sb.append("}");
+ };
+
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SUBJECT_ALT_NAME_EXT", getConfig(CONFIG_CRITICAL), sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ SubjectAlternativeNameExtension ext = null;
+
+ try {
+ /* read from config file*/
+ ext = createExtension(request);
+
+ } catch (IOException e) {
+ CMS.debug("SubjectAltNameExtDefault: populate " + e.toString());
+ }
+ if (ext != null) {
+ addExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(),
+ ext, info);
+ } else {
+ CMS.debug("SubjectAltNameExtDefault: populate sees no extension. get out");
+ }
+ }
+
+ public SubjectAlternativeNameExtension createExtension(IRequest request)
+ throws IOException {
+ SubjectAlternativeNameExtension ext = null;
+ int num = getNumGNs();
+
+ boolean critical = Boolean.valueOf(
+ getConfig(CONFIG_CRITICAL)).booleanValue();
+
+ GeneralNames gn = new GeneralNames();
+ int count = 0; // # of actual gnames
+ for (int i=0; i< num; i++) {
+ String enable = getConfig(CONFIG_GN_ENABLE +i);
+ if (enable != null && enable.equals("true")) {
+ CMS.debug("SubjectAltNameExtDefault: createExtension i=" +i);
+
+ String pattern = getConfig(CONFIG_PATTERN + i);
+ if (pattern == null || pattern.equals("")) {
+ pattern = " ";
+ }
+
+ if (!pattern.equals("")) {
+ String gname = "";
+
+ // cfu - see if this is server-generated (e.g. UUID4)
+ // to use this feature, use $server.source$ in pattern
+ String source = getConfig(CONFIG_SOURCE +i);
+ String type = getConfig(CONFIG_TYPE + i);
+ if ((source != null) && (!source.equals(""))) {
+ if (type.equalsIgnoreCase("OtherName")) {
+ CMS.debug("SubjectAlternativeNameExtension: using "+
+ source+ " as gn");
+ if (source.equals(CONFIG_SOURCE_UUID4)) {
+ UUID randUUID = UUID.randomUUID();
+ // call the mapPattern that does server-side gen
+ // request is not used, but needed for the substitute
+ // function
+ gname = mapPattern(randUUID.toString(), request, pattern);
+ } else { //expand more server-gen types here
+ CMS.debug("SubjectAltNameExtDefault: createExtension - unsupported server-generated type: "+source+". Supported: UUID4");
+ continue;
+ }
+ } else {
+ CMS.debug("SubjectAltNameExtDefault: createExtension - source is only supported for subjAltExtType OtherName");
+ continue;
+ }
+ } else {
+ if (request != null) {
+ gname = mapPattern(request, pattern);
+ }
+ }
+
+ if (gname.equals("")) {
+ CMS.debug("gname is empty, not added");
+ continue;
+ }
+ CMS.debug("SubjectAltNameExtDefault: createExtension got gname=" +gname);
+
+ GeneralNameInterface n = parseGeneralName(type + ":" + gname);
+
+ CMS.debug("adding gname: "+gname);
+ if (n != null) {
+ CMS.debug("SubjectAlternativeNameExtension: n not null");
+ gn.addElement(n);
+ count++;
+ } else {
+ CMS.debug("SubjectAlternativeNameExtension: n null");
+ }
+ }
+ }
+ } //for
+
+ if (count != 0) {
+ try {
+ ext = new SubjectAlternativeNameExtension();
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ throw new IOException( e.toString() );
+ }
+ ext.set(SubjectAlternativeNameExtension.SUBJECT_NAME, gn);
+ ext.setCritical(critical);
+ } else {
+ CMS.debug("count is 0");
+ }
+ return ext;
+ }
+
+ public String mapPattern(IRequest request, String pattern)
+ throws IOException {
+ Pattern p = new Pattern(pattern);
+ IAttrSet attrSet = null;
+ if (request != null) {
+ attrSet = request.asIAttrSet();
+ }
+ return p.substitute("request", attrSet);
+ }
+
+ // for server-side generated values
+ public String mapPattern(String val, IRequest request, String pattern)
+ throws IOException {
+ Pattern p = new Pattern(pattern);
+ IAttrSet attrSet = null;
+ if (request != null) {
+ attrSet = request.asIAttrSet();
+ }
+ try {
+ attrSet.set("source", val);
+ } catch (Exception e) {
+ CMS.debug("SubjectAlternativeNameExtension: mapPattern source "+e.toString());
+ }
+
+ return p.substitute("server", attrSet);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java
new file mode 100644
index 000000000..afd3fcd0a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java
@@ -0,0 +1,523 @@
+// --- 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.def;
+
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+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.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a subject directory attributes extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectDirAttributesExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "subjDirAttrsCritical";
+ public static final String CONFIG_NUM_ATTRS = "subjDirAttrsNum";
+ public static final String CONFIG_ATTR_NAME = "subjDirAttrName_";
+ public static final String CONFIG_PATTERN = "subjDirAttrPattern_";
+ public static final String CONFIG_ENABLE = "subjDirAttrEnable_";
+
+ public static final String VAL_CRITICAL = "subjDirAttrCritical";
+ public static final String VAL_ATTR = "subjDirAttrValue";
+
+ private static final int DEF_NUM_ATTRS = 1;
+ private static final int MAX_NUM_ATTRS = 100;
+ private static final String ENABLE = "Enable";
+ private static final String ATTR_NAME = "Attribute Name";
+ private static final String ATTR_VALUE = "Attribute Value";
+
+ public SubjectDirAttributesExtDefault() {
+ super();
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+ protected int getNumAttrs() {
+ int num = DEF_NUM_ATTRS;
+ String val = getConfig(CONFIG_NUM_ATTRS);
+
+ if (val != null) {
+ try {
+ num = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ if (num >= MAX_NUM_ATTRS)
+ num = DEF_NUM_ATTRS;
+
+ return num;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(DEF_NUM_ATTRS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_ATTRS || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ATTRS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ATTRS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_ATTR);
+
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumAttrs();
+ addConfigName(CONFIG_NUM_ATTRS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_ATTR_NAME + i);
+ addConfigName(CONFIG_PATTERN + i);
+ addConfigName(CONFIG_ENABLE + i);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_ATTR_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_ATTRS"));
+ } else if (name.startsWith(CONFIG_ATTR_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ATTR_NAME"));
+ } else if (name.startsWith(CONFIG_PATTERN)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ATTR_VALUE"));
+ } else if (name.startsWith(CONFIG_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_ATTRS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_ATTRS"));
+ }
+
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_ATTR)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJDIR_ATTRS"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ SubjectDirAttributesExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null)
+ {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_ATTR)) {
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+
+ if(ext == null)
+ {
+ return;
+ }
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+
+ X500NameAttrMap map = X500NameAttrMap.getDefault();
+ Vector attrV = new Vector();
+ for (int i=0; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+ String attrName = null;
+ String attrValue = null;
+ String enable = "false";
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(ATTR_NAME)) {
+ attrName = nvps.getValue(name1);
+ } else if (name1.equals(ATTR_VALUE)) {
+ attrValue = nvps.getValue(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable.equals("true")) {
+ AttributeConfig attributeConfig =
+ new AttributeConfig(attrName, attrValue);
+ Attribute attr = attributeConfig.mAttribute;
+ if (attr != null)
+ attrV.addElement(attr);
+ }
+ }
+
+ if (attrV.size() > 0) {
+ Attribute[] attrList = new Attribute[attrV.size()];
+ attrV.copyInto(attrList);
+ ext = new SubjectDirAttributesExtension(attrList, critical);
+ } else
+ return;
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ ext, info);
+ } catch (EProfileException e) {
+ CMS.debug("SubjectDirAttributesExtDefault: setValue " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (IOException e) {
+ CMS.debug("SubjectDirAttributesExtDefault: setValue " +
+ e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ SubjectDirAttributesExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_ATTR)) {
+ ext = (SubjectDirAttributesExtension)
+ getExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ info);
+
+ if (ext == null)
+ return "";
+
+ X500NameAttrMap map = X500NameAttrMap.getDefault();
+
+ Vector recs = new Vector();
+ int num = getNumAttrs();
+ Enumeration e = ext.getAttributesList();
+ CMS.debug("SubjectDirAttributesExtDefault: getValue: attributesList="+e);
+ int i=0;
+
+ while (e.hasMoreElements()) {
+ NameValuePairs pairs = new NameValuePairs();
+ pairs.add(ENABLE, "true");
+ Attribute attr = (Attribute)(e.nextElement());
+ CMS.debug("SubjectDirAttributesExtDefault: getValue: attribute="+attr);
+ ObjectIdentifier oid = attr.getOid();
+ CMS.debug("SubjectDirAttributesExtDefault: getValue: oid="+oid);
+
+ String vv = map.getName(oid);
+
+ if (vv != null)
+ pairs.add(ATTR_NAME, vv);
+ else
+ pairs.add(ATTR_NAME, oid.toString());
+ Enumeration v = attr.getValues();
+
+ // just support single value for now
+ StringBuffer ss = new StringBuffer();
+ while (v.hasMoreElements()) {
+ if (ss.length() == 0)
+ ss.append((String)(v.nextElement()));
+ else {
+ ss.append(",");
+ ss.append((String)(v.nextElement()));
+ }
+ }
+
+ pairs .add(ATTR_VALUE, ss.toString());
+ recs.addElement(pairs);
+ i++;
+ }
+
+ for (;i < num; i++) {
+ NameValuePairs pairs = new NameValuePairs();
+ pairs.add(ENABLE, "false");
+ pairs.add(ATTR_NAME, "GENERATIONQUALIFIER");
+ pairs.add(ATTR_VALUE, "");
+ recs.addElement(pairs);
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer sb = new StringBuffer();
+ int num = getNumAttrs();
+
+ for (int i = 0; i < num; i++) {
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("{");
+ sb.append(ATTR_NAME + ":");
+ sb.append(getConfig(CONFIG_ATTR_NAME + i));
+ sb.append(",");
+ sb.append(ATTR_VALUE + ":");
+ sb.append(getConfig(CONFIG_PATTERN + i));
+ sb.append(",");
+ sb.append(ENABLE + ":");
+ sb.append(getConfig(CONFIG_ENABLE + i));
+ sb.append("}");
+ }
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEF_SUBJECT_DIR_ATTR_EXT",
+ getConfig(CONFIG_CRITICAL),
+ sb.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ SubjectDirAttributesExtension ext = createExtension(request);
+
+ if (ext == null)
+ return;
+
+ addExtension(PKIXExtensions.SubjectDirectoryAttributes_Id.toString(),
+ ext, info);
+ }
+
+ public SubjectDirAttributesExtension createExtension(IRequest request)
+ throws EProfileException {
+ SubjectDirAttributesExtension ext = null;
+ int num = 0;
+
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ num = getNumAttrs();
+
+ AttributeConfig attributeConfig = null;
+ Vector attrs = new Vector();
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_ENABLE + i);
+ if (enable != null && enable.equals("true")) {
+ String attrName = getConfig(CONFIG_ATTR_NAME + i);
+ String pattern = getConfig(CONFIG_PATTERN + i);
+ if (pattern == null || pattern.equals(""))
+ pattern = " ";
+
+ //check pattern syntax
+ int startpos = pattern.indexOf("$");
+ int lastpos = pattern.lastIndexOf("$");
+ String attrValue = pattern;
+ if (!pattern.equals("") && startpos != -1 &&
+ startpos == 0 && lastpos != -1 &&
+ lastpos == (pattern.length()-1)) {
+ if (request != null) {
+ try {
+ attrValue = mapPattern(request, pattern);
+ } catch (IOException e) {
+ throw new EProfileException(e.toString());
+ }
+ }
+ }
+ try {
+ attributeConfig = new AttributeConfig(attrName, attrValue);
+ } catch (EPropertyException e) {
+ throw new EProfileException(e.toString());
+ }
+ Attribute attr = attributeConfig.mAttribute;
+ if (attr != null) {
+ attrs.addElement(attr);
+ }
+ }
+ }
+
+ if (attrs.size() > 0) {
+ Attribute[] attrList = new Attribute[attrs.size()];
+ attrs.copyInto(attrList);
+ try {
+ ext =
+ new SubjectDirAttributesExtension(attrList, critical);
+ } catch (IOException e) {
+ throw new EProfileException(e.toString());
+ }
+ }
+
+ return ext;
+ }
+}
+
+class AttributeConfig {
+
+ protected ObjectIdentifier mAttributeOID = null;
+ protected Attribute mAttribute = null;
+
+ public AttributeConfig(String attrName, String attrValue)
+ throws EPropertyException {
+ X500NameAttrMap map = X500NameAttrMap.getDefault();
+
+ if (attrName == null || attrName.length() == 0) {
+ throw new EPropertyException(
+ CMS.getUserMessage("CMS_PROFILE_SUBJDIR_EMPTY_ATTRNAME", attrName));
+ }
+
+ if (attrValue == null || attrValue.length() == 0) {
+ throw new EPropertyException(
+ CMS.getUserMessage("CMS_PROFILE_SUBJDIR_EMPTY_ATTRVAL", attrValue));
+ }
+
+ try {
+ mAttributeOID = new ObjectIdentifier(attrName);
+ } catch (Exception e) {
+ CMS.debug("SubjectDirAttributesExtDefault: invalid OID syntax: "+ attrName);
+ }
+
+ if (mAttributeOID == null) {
+ mAttributeOID = map.getOid(attrName);
+ if (mAttributeOID == null)
+ throw new EPropertyException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", attrName));
+ try {
+ checkValue(mAttributeOID, attrValue);
+ } catch (IOException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_BASE_INVALID_ATTR_VALUE", e.getMessage()));
+ }
+ }
+
+
+ try {
+ mAttribute = new Attribute(mAttributeOID,
+ str2MultiValues(attrValue));
+ } catch (IOException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_BASE_INVALID_ATTR_VALUE", e.getMessage()));
+ }
+ }
+
+ private static void checkValue(ObjectIdentifier oid, String val)
+ throws IOException {
+ AVAValueConverter c = X500NameAttrMap.getDefault().getValueConverter(oid);
+ DerValue derval;
+
+ derval = c.getValue(val); // errs encountered will get thrown.
+ return;
+ }
+
+ private Vector str2MultiValues(String attrValue) {
+ StringTokenizer tokenizer = new StringTokenizer(attrValue, ",");
+ Vector v = new Vector();
+ while (tokenizer.hasMoreTokens()) {
+ v.addElement(tokenizer.nextToken());
+ }
+
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java
new file mode 100644
index 000000000..4c20769ed
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java
@@ -0,0 +1,449 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.cert.*;
+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 com.netscape.certsrv.common.*;
+
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates Subject Info Access extension.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectInfoAccessExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "subjInfoAccessCritical";
+ public static final String CONFIG_NUM_ADS = "subjInfoAccessNumADs";
+ public static final String CONFIG_AD_ENABLE = "subjInfoAccessADEnable_";
+ public static final String CONFIG_AD_METHOD = "subjInfoAccessADMethod_";
+ public static final String CONFIG_AD_LOCATIONTYPE = "subjInfoAccessADLocationType_";
+ public static final String CONFIG_AD_LOCATION = "subjInfoAccessADLocation_";
+
+ public static final String VAL_CRITICAL = "subjInfoAccessCritical";
+ public static final String VAL_GENERAL_NAMES = "subjInfoAccessGeneralNames";
+
+ private static final String AD_METHOD = "Method";
+ private static final String AD_LOCATION_TYPE = "Location Type";
+ private static final String AD_LOCATION = "Location";
+ private static final String AD_ENABLE = "Enable";
+
+ private static final int DEF_NUM_AD = 1;
+ private static final int MAX_NUM_AD = 100;
+
+ public SubjectInfoAccessExtDefault() {
+ super();
+ }
+
+ protected int getNumAds() {
+ int num = DEF_NUM_AD;
+ String numAds = getConfig(CONFIG_NUM_ADS);
+
+ if (numAds != null) {
+ try {
+ num = Integer.parseInt(numAds);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ if (num >= MAX_NUM_AD)
+ num = DEF_NUM_AD;
+
+ return num;
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ refreshConfigAndValueNames();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ int num = 0;
+ if (name.equals(CONFIG_NUM_ADS)) {
+ try {
+ num = Integer.parseInt(value);
+
+ if (num >= MAX_NUM_AD || num < 0) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ADS));
+ }
+
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_NUM_ADS));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public Enumeration getConfigNames() {
+ refreshConfigAndValueNames();
+ return super.getConfigNames();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ super.refreshConfigAndValueNames();
+
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_GENERAL_NAMES);
+
+ // register configuration names bases on num ads
+ addConfigName(CONFIG_CRITICAL);
+ int num = getNumAds();
+ addConfigName(CONFIG_NUM_ADS);
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_AD_METHOD + i);
+ addConfigName(CONFIG_AD_LOCATIONTYPE + i);
+ addConfigName(CONFIG_AD_LOCATION + i);
+ addConfigName(CONFIG_AD_ENABLE + i);
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.startsWith(CONFIG_AD_METHOD)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_METHOD"));
+ } else if (name.startsWith(CONFIG_AD_LOCATIONTYPE)) {
+ return new Descriptor(IDescriptor.CHOICE, "RFC822Name,DNSName,DirectoryName,EDIPartyName,URIName,IPAddress,OIDName",
+ "URIName",
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_LOCATIONTYPE"));
+ } else if (name.startsWith(CONFIG_AD_LOCATION)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_LOCATION"));
+ } else if (name.startsWith(CONFIG_AD_ENABLE)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_AD_ENABLE"));
+ } else if (name.startsWith(CONFIG_NUM_ADS)) {
+ return new Descriptor(IDescriptor.INTEGER, null,
+ "1",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NUM_ADS"));
+ }
+ return null;
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GENERAL_NAMES"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ try {
+ SubjectInfoAccessExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+
+ SubjectInfoAccessExtension a = new SubjectInfoAccessExtension(false);
+ ObjectIdentifier oid = a.getExtensionId();
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null) {
+ populate(null,info);
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+ boolean val = Boolean.valueOf(value).booleanValue();
+
+ if(ext == null)
+ {
+ return;
+ }
+ ext.setCritical(val);
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ return;
+ }
+ boolean critical = ext.isCritical();
+
+ Vector v = parseRecords(value);
+ int size = v.size();
+
+ ext = new SubjectInfoAccessExtension(critical);
+ String method = null;
+ String locationType = null;
+ String location = null;
+ String enable = null;
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = (NameValuePairs) v.elementAt(i);
+ Enumeration names = nvps.getNames();
+
+ while (names.hasMoreElements()) {
+ String name1 = (String) names.nextElement();
+
+ if (name1.equals(AD_METHOD)) {
+ method = nvps.getValue(name1);
+ } else if (name1.equals(AD_LOCATION_TYPE)) {
+ locationType = nvps.getValue(name1);
+ } else if (name1.equals(AD_LOCATION)) {
+ location = nvps.getValue(name1);
+ } else if (name1.equals(AD_ENABLE)) {
+ enable = nvps.getValue(name1);
+ }
+ }
+
+ if (enable != null && enable.equals("true")) {
+ GeneralName gn = null;
+
+ if (locationType != null || location != null) {
+ GeneralNameInterface interface1 = parseGeneralName(locationType + ":" + location);
+ if (interface1 == null)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", locationType));
+ gn = new GeneralName(interface1);
+ }
+
+ if (method != null) {
+ try {
+ ext.addAccessDescription(new ObjectIdentifier(method), gn);
+ } catch (NumberFormatException ee) {
+ CMS.debug("SubjectInfoAccessExtDefault: "+ee.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_DEF_SIA_OID", method));
+ }
+ }
+ }
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ replaceExtension(ext.getExtensionId().toString(), ext, info);
+ } catch (IOException e) {
+ CMS.debug("SubjectInfoAccessExtDefault: " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } catch (EProfileException e) {
+ CMS.debug("SubjectInfoAccessExtDefault: " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ SubjectInfoAccessExtension ext = null;
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ SubjectInfoAccessExtension a = new SubjectInfoAccessExtension(false);
+ ObjectIdentifier oid = a.getExtensionId();
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ CMS.debug("SubjectInfoAccessExtDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+ if (name.equals(VAL_CRITICAL)) {
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_GENERAL_NAMES)) {
+
+ ext = (SubjectInfoAccessExtension)
+ getExtension(oid.toString(), info);
+
+ if (ext == null)
+ return "";
+
+ int num = getNumAds();
+
+ CMS.debug("SubjectInfoAccess num=" + num);
+ Vector recs = new Vector();
+
+ for (int i = 0; i < num; i++) {
+ NameValuePairs np = new NameValuePairs();
+ AccessDescription des = null;
+
+ if (i < ext.numberOfAccessDescription()) {
+ des = ext.getAccessDescription(i);
+ }
+ if (des == null) {
+ np.add(AD_METHOD, "");
+ np.add(AD_LOCATION_TYPE, "");
+ np.add(AD_LOCATION, "");
+ np.add(AD_ENABLE, "false");
+ } else {
+ ObjectIdentifier methodOid = des.getMethod();
+ GeneralName gn = des.getLocation();
+
+ np.add(AD_METHOD, methodOid.toString());
+ np.add(AD_LOCATION_TYPE, getGeneralNameType(gn));
+ np.add(AD_LOCATION, getGeneralNameValue(gn));
+ np.add(AD_ENABLE, "true");
+ }
+ recs.addElement(np);
+ }
+
+ return buildRecords(recs);
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ StringBuffer ads = new StringBuffer();
+ String numAds = getConfig(CONFIG_NUM_ADS);
+ int num = getNumAds();
+
+ for (int i = 0; i < num; i++) {
+ ads.append("Record #");
+ ads.append(i);
+ ads.append("{");
+ ads.append(AD_METHOD + ":");
+ ads.append(getConfig(CONFIG_AD_METHOD + i));
+ ads.append(",");
+ ads.append(AD_LOCATION_TYPE + ":");
+ ads.append(getConfig(CONFIG_AD_LOCATIONTYPE + i));
+ ads.append(",");
+ ads.append(AD_LOCATION + ":");
+ ads.append(getConfig(CONFIG_AD_LOCATION + i));
+ ads.append(",");
+ ads.append(AD_ENABLE + ":");
+ ads.append(getConfig(CONFIG_AD_ENABLE + i));
+ ads.append("}");
+ }
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SIA_TEXT",
+ getConfig(CONFIG_CRITICAL), ads.toString());
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ SubjectInfoAccessExtension ext = createExtension();
+
+ addExtension(ext.getExtensionId().toString(), ext, info);
+ }
+
+ public SubjectInfoAccessExtension createExtension() {
+ SubjectInfoAccessExtension ext = null;
+ int num = getNumAds();
+
+ try {
+ boolean critical = getConfigBoolean(CONFIG_CRITICAL);
+
+ ext = new SubjectInfoAccessExtension(critical);
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_AD_ENABLE + i);
+ if (enable != null && enable.equals("true")) {
+ CMS.debug("SubjectInfoAccess: createExtension i=" + i);
+ String method = getConfig(CONFIG_AD_METHOD + i);
+ String locationType = getConfig(CONFIG_AD_LOCATIONTYPE + i);
+ if (locationType == null || locationType.length() == 0)
+ locationType = "URIName";
+ String location = getConfig(CONFIG_AD_LOCATION + i);
+
+ if (location == null || location.equals("")) {
+ if (method.equals("1.3.6.1.5.5.7.48.1")) {
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ if (hostname != null && port != null)
+ location = "http://"+hostname+":"+port+"/ocsp";
+ }
+ }
+
+ String s = locationType + ":" + location;
+ GeneralNameInterface gn = parseGeneralName(s);
+ if (gn != null) {
+ ext.addAccessDescription(new ObjectIdentifier(method),
+ new GeneralName(gn));
+ }
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("SubjectInfoAccessExtDefault: createExtension " +
+ e.toString());
+ }
+
+ return ext;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
new file mode 100644
index 000000000..27a2c496f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
@@ -0,0 +1,213 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a subject key identifier extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectKeyIdentifierExtDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "critical";
+
+ public static final String VAL_CRITICAL = "critical";
+ public static final String VAL_KEY_ID = "keyid";
+
+ public SubjectKeyIdentifierExtDefault() {
+ super();
+ addValueName(VAL_CRITICAL);
+ addValueName(VAL_KEY_ID);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CRITICAL)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL"));
+ } else if (name.equals(VAL_KEY_ID)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_ID"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_CRITICAL)) {
+ // read-only; do nothing
+ } else if (name.equals(VAL_KEY_ID)) {
+ // read-only; do nothing
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ SubjectKeyIdentifierExtension ext =
+ (SubjectKeyIdentifierExtension) getExtension(
+ PKIXExtensions.SubjectKey_Id.toString(), info);
+
+ if(ext == null)
+ {
+ try {
+ populate(null,info);
+
+ } catch (EProfileException e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ if (name.equals(VAL_CRITICAL)) {
+ ext =
+ (SubjectKeyIdentifierExtension) getExtension(
+ PKIXExtensions.SubjectKey_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ if (ext.isCritical()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ } else if (name.equals(VAL_KEY_ID)) {
+ ext =
+ (SubjectKeyIdentifierExtension) getExtension(
+ PKIXExtensions.SubjectKey_Id.toString(), info);
+
+ if (ext == null) {
+ return null;
+ }
+ KeyIdentifier kid = null;
+
+ try {
+ kid = (KeyIdentifier)
+ ext.get(SubjectKeyIdentifierExtension.KEY_ID);
+ } catch (IOException e) {
+ CMS.debug( "SubjectKeyIdentifierExtDefault::getValue() - " +
+ "kid is null!" );
+ throw new EPropertyException( CMS.getUserMessage( locale,
+ "CMS_INVALID_PROPERTY",
+ name ) );
+ }
+ return toHexString(kid.getIdentifier());
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SUBJECT_KEY_ID_EXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ SubjectKeyIdentifierExtension ext = createExtension(info);
+
+ addExtension(PKIXExtensions.SubjectKey_Id.toString(), ext, info);
+ }
+
+ public SubjectKeyIdentifierExtension createExtension(X509CertInfo info) {
+ KeyIdentifier kid = getKeyIdentifier(info);
+
+ if (kid == null) {
+ CMS.debug("SubjectKeyIdentifierExtDefault: KeyIdentifier not found");
+ return null;
+ }
+ SubjectKeyIdentifierExtension ext = null;
+
+ boolean critical = Boolean.valueOf(getConfig(CONFIG_CRITICAL)).booleanValue();
+
+ try {
+ ext = new SubjectKeyIdentifierExtension(critical, kid.getIdentifier());
+ } catch (IOException e) {
+ CMS.debug("SubjectKeyIdentifierExtDefault: createExtension " +
+ e.toString());
+ //
+ }
+ return ext;
+ }
+
+ public KeyIdentifier getKeyIdentifier(X509CertInfo info) {
+ try {
+ CertificateX509Key infokey = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ X509Key key = (X509Key) infokey.get(CertificateX509Key.KEY);
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getKey());
+ byte[] hash = md.digest();
+
+ return new KeyIdentifier(hash);
+ } catch (NoSuchAlgorithmException e) {
+ CMS.debug("SubjectKeyIdentifierExtDefault: getKeyIdentifier " +
+ e.toString());
+ } catch (Exception e) {
+ CMS.debug("SubjectKeyIdentifierExtDefault: getKeyIdentifier " +
+ e.toString());
+ }
+ return null;
+ }
+}
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
new file mode 100644
index 000000000..d19b5e5b8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java
@@ -0,0 +1,181 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates server-side configurable subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectNameDefault extends EnrollDefault {
+
+ public static final String CONFIG_NAME = "name";
+
+ public static final String VAL_NAME = "name";
+
+ public SubjectNameDefault() {
+ super();
+ addValueName(VAL_NAME);
+ addConfigName(CONFIG_NAME);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, "CN=TEST", CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ 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.toString());
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("SubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ CMS.debug("SubjectNameDefault: getValue info=" + info);
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ CMS.debug("SubjectNameDefault: getValue name=" + sn);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("SubjectNameDefault: getValue " + e.toString());
+
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SUBJECT_NAME",
+ getConfig(CONFIG_NAME));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ X500Name name = null;
+
+ String subjectName = null;
+
+ try {
+ subjectName = mapPattern(request, getConfig(CONFIG_NAME));
+ } catch (IOException e) {
+ CMS.debug("SubjectNameDefault: mapPattern " + e.toString());
+ }
+
+ CMS.debug("subjectName=" + subjectName);
+ if (subjectName == null || subjectName.equals(""))
+ return;
+ try {
+ name = new X500Name(subjectName);
+ } catch (IOException e) {
+ // failed to build x500 name
+ CMS.debug("SubjectNameDefault: populate " + e.toString());
+ }
+ if (name == null) {
+ // failed to build x500 name
+ }
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("SubjectNameDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java
new file mode 100644
index 000000000..a5594917e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java
@@ -0,0 +1,133 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+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.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a user-supplied extension
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserExtensionDefault extends EnrollExtDefault {
+
+ public static final String CONFIG_CRITICAL = "userExtCritical";
+ public static final String CONFIG_OID = "userExtOID";
+
+ public static final String VAL_CRITICAL = "userExtCritical";
+ public static final String VAL_OID = "userExtOID";
+
+ public UserExtensionDefault() {
+ super();
+ addValueName(VAL_OID);
+ addConfigName(CONFIG_OID);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_OID)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ "Comment Here...",
+ CMS.getUserMessage(locale, "CMS_PROFILE_OID"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_OID)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_OID"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ // Nothing to do for read-only values
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_OID)) {
+ Extension ext = getExtension(getConfig(CONFIG_OID), info);
+
+ if (ext == null) {
+ // do something here
+ return "";
+ }
+ return ext.getExtensionId().toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_USER_EXT", getConfig(CONFIG_OID));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CertificateExtensions inExts = null;
+ String oid = getConfig(CONFIG_OID);
+
+ inExts = request.getExtDataInCertExts(IEnrollProfile.REQUEST_EXTENSIONS);
+ if (inExts == null)
+ return;
+ Extension ext = getExtension(getConfig(CONFIG_OID), inExts);
+ if (ext == null) {
+ CMS.debug("UserExtensionDefault: no user ext supplied for "+ oid);
+ return;
+ }
+
+ // user supplied the ext that's allowed, replace the def set by system
+ deleteExtension(oid, info);
+ CMS.debug("UserExtensionDefault: using user supplied ext for "+ oid);
+ addExtension(oid, ext, info);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java
new file mode 100644
index 000000000..258b470fa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java
@@ -0,0 +1,229 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+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 com.netscape.certsrv.apps.CMS;
+
+import java.security.interfaces.DSAParams;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.provider.DSAPublicKey;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a user supplied key
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserKeyDefault extends EnrollDefault {
+
+ public static final String VAL_KEY = "KEY";
+ public static final String VAL_LEN = "LEN";
+ public static final String VAL_TYPE = "TYPE";
+
+ public UserKeyDefault() {
+ super();
+ addValueName(VAL_TYPE);
+ addValueName(VAL_LEN);
+ addValueName(VAL_KEY);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_KEY)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY"));
+ } else if (name.equals(VAL_LEN)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_LEN"));
+ } else if (name.equals(VAL_TYPE)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_KEY_TYPE"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ // this default rule is readonly
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_KEY)) {
+ CertificateX509Key ck = null;
+
+ try {
+ ck = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ X509Key k = null;
+
+ try {
+ k = (X509Key)
+ ck.get(CertificateX509Key.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ if (k == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_KEY_NOT_FOUND"));
+ }
+ return toHexString(k.getKey());
+ } else if (name.equals(VAL_LEN)) {
+ CertificateX509Key ck = null;
+
+ try {
+ ck = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ X509Key k = null;
+
+ try {
+ k = (X509Key)
+ ck.get(CertificateX509Key.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ if (k == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_KEY_NOT_FOUND"));
+ }
+ try {
+ if (k.getAlgorithm().equals("RSA")) {
+ return Integer.toString(getRSAKeyLen(k));
+ } else {
+ return Integer.toString(getDSAKeyLen(k));
+ }
+ } catch (Exception e) {
+ CMS.debug("UserKeyDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_TYPE)) {
+ CertificateX509Key ck = null;
+
+ try {
+ ck = (CertificateX509Key)
+ info.get(X509CertInfo.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ X509Key k = null;
+
+ try {
+ k = (X509Key)
+ ck.get(CertificateX509Key.KEY);
+ } catch (Exception e) {
+ // nothing
+ }
+ if (k == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_PROFILE_KEY_NOT_FOUND"));
+ }
+ return k.getAlgorithm() + " - " +
+ k.getAlgorithmId().getOID().toString();
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_USER_KEY");
+ }
+
+ public int getRSAKeyLen(X509Key key) throws Exception {
+ X509Key newkey = null;
+
+ try {
+ newkey = new X509Key(AlgorithmId.get("RSA"),
+ key.getKey());
+ } catch (Exception e) {
+ CMS.debug("UserKeyDefault: getRSAKey " + e.toString());
+ throw e;
+ }
+ RSAPublicKey rsaKey = new RSAPublicKey(newkey.getEncoded());
+
+ return rsaKey.getKeySize();
+ }
+
+ public int getDSAKeyLen(X509Key key) throws Exception {
+ // Check DSAKey parameters.
+ // size refers to the p parameter.
+ DSAPublicKey dsaKey = new DSAPublicKey(key.getEncoded());
+ DSAParams keyParams = dsaKey.getParams();
+ BigInteger p = keyParams.getP();
+ int len = p.bitLength();
+
+ return len;
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CertificateX509Key certKey = null;
+ // authenticate the certificate key, and move
+ // the key from request into x509 certinfo
+ try {
+ byte[] certKeyData = request.getExtDataInByteArray(IEnrollProfile.REQUEST_KEY);
+ if (certKeyData != null) {
+ certKey = new CertificateX509Key(
+ new ByteArrayInputStream(certKeyData));
+ }
+ info.set(X509CertInfo.KEY, certKey);
+ } catch (Exception e) {
+ CMS.debug("UserKeyDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java
new file mode 100644
index 000000000..a8e2900d7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java
@@ -0,0 +1,126 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+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 com.netscape.certsrv.apps.CMS;
+
+//import java.security.interfaces.DSAParams;
+import netscape.security.x509.*;
+//import netscape.security.provider.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a user-supplied signing algorithm
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserSigningAlgDefault extends EnrollDefault {
+
+ public static final String VAL_ALG_ID = "userSigningAlgID";
+
+ public UserSigningAlgDefault() {
+ super();
+ addValueName(VAL_ALG_ID);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_ALG_ID)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY, null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SIGNING_ALGORITHM"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ // this default rule is readonly
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_ALG_ID)) {
+ CertificateAlgorithmId algID = null;
+
+ try {
+ algID = (CertificateAlgorithmId)
+ info.get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId id = (AlgorithmId)
+ algID.get(CertificateAlgorithmId.ALGORITHM);
+
+ return id.toString();
+ } catch (Exception e) {
+ CMS.debug("UserSigningAlgDefault: setValue " + e.toString());
+ return ""; //XXX
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_USER_SIGNING_ALGORITHM");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CertificateAlgorithmId certAlg = null;
+ // authenticate the certificate key, and move
+ // the key from request into x509 certinfo
+ try {
+ byte[] certAlgData = request.getExtDataInByteArray(
+ IEnrollProfile.REQUEST_SIGNING_ALGORITHM);
+ if (certAlgData != null) {
+ certAlg = new CertificateAlgorithmId(
+ new ByteArrayInputStream(certAlgData));
+ }
+ info.set(X509CertInfo.ALGORITHM_ID, certAlg);
+ } catch (Exception e) {
+ CMS.debug("UserSigningAlgDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java
new file mode 100644
index 000000000..4bbe0669e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java
@@ -0,0 +1,139 @@
+// --- 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.def;
+
+
+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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a user-supplied subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserSubjectNameDefault extends EnrollDefault {
+
+ public static final String VAL_NAME = "name";
+
+ public UserSubjectNameDefault() {
+ super();
+ addValueName(VAL_NAME);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug(e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("SubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("UserSubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_USER_SUBJECT_NAME");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ // authenticate the subject name and populate it
+ // to the certinfo
+ try {
+ info.set(X509CertInfo.SUBJECT, request.getExtDataInCertSubjectName(
+ IEnrollProfile.REQUEST_SUBJECT_NAME));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("UserSubjectNameDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java
new file mode 100644
index 000000000..e16c032a5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java
@@ -0,0 +1,149 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import com.netscape.cms.profile.common.*;
+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 com.netscape.certsrv.apps.CMS;
+
+//import java.security.interfaces.DSAParams;
+import netscape.security.x509.*;
+//import netscape.security.provider.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a user-supplied validity
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserValidityDefault extends EnrollDefault {
+
+ public static final String VAL_NOT_BEFORE = "userValdityNotBefore";
+ public static final String VAL_NOT_AFTER = "userValdityNotAfter";
+
+ public UserValidityDefault() {
+ super();
+ addValueName(VAL_NOT_BEFORE);
+ addValueName(VAL_NOT_AFTER);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NOT_BEFORE)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_BEFORE"));
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ return new Descriptor(IDescriptor.STRING,
+ IDescriptor.READONLY,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_AFTER"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ // this default rule is readonly
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NOT_BEFORE)) {
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ Date notBefore = (Date)
+ validity.get(CertificateValidity.NOT_BEFORE);
+
+ return notBefore.toString();
+ } catch (Exception e) {
+ CMS.debug("UserValidityDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ try {
+ CertificateValidity validity = null;
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ validity.get(CertificateValidity.NOT_AFTER);
+
+ return notAfter.toString();
+ } catch (Exception e) {
+ CMS.debug("UserValidityDefault: getValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_USER_VALIDITY");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ CertificateValidity certValidity = null;
+ // authenticate the certificate key, and move
+ // the key from request into x509 certinfo
+ try {
+ byte[] certValidityData = request.getExtDataInByteArray(
+ IEnrollProfile.REQUEST_VALIDITY);
+ if (certValidityData != null) {
+ certValidity = new CertificateValidity();
+ certValidity.decode(
+ new ByteArrayInputStream(certValidityData));
+ }
+ info.set(X509CertInfo.VALIDITY, certValidity);
+ } catch (Exception e) {
+ CMS.debug("UserValidityDefault: populate " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java
new file mode 100644
index 000000000..f0af47f70
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java
@@ -0,0 +1,259 @@
+// --- 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.def;
+
+
+import java.io.*;
+import java.text.*;
+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 com.netscape.cms.profile.common.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a server-side configurable validity
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ValidityDefault extends EnrollDefault {
+ public static final String CONFIG_RANGE = "range";
+ public static final String CONFIG_START_TIME = "startTime";
+
+ public static final String VAL_NOT_BEFORE = "notBefore";
+ public static final String VAL_NOT_AFTER = "notAfter";
+
+ public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+ private long mDefault = 86400000; // 1 days
+
+ public ValidityDefault() {
+ super();
+ addConfigName(CONFIG_RANGE);
+ addConfigName(CONFIG_START_TIME);
+ addValueName(VAL_NOT_BEFORE);
+ addValueName(VAL_NOT_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_RANGE)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_RANGE));
+ }
+ } else if (name.equals(CONFIG_START_TIME)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_START_TIME));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_RANGE)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ "2922",
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_VALIDITY_RANGE"));
+ } else if (name.equals(CONFIG_START_TIME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ "60", /* 1 minute */
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_VALIDITY_START_TIME"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NOT_BEFORE)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_BEFORE"));
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_NOT_AFTER"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (value == null || value.equals("")) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ validity.set(CertificateValidity.NOT_BEFORE,
+ date);
+ } catch (Exception e) {
+ CMS.debug("ValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ ParsePosition pos = new ParsePosition(0);
+ Date date = formatter.parse(value, pos);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ validity.set(CertificateValidity.NOT_AFTER,
+ date);
+ } catch (Exception e) {
+ CMS.debug("ValidityDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+
+ if (name == null)
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+
+ if (name.equals(VAL_NOT_BEFORE)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ return formatter.format((Date)
+ validity.get(CertificateValidity.NOT_BEFORE));
+ } catch (Exception e) {
+ CMS.debug("ValidityDefault: getValue " + e.toString());
+ }
+ throw new EPropertyException("Invalid valie");
+ } else if (name.equals(VAL_NOT_AFTER)) {
+ SimpleDateFormat formatter =
+ new SimpleDateFormat(DATE_FORMAT);
+ CertificateValidity validity = null;
+
+ try {
+ validity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ return formatter.format((Date)
+ validity.get(CertificateValidity.NOT_AFTER));
+ } catch (Exception e) {
+ CMS.debug("ValidityDefault: getValue " + e.toString());
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_VALIDITY",
+ getConfig(CONFIG_RANGE));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ // always + 60 seconds
+ String startTimeStr = getConfig(CONFIG_START_TIME);
+ try {
+ startTimeStr = mapPattern(request, startTimeStr);
+ } catch (IOException e) {
+ CMS.debug("ValidityDefault: populate " + e.toString());
+ }
+
+ if (startTimeStr == null || startTimeStr.equals("")) {
+ startTimeStr = "60";
+ }
+ int startTime = Integer.parseInt(startTimeStr);
+ Date notBefore = new Date(CMS.getCurrentDate().getTime() + (1000 * startTime));
+ long notAfterVal = 0;
+
+ try {
+ String rangeStr = getConfig(CONFIG_RANGE);
+ rangeStr = mapPattern(request, rangeStr);
+ notAfterVal = notBefore.getTime() +
+ (mDefault * Integer.parseInt(rangeStr));
+ } catch (Exception e) {
+ // configured value is not correct
+ CMS.debug("ValidityDefault: populate " + e.toString());
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_INVALID_PROPERTY", CONFIG_RANGE));
+ }
+ Date notAfter = new Date(notAfterVal);
+ CertificateValidity validity =
+ new CertificateValidity(notBefore, notAfter);
+
+ try {
+ info.set(X509CertInfo.VALIDITY, validity);
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("ValidityDefault: populate " + e.toString());
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_INVALID_PROPERTY", X509CertInfo.VALIDITY));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java
new file mode 100644
index 000000000..5a967a245
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java
@@ -0,0 +1,211 @@
+// --- 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.def;
+
+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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.authentication.DNPattern;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates server-side configurable subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsHKeySubjectNameDefault extends EnrollDefault {
+
+ public static final String PROP_PARAMS = "params";
+ public static final String CONFIG_DNPATTERN = "dnpattern";
+
+ public static final String VAL_NAME = "name";
+
+ /* default dn pattern if left blank or not set in the config */
+ protected static String DEFAULT_DNPATTERN =
+ "CN=SecureMember - $request.tokencuid$, OU=Subscriber, O=Red Hat, C=US";
+
+ protected IConfigStore mParamsConfig;
+
+ public nsHKeySubjectNameDefault() {
+ super();
+ addConfigName(CONFIG_DNPATTERN);
+
+ addValueName(CONFIG_DNPATTERN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ CMS.debug("nsHKeySubjectNameDefault: in getConfigDescriptor, name="+ name);
+ if (name.equals(CONFIG_DNPATTERN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ CMS.debug("nsHKeySubjectNameDefault: in getValueDescriptor name="+name);
+
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+
+ CMS.debug("nsHKeySubjectNameDefault: in setValue, value="+value);
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug("nsHKeySubjectNameDefault: setValue " + e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("nsHKeySubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsHKeySubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ CMS.debug("nsHKeySubjectNameDefault: in getValue, name="+name);
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ CMS.debug("nsHKeySubjectNameDefault: getValue info=" + info);
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ CMS.debug("nsHKeySubjectNameDefault: getValue name=" + sn);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("nsHKeySubjectNameDefault: getValue " + e.toString());
+
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ CMS.debug("nsHKeySubjectNameDefault: in getText");
+ return CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME",
+ getConfig(CONFIG_DNPATTERN));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ X500Name name = null;
+ CMS.debug("nsHKeySubjectNameDefault: in populate");
+
+ try {
+ String subjectName = getSubjectName(request);
+ CMS.debug("subjectName=" + subjectName);
+ if (subjectName == null || subjectName.equals(""))
+ return;
+
+ name = new X500Name(subjectName);
+ } catch (IOException e) {
+ // failed to build x500 name
+ CMS.debug("nsHKeySubjectNameDefault: populate " + e.toString());
+ }
+ if (name == null) {
+ // failed to build x500 name
+ }
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsHKeySubjectNameDefault: populate " + e.toString());
+ }
+ }
+
+ private String getSubjectName(IRequest request)
+ throws EProfileException, IOException {
+
+ CMS.debug("nsHKeySubjectNameDefault: in getSubjectName");
+
+ String pattern = getConfig(CONFIG_DNPATTERN);
+ if (pattern == null || pattern.equals("")) {
+ pattern = " ";
+ }
+
+ String sbjname = "";
+
+ if (request != null) {
+ CMS.debug("pattern = "+pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsHKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ }
+
+ return sbjname;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java
new file mode 100644
index 000000000..fe1c92fc3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java
@@ -0,0 +1,409 @@
+// --- 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.def;
+
+//ldap java sdk
+import netscape.ldap.*;
+import com.netscape.certsrv.ldap.*;
+
+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.*;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates server-side configurable subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsNKeySubjectNameDefault extends EnrollDefault {
+
+ public static final String PROP_LDAP = "ldap";
+ public static final String PROP_PARAMS = "params";
+ public static final String CONFIG_DNPATTERN = "dnpattern";
+ public static final String CONFIG_LDAP_STRING_ATTRS = "ldapStringAttributes";
+ public static final String CONFIG_LDAP_HOST = "ldap.ldapconn.host";
+ public static final String CONFIG_LDAP_PORT = "ldap.ldapconn.port";
+ public static final String CONFIG_LDAP_SEC_CONN = "ldap.ldapconn.secureConn";
+ public static final String CONFIG_LDAP_VER = "ldap.ldapconn.Version";
+ public static final String CONFIG_LDAP_BASEDN = "ldap.basedn";
+ public static final String CONFIG_LDAP_MIN_CONN = "ldap.minConns";
+ public static final String CONFIG_LDAP_MAX_CONN = "ldap.maxConns";
+
+ public static final String VAL_NAME = "name";
+
+ public static final String CONFIG_LDAP_VERS =
+ "2,3";
+
+ /* default dn pattern if left blank or not set in the config */
+ protected static String DEFAULT_DNPATTERN =
+ "CN=$request.aoluid$, E=$request.mail$";
+
+ /* ldap configuration sub-store */
+ boolean mInitialized = false;
+ protected IConfigStore mInstConfig;
+ protected IConfigStore mLdapConfig;
+ protected IConfigStore mParamsConfig;
+
+ /* ldap base dn */
+ protected String mBaseDN = null;
+
+ /* factory of anonymous ldap connections */
+ protected ILdapConnFactory mConnFactory = null;
+
+ /* the list of LDAP attributes with string values to retrieve to
+ * form the subject dn. */
+ protected String[] mLdapStringAttrs = null;
+
+ public nsNKeySubjectNameDefault() {
+ super();
+ addConfigName(CONFIG_DNPATTERN);
+ addConfigName(CONFIG_LDAP_STRING_ATTRS);
+ addConfigName(CONFIG_LDAP_HOST);
+ addConfigName(CONFIG_LDAP_PORT);
+ addConfigName(CONFIG_LDAP_SEC_CONN);
+ addConfigName(CONFIG_LDAP_VER);
+ addConfigName(CONFIG_LDAP_BASEDN);
+ addConfigName(CONFIG_LDAP_MIN_CONN);
+ addConfigName(CONFIG_LDAP_MAX_CONN);
+
+ addValueName(CONFIG_DNPATTERN);
+ addValueName(CONFIG_LDAP_STRING_ATTRS);
+ addValueName(CONFIG_LDAP_HOST);
+ addValueName(CONFIG_LDAP_PORT);
+ addValueName(CONFIG_LDAP_SEC_CONN);
+ addValueName(CONFIG_LDAP_VER);
+ addValueName(CONFIG_LDAP_BASEDN);
+ addValueName(CONFIG_LDAP_MIN_CONN);
+ addValueName(CONFIG_LDAP_MAX_CONN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mInstConfig = config;
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ CMS.debug("nsNKeySubjectNameDefault: in getConfigDescriptor, name="+ name);
+ if (name.equals(CONFIG_DNPATTERN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else if (name.equals(CONFIG_LDAP_STRING_ATTRS)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_LDAP_STRING_ATTRS"));
+ } else if (name.equals(CONFIG_LDAP_HOST)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_HOST_NAME"));
+ } else if (name.equals(CONFIG_LDAP_PORT)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_PORT_NUMBER"));
+ } else if (name.equals(CONFIG_LDAP_SEC_CONN)) {
+ return new Descriptor(IDescriptor.BOOLEAN,
+ null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NSNKEY_SECURE_CONN"));
+ } else if (name.equals(CONFIG_LDAP_VER)) {
+ return new Descriptor(IDescriptor.CHOICE, CONFIG_LDAP_VERS,
+ "3",
+ CMS.getUserMessage(locale, "CMS_PROFILE_NSNKEY_LDAP_VERSION"));
+ } else if (name.equals(CONFIG_LDAP_BASEDN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_BASEDN"));
+ } else if (name.equals(CONFIG_LDAP_MIN_CONN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_LDAP_MIN_CONN"));
+ } else if (name.equals(CONFIG_LDAP_MAX_CONN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_NSNKEY_LDAP_MAX_CONN"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ CMS.debug("nsNKeySubjectNameDefault: in getValueDescriptor name="+name);
+
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+
+ CMS.debug("nsNKeySubjectNameDefault: in setValue, value="+value);
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug("nsNKeySubjectNameDefault: setValue " + e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("nsNKeySubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsNKeySubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ CMS.debug("nsNKeySubjectNameDefault: in getValue, name="+name);
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ CMS.debug("nsNKeySubjectNameDefault: getValue info=" + info);
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ CMS.debug("nsNKeySubjectNameDefault: getValue name=" + sn);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("nsNKeySubjectNameDefault: getValue " + e.toString());
+
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ CMS.debug("nsNKeySubjectNameDefault: in getText");
+ return CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME",
+ getConfig(CONFIG_DNPATTERN));
+ }
+
+ public void ldapInit()
+ throws EProfileException {
+ if (mInitialized == true) return;
+
+ CMS.debug("nsNKeySubjectNameDefault: ldapInit(): begin");
+
+ try {
+ // cfu - XXX do more error handling here later
+ /* initialize ldap server configuration */
+ mParamsConfig = mInstConfig.getSubStore(PROP_PARAMS);
+ mLdapConfig = mParamsConfig.getSubStore(PROP_LDAP);
+ mBaseDN = mParamsConfig.getString(CONFIG_LDAP_BASEDN, null);
+ mConnFactory = CMS.getLdapAnonConnFactory();
+ mConnFactory.init(mLdapConfig);
+
+ /* initialize dn pattern */
+ String pattern = mParamsConfig.getString(CONFIG_DNPATTERN, null);
+
+ if (pattern == null || pattern.length() == 0)
+ pattern = DEFAULT_DNPATTERN;
+
+ /* initialize ldap string attribute list */
+ String ldapStringAttrs = mParamsConfig.getString(CONFIG_LDAP_STRING_ATTRS, null);
+
+ if ((ldapStringAttrs != null) && (ldapStringAttrs.length() != 0)) {
+ StringTokenizer pAttrs =
+ new StringTokenizer(ldapStringAttrs, ",", false);
+
+ mLdapStringAttrs = new String[pAttrs.countTokens()];
+
+ for (int i = 0; i < mLdapStringAttrs.length; i++) {
+ mLdapStringAttrs[i] = ((String) pAttrs.nextElement()).trim();
+ }
+ }
+ CMS.debug("nsNKeySubjectNameDefault: ldapInit(): done");
+ mInitialized = true;
+ } catch (Exception e) {
+ CMS.debug("nsNKeySubjectNameDefault: ldapInit(): "+e.toString());
+ // throw EProfileException...
+ throw new EProfileException("ldap init failure: "+e.toString());
+ }
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ X500Name name = null;
+ CMS.debug("nsNKeySubjectNameDefault: in populate");
+ ldapInit();
+ try {
+ // cfu - this goes to ldap
+ String subjectName = getSubjectName(request);
+ CMS.debug("subjectName=" + subjectName);
+ if (subjectName == null || subjectName.equals(""))
+ return;
+
+ name = new X500Name(subjectName);
+ } catch (IOException e) {
+ // failed to build x500 name
+ CMS.debug("nsNKeySubjectNameDefault: populate " + e.toString());
+ }
+ if (name == null) {
+ // failed to build x500 name
+ }
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsNKeySubjectNameDefault: populate " + e.toString());
+ }
+ }
+
+ private String getSubjectName(IRequest request)
+ throws EProfileException, IOException {
+
+ CMS.debug("nsNKeySubjectNameDefault: in getSubjectName");
+
+ String pattern = getConfig(CONFIG_DNPATTERN);
+ if (pattern == null || pattern.equals("")) {
+ pattern = " ";
+ }
+
+ LDAPConnection conn = null;
+ String userdn = null;
+ String sbjname = "";
+ // get DN from ldap to fill request
+ try {
+ if (mConnFactory == null) {
+ conn = null;
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): no LDAP connection");
+ throw new EProfileException("no LDAP connection");
+ } else {
+ conn = mConnFactory.getConn();
+ if( conn == null ) {
+ CMS.debug( "nsNKeySubjectNameDefault::getSubjectName() - " +
+ "no LDAP connection" );
+ throw new EProfileException( "no LDAP connection" );
+ }
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): got LDAP connection");
+ }
+
+ if (request != null) {
+ CMS.debug("pattern = "+pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ } else {
+ CMS.debug( "nsNKeySubjectNameDefault::getSubjectName() - " +
+ "request is null!" );
+ throw new EProfileException( "request is null" );
+ }
+ // retrieve the attributes
+ // get user dn.
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): about to search with basedn = "+ mBaseDN);
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(aoluid=" + request.getExtDataInString("aoluid") + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = res.next();
+
+ userdn = entry.getDN();
+ } else {// put into property file later - cfu
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): screen name does not exist");
+ throw new EProfileException("screenname does not exist");
+ }
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): retrieved entry for aoluid = "+request.getExtDataInString("aoluid"));;
+
+ LDAPEntry entry = null;
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): about to search with "+ mLdapStringAttrs.length +" attributes");
+ LDAPSearchResults results =
+ conn.search(userdn, LDAPv2.SCOPE_BASE, "objectclass=*",
+ mLdapStringAttrs, false);
+
+ if (!results.hasMoreElements()) {
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): no attributes");
+ throw new EProfileException("no ldap attributes found");
+ }
+ entry = results.next();
+ // set attrs into request
+ for (int i = 0; i < mLdapStringAttrs.length; i++) {
+ LDAPAttribute la =
+ entry.getAttribute(mLdapStringAttrs[i]);
+ if (la != null) {
+ String[] sla = la.getStringValueArray();
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): got attribute: "+sla[0]);
+ request.setExtData(mLdapStringAttrs[i], sla[0]);
+ }
+ }
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): attributes set in request");
+ } catch (Exception e) {
+ CMS.debug("nsNKeySubjectNameDefault: getSubjectName(): "+e.toString());
+ throw new EProfileException("getSubjectName() failure: "+e.toString());
+ } finally {
+ try {
+ if (conn != null)
+ mConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("nsNKeySubjectNameDefault: getSubjectName(): connection return failure");
+ }
+ }
+ return sbjname;
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java
new file mode 100644
index 000000000..b1f09e427
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java
@@ -0,0 +1,212 @@
+// --- 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.def;
+
+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 com.netscape.cms.profile.common.*;
+import com.netscape.cms.authentication.DNPattern;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates server-side configurable subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsTokenDeviceKeySubjectNameDefault extends EnrollDefault {
+
+ public static final String PROP_PARAMS = "params";
+ public static final String CONFIG_DNPATTERN = "dnpattern";
+
+ public static final String VAL_NAME = "name";
+
+ /* default dn pattern if left blank or not set in the config */
+ protected static String DEFAULT_DNPATTERN =
+ "Token Key Device - $request.tokencuid$";
+
+ protected IConfigStore mParamsConfig;
+
+ public nsTokenDeviceKeySubjectNameDefault() {
+ super();
+ addConfigName(CONFIG_DNPATTERN);
+
+ addValueName(CONFIG_DNPATTERN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in getConfigDescriptor, name="+ name);
+ if (name.equals(CONFIG_DNPATTERN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in getValueDescriptor name="+name);
+
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in setValue, value="+value);
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: setValue " + e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException
+ {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in getValue, name="+name);
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: getValue info=" + info);
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: getValue name=" + sn);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: getValue " + e.toString());
+
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in getText");
+ return CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME",
+ getConfig(CONFIG_DNPATTERN));
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ X500Name name = null;
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in populate");
+
+ try {
+ String subjectName = getSubjectName(request);
+ CMS.debug("subjectName=" + subjectName);
+ if (subjectName == null || subjectName.equals(""))
+ return;
+
+ name = new X500Name(subjectName);
+ } catch (IOException e) {
+ // failed to build x500 name
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: populate " + e.toString());
+ }
+ if (name == null) {
+ // failed to build x500 name
+ }
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: populate " + e.toString());
+ }
+ }
+
+ private String getSubjectName(IRequest request)
+ throws EProfileException, IOException {
+
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: in getSubjectName");
+
+ String pattern = getConfig(CONFIG_DNPATTERN);
+ if (pattern == null || pattern.equals("")) {
+ pattern = " ";
+ }
+
+ String sbjname = "";
+
+ if (request != null) {
+ CMS.debug("pattern = "+pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsTokenDeviceKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ }
+
+ return sbjname;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java
new file mode 100644
index 000000000..ef7fe53cf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java
@@ -0,0 +1,448 @@
+// --- 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.def;
+
+//ldap java sdk
+import netscape.ldap.*;
+import com.netscape.certsrv.ldap.*;
+
+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.*;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates server-side configurable subject name
+ * into the certificate template.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsTokenUserKeySubjectNameDefault extends EnrollDefault {
+
+ public static final String PROP_LDAP = "ldap";
+ public static final String PROP_PARAMS = "params";
+ public static final String CONFIG_DNPATTERN = "dnpattern";
+ public static final String CONFIG_LDAP_ENABLE = "ldap.enable";
+ public static final String CONFIG_LDAP_SEARCH_NAME = "ldap.searchName";
+ public static final String CONFIG_LDAP_STRING_ATTRS = "ldapStringAttributes";
+ public static final String CONFIG_LDAP_HOST = "ldap.ldapconn.host";
+ public static final String CONFIG_LDAP_PORT = "ldap.ldapconn.port";
+ public static final String CONFIG_LDAP_SEC_CONN = "ldap.ldapconn.secureConn";
+ public static final String CONFIG_LDAP_VER = "ldap.ldapconn.Version";
+ public static final String CONFIG_LDAP_BASEDN = "ldap.basedn";
+ public static final String CONFIG_LDAP_MIN_CONN = "ldap.minConns";
+ public static final String CONFIG_LDAP_MAX_CONN = "ldap.maxConns";
+
+ public static final String VAL_NAME = "name";
+
+ public static final String CONFIG_LDAP_VERS =
+ "2,3";
+
+ /* default dn pattern if left blank or not set in the config */
+ protected static String DEFAULT_DNPATTERN =
+ "CN=$request.uid$, E=$request.mail$";
+
+ /* ldap configuration sub-store */
+ boolean mldapInitialized = false;
+ boolean mldapEnabled = false;
+ protected IConfigStore mInstConfig;
+ protected IConfigStore mLdapConfig;
+ protected IConfigStore mParamsConfig;
+
+ /* ldap base dn */
+ protected String mBaseDN = null;
+
+ /* factory of anonymous ldap connections */
+ protected ILdapConnFactory mConnFactory = null;
+
+ /* the list of LDAP attributes with string values to retrieve to
+ * form the subject dn. */
+ protected String[] mLdapStringAttrs = null;
+
+ public nsTokenUserKeySubjectNameDefault() {
+ super();
+ addConfigName(CONFIG_DNPATTERN);
+ addConfigName(CONFIG_LDAP_ENABLE);
+ addConfigName(CONFIG_LDAP_SEARCH_NAME);
+ addConfigName(CONFIG_LDAP_STRING_ATTRS);
+ addConfigName(CONFIG_LDAP_HOST);
+ addConfigName(CONFIG_LDAP_PORT);
+ addConfigName(CONFIG_LDAP_SEC_CONN);
+ addConfigName(CONFIG_LDAP_VER);
+ addConfigName(CONFIG_LDAP_BASEDN);
+ addConfigName(CONFIG_LDAP_MIN_CONN);
+ addConfigName(CONFIG_LDAP_MAX_CONN);
+
+ addValueName(CONFIG_DNPATTERN);
+ addValueName(CONFIG_LDAP_ENABLE);
+ addValueName(CONFIG_LDAP_SEARCH_NAME);
+ addValueName(CONFIG_LDAP_STRING_ATTRS);
+ addValueName(CONFIG_LDAP_HOST);
+ addValueName(CONFIG_LDAP_PORT);
+ addValueName(CONFIG_LDAP_SEC_CONN);
+ addValueName(CONFIG_LDAP_VER);
+ addValueName(CONFIG_LDAP_BASEDN);
+ addValueName(CONFIG_LDAP_MIN_CONN);
+ addValueName(CONFIG_LDAP_MAX_CONN);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mInstConfig = config;
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in getConfigDescriptor, name="+ name);
+ if (name.equals(CONFIG_DNPATTERN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null, null, CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else if (name.equals(CONFIG_LDAP_STRING_ATTRS)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_STRING_ATTRS"));
+ } else if (name.equals(CONFIG_LDAP_ENABLE)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_ENABLE"));
+ } else if (name.equals(CONFIG_LDAP_SEARCH_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_SEARCH_NAME"));
+ } else if (name.equals(CONFIG_LDAP_HOST)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_HOST_NAME"));
+ } else if (name.equals(CONFIG_LDAP_PORT)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_PORT_NUMBER"));
+ } else if (name.equals(CONFIG_LDAP_SEC_CONN)) {
+ return new Descriptor(IDescriptor.BOOLEAN,
+ null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_TOKENKEY_LDAP_SECURE_CONN"));
+ } else if (name.equals(CONFIG_LDAP_VER)) {
+ return new Descriptor(IDescriptor.CHOICE, CONFIG_LDAP_VERS,
+ "3",
+ CMS.getUserMessage(locale, "CMS_PROFILE_TOKENKEY_LDAP_VERSION"));
+ } else if (name.equals(CONFIG_LDAP_BASEDN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_BASEDN"));
+ } else if (name.equals(CONFIG_LDAP_MIN_CONN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_MIN_CONN"));
+ } else if (name.equals(CONFIG_LDAP_MAX_CONN)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,"CMS_PROFILE_TOKENKEY_LDAP_MAX_CONN"));
+ } else {
+ return null;
+ }
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in getValueDescriptor name="+name);
+
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING,
+ null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in setValue, value="+value);
+
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: setValue " + e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("nsTokenUserKeySubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsTokenUserKeySubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in getValue, name="+name);
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getValue info=" + info);
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getValue name=" + sn);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getValue " + e.toString());
+
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in getText");
+ return CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME",
+ getConfig(CONFIG_DNPATTERN));
+ }
+
+ public void ldapInit()
+ throws EProfileException {
+ if (mldapInitialized == true) return;
+
+ CMS.debug("nsTokenUserKeySubjectNameDefault: ldapInit(): begin");
+
+ try {
+ // cfu - XXX do more error handling here later
+ /* initialize ldap server configuration */
+ mParamsConfig = mInstConfig.getSubStore(PROP_PARAMS);
+ mLdapConfig = mParamsConfig.getSubStore(PROP_LDAP);
+ mldapEnabled = mParamsConfig.getBoolean(CONFIG_LDAP_ENABLE,
+ false);
+ if (mldapEnabled == false)
+ return;
+
+ mBaseDN = mParamsConfig.getString(CONFIG_LDAP_BASEDN, null);
+ mConnFactory = CMS.getLdapAnonConnFactory();
+ mConnFactory.init(mLdapConfig);
+
+ /* initialize dn pattern */
+ String pattern = mParamsConfig.getString(CONFIG_DNPATTERN, null);
+
+ if (pattern == null || pattern.length() == 0)
+ pattern = DEFAULT_DNPATTERN;
+
+ /* initialize ldap string attribute list */
+ String ldapStringAttrs = mParamsConfig.getString(CONFIG_LDAP_STRING_ATTRS, null);
+
+ if ((ldapStringAttrs != null) && (ldapStringAttrs.length() != 0)) {
+ StringTokenizer pAttrs =
+ new StringTokenizer(ldapStringAttrs, ",", false);
+
+ mLdapStringAttrs = new String[pAttrs.countTokens()];
+
+ for (int i = 0; i < mLdapStringAttrs.length; i++) {
+ mLdapStringAttrs[i] = ((String) pAttrs.nextElement()).trim();
+ }
+ }
+ CMS.debug("nsTokenUserKeySubjectNameDefault: ldapInit(): done");
+ mldapInitialized = true;
+ } catch (Exception e) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: ldapInit(): "+e.toString());
+ // throw EProfileException...
+ throw new EProfileException("ldap init failure: "+e.toString());
+ }
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ X500Name name = null;
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in populate");
+ldapInit();
+ try {
+ // cfu - this goes to ldap
+ String subjectName = getSubjectName(request);
+ CMS.debug("subjectName=" + subjectName);
+ if (subjectName == null || subjectName.equals(""))
+ return;
+
+ name = new X500Name(subjectName);
+ } catch (IOException e) {
+ // failed to build x500 name
+ CMS.debug("nsTokenUserKeySubjectNameDefault: populate " + e.toString());
+ }
+ if (name == null) {
+ // failed to build x500 name
+ }
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("nsTokenUserKeySubjectNameDefault: populate " + e.toString());
+ }
+ }
+
+ private String getSubjectName(IRequest request)
+ throws EProfileException, IOException {
+
+ CMS.debug("nsTokenUserKeySubjectNameDefault: in getSubjectName");
+
+ String pattern = getConfig(CONFIG_DNPATTERN);
+ if (pattern == null || pattern.equals("")) {
+ pattern = " ";
+ }
+ String sbjname = "";
+
+ if (mldapInitialized == false) {
+ if (request != null) {
+ CMS.debug("pattern = "+pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ }
+ return sbjname;
+ }
+
+ // ldap is initialized, do more substitution
+ String searchName = getConfig(CONFIG_LDAP_SEARCH_NAME);
+ if (searchName == null || searchName.equals("")) {
+ searchName = "uid";
+ }
+
+ LDAPConnection conn = null;
+ String userdn = null;
+ // get DN from ldap to fill request
+ try {
+ if (mConnFactory == null) {
+ conn = null;
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): no LDAP connection");
+ throw new EProfileException("no LDAP connection");
+ } else {
+ conn = mConnFactory.getConn();
+ if( conn == null ) {
+ CMS.debug( "nsTokenUserKeySubjectNameDefault::getSubjectName() - " +
+ "no LDAP connection" );
+ throw new EProfileException( "no LDAP connection" );
+ }
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): got LDAP connection");
+ }
+ // retrieve the attributes
+ // get user dn.
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): about to search with basedn = "+ mBaseDN);
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "("+ searchName + "=" + request.getExtDataInString("uid") + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = res.next();
+
+ userdn = entry.getDN();
+ } else {// put into property file later - cfu
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): "+ searchName + " does not exist");
+ throw new EProfileException("id does not exist");
+ }
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): retrieved entry for "+searchName + " = "+request.getExtDataInString("uid"));
+
+ LDAPEntry entry = null;
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): about to search with "+ mLdapStringAttrs.length +" attributes");
+ LDAPSearchResults results =
+ conn.search(userdn, LDAPv2.SCOPE_BASE, "objectclass=*",
+ mLdapStringAttrs, false);
+
+ if (!results.hasMoreElements()) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): no attributes");
+ throw new EProfileException("no ldap attributes found");
+ }
+ entry = results.next();
+ // set attrs into request
+ for (int i = 0; i < mLdapStringAttrs.length; i++) {
+ LDAPAttribute la =
+ entry.getAttribute(mLdapStringAttrs[i]);
+ if (la != null) {
+ String[] sla = la.getStringValueArray();
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute: "+mLdapStringAttrs[i]+
+ "=" + escapeValueRfc1779(sla[0], false).toString());
+ request.setExtData(mLdapStringAttrs[i], escapeValueRfc1779(sla[0], false).toString());
+ }
+ }
+//cfu
+ if (request != null) {
+ CMS.debug("pattern = "+pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ } else {
+ CMS.debug( "nsTokenUserKeySubjectNameDefault::getSubjectName() "
+ + "- request is null!" );
+ throw new EProfileException( "request is null" );
+ }
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): attributes set in request");
+
+ } catch (Exception e) {
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): "+e.toString());
+ throw new EProfileException("getSubjectName() failure: "+e.toString());
+ } finally {
+ try {
+ if (conn != null)
+ mConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("nsTokenUserKeySubjectNameDefault: getSubjectName(): connection return failure");
+ }
+ }
+ return sbjname;
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java b/pki/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java
new file mode 100644
index 000000000..4c368c03e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java
@@ -0,0 +1,129 @@
+// --- 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.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+
+
+/**
+ * This class implements the certificate request input.
+ * This input populates 2 main fields to the enrollment page:
+ * 1/ Certificate Request Type, 2/ Certificate Request
+ * <p>
+ *
+ * This input usually is used by an enrollment profile for
+ * certificate requests.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCCertReqInput extends EnrollInput implements IProfileInput {
+ public static final String VAL_CERT_REQUEST_TYPE =
+ EnrollProfile.CTX_CERT_REQUEST_TYPE;
+ public static final String VAL_CERT_REQUEST =
+ EnrollProfile.CTX_CERT_REQUEST;
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public CMCCertReqInput() {
+ addValueName(VAL_CERT_REQUEST);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_CERT_REQ_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_CERT_REQ_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String cert_request = ctx.get(VAL_CERT_REQUEST);
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+
+ if (msgs == null) {
+ return;
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+ if (seqNum == null) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_SEQ_NUM"));
+ }
+
+ mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request);
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CERT_REQUEST)) {
+ return new Descriptor(IDescriptor.CERT_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_CERT_REQ"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/CertReqInput.java b/pki/base/common/src/com/netscape/cms/profile/input/CertReqInput.java
new file mode 100644
index 000000000..565b7795e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/CertReqInput.java
@@ -0,0 +1,189 @@
+// --- 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.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+
+
+/**
+ * This class implements the certificate request input.
+ * This input populates 2 main fields to the enrollment page:
+ * 1/ Certificate Request Type, 2/ Certificate Request
+ * <p>
+ *
+ * This input usually is used by an enrollment profile for
+ * certificate requests.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertReqInput extends EnrollInput implements IProfileInput {
+ public static final String VAL_CERT_REQUEST_TYPE =
+ EnrollProfile.CTX_CERT_REQUEST_TYPE;
+ public static final String VAL_CERT_REQUEST =
+ EnrollProfile.CTX_CERT_REQUEST;
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public CertReqInput() {
+ addValueName(VAL_CERT_REQUEST_TYPE);
+ addValueName(VAL_CERT_REQUEST);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_CERT_REQ_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_CERT_REQ_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String cert_request_type = ctx.get(VAL_CERT_REQUEST_TYPE);
+ String cert_request = ctx.get(VAL_CERT_REQUEST);
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ if (cert_request_type == null) {
+ CMS.debug("CertReqInput: populate - invalid cert request type " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ ""));
+ }
+
+ if (cert_request_type.equals(EnrollProfile.REQ_TYPE_PKCS10)) {
+ PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), cert_request);
+
+ if (pkcs10 == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+
+ mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request);
+ } else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_KEYGEN)) {
+ DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), cert_request);
+
+ if (keygen == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+
+ mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request);
+ } else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_CRMF)) {
+ CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), cert_request);
+
+ if (msgs == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+ for (int x = 0; x < msgs.length; x++) {
+ verifyPOP(getLocale(request), msgs[x]);
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+
+ mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request
+ );
+ } else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_CMC)) {
+ TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+
+ if (msgs == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+ if (seqNum == null) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_SEQ_NUM"));
+ }
+
+ mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request);
+ } else {
+ // error
+ CMS.debug("CertReqInput: populate - invalid cert request type " +
+ cert_request_type);
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ cert_request_type));
+ }
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_CERT_REQUEST_TYPE)) {
+ return new Descriptor(IDescriptor.CERT_REQUEST_TYPE, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_CERT_REQ_TYPE"));
+ } else if (name.equals(VAL_CERT_REQUEST)) {
+ return new Descriptor(IDescriptor.CERT_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_CERT_REQ"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java b/pki/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java
new file mode 100644
index 000000000..dfb7be887
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java
@@ -0,0 +1,164 @@
+// --- 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 org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+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 dual key generation input.
+ * This input populates parameters to the enrollment
+ * pages so that a CRMF request containing 2 certificate
+ * requests will be generated.
+ * <p>
+ *
+ * This input can only be used with Netscape 7.x or later
+ * clients.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class DualKeyGenInput extends EnrollInput implements IProfileInput {
+
+ public static final String VAL_KEYGEN_REQUEST_TYPE =
+ EnrollProfile.CTX_CERT_REQUEST_TYPE;
+ public static final String VAL_KEYGEN_REQUEST =
+ EnrollProfile.CTX_CERT_REQUEST;
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public DualKeyGenInput() {
+ addValueName(VAL_KEYGEN_REQUEST_TYPE);
+ addValueName(VAL_KEYGEN_REQUEST);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_DUAL_KEY_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_DUAL_KEY_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String keygen_request_type = ctx.get(VAL_KEYGEN_REQUEST_TYPE);
+ String keygen_request = ctx.get(VAL_KEYGEN_REQUEST);
+
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ if (keygen_request_type == null) {
+ CMS.debug("DualKeyGenInput: populate - invalid cert request type " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ ""));
+ }
+ if (keygen_request_type.startsWith("pkcs10")) {
+ PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), keygen_request);
+
+ mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request);
+ } else if (keygen_request_type.startsWith("keygen")) {
+ DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), keygen_request);
+
+ mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request);
+ } else if (keygen_request_type.startsWith("crmf")) {
+ CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), keygen_request);
+
+ if (msgs == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+ for (int x = 0; x < msgs.length; x++) {
+ verifyPOP(getLocale(request), msgs[x]);
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+
+ if (seqNum == null) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_SEQ_NUM"));
+ }
+
+ mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request);
+ } else {
+ // error
+ CMS.debug("DualKeyGenInput: populate - " +
+ "invalid cert request type " + keygen_request_type);
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ keygen_request_type));
+ }
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_KEYGEN_REQUEST_TYPE)) {
+ return new Descriptor(IDescriptor.DUAL_KEYGEN_REQUEST_TYPE, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE"));
+ } else if (name.equals(VAL_KEYGEN_REQUEST)) {
+ return new Descriptor(IDescriptor.DUAL_KEYGEN_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/EnrollInput.java b/pki/base/common/src/com/netscape/cms/profile/input/EnrollInput.java
new file mode 100644
index 000000000..949e58b1a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/EnrollInput.java
@@ -0,0 +1,297 @@
+// --- 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.util.*;
+
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the base enrollment input.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollInput implements IProfileInput {
+
+ private final static String LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION =
+ "LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2";
+
+ protected IConfigStore mConfig = null;
+ protected Vector mValueNames = new Vector();
+ protected Vector mConfigNames = new Vector();
+ protected IProfile mProfile = null;
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ mProfile = profile;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * @param ctx profile context
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public abstract void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale user locale
+ * @return localized input name
+ */
+ public abstract String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale user locale
+ * @return localized input description
+ */
+ public abstract String getText(Locale locale);
+
+ /**
+ * Retrieves the descriptor of the given value
+ * property by name.
+ *
+ * @param locale user locale
+ * @param name property name
+ * @return descriptor of the property
+ */
+ public abstract IDescriptor getValueDescriptor(Locale locale, String name);
+
+
+ public void addValueName(String name) {
+ mValueNames.addElement(name);
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ return mValueNames.elements();
+ }
+
+ public void addConfigName(String name) {
+ mConfigNames.addElement(name);
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (mConfig.getSubStore("params") == null) {
+ //
+ } else {
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public String getConfig(String name) {
+ try {
+ if (mConfig == null) {
+ return null;
+ }
+ if (mConfig.getSubStore("params") != null) {
+ return mConfig.getSubStore("params").getString(name);
+ }
+ } catch (EBaseException e) {
+ }
+ return "";
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ return request.getExtDataInString(name);
+ }
+
+ /**
+ * Sets the value of the given value parameter by name.
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value) throws EPropertyException {
+ request.setExtData(name, value);
+ }
+
+ public Locale getLocale(IRequest request) {
+ Locale locale = null;
+ String language = request.getExtDataInString(
+ EnrollProfile.REQUEST_LOCALE);
+ if (language != null) {
+ locale = new Locale(language);
+ }
+ return locale;
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void verifyPOP(Locale locale, CertReqMsg certReqMsg)
+ throws EProfileException {
+ CMS.debug("EnrollInput ::in verifyPOP");
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ if (!certReqMsg.hasPop()) {
+ CMS.debug("CertReqMsg has not POP, return");
+ return;
+ }
+ ProofOfPossession pop = certReqMsg.getPop();
+ ProofOfPossession.Type popType = pop.getType();
+
+ if (popType != ProofOfPossession.SIGNATURE) {
+ CMS.debug("not POP SIGNATURE, return");
+ return;
+ }
+
+ try {
+ if (CMS.getConfigStore().getBoolean("cms.skipPOPVerify", false)) {
+ CMS.debug("skipPOPVerify on, return");
+ return;
+ }
+ CMS.debug("POP verification begins:");
+ CryptoManager cm = CryptoManager.getInstance();
+ String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
+ "Internal Key Storage Token");
+ CryptoToken verifyToken = cm.getTokenByName(tokenName);
+ if (tokenName.equals("Internal Key Storage Token")) {
+ //use internal token
+ CMS.debug("POP verification using internal token");
+ certReqMsg.verify();
+ } else {
+ CMS.debug("POP verification using token:"+ tokenName);
+ certReqMsg.verify(verifyToken);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.SUCCESS );
+ audit( auditMessage );
+ } catch (Exception e) {
+
+ CMS.debug("Failed POP verify! "+e.toString());
+ CMS.debug(e);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new EProfileException(CMS.getUserMessage(locale,
+ "CMS_POP_VERIFICATION_ERROR"));
+ }
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java b/pki/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java
new file mode 100644
index 000000000..e79372b16
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java
@@ -0,0 +1,141 @@
+// --- 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.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 java.net.*;
+import java.security.*;
+
+
+/**
+ * This class implements the image
+ * input that collects a picture.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class FileSigningInput extends EnrollInput implements IProfileInput {
+
+ public static final String URL = "file_signing_url";
+ public static final String TEXT = "file_signing_text";
+ public static final String SIZE = "file_signing_size";
+ public static final String DIGEST = "file_signing_digest";
+ public static final String DIGEST_TYPE = "file_signing_digest_type";
+
+ public FileSigningInput() {
+ addValueName(URL);
+ addValueName(TEXT);
+ }
+
+ /**
+ * 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_FILE_SIGNING_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_FILE_SIGNING_TEXT");
+ }
+
+ public String toHexString(byte data[])
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < data.length; i++) {
+ int v = data[i] & 0xff;
+ if (v <= 9) {
+ sb.append("0");
+ }
+ sb.append(Integer.toHexString(v));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ request.setExtData(TEXT, ctx.get(TEXT));
+ request.setExtData(URL, ctx.get(URL));
+ request.setExtData(DIGEST_TYPE, "SHA256");
+
+ try {
+ // retrieve file and calculate the hash
+ URL url = new URL(ctx.get(URL));
+ URLConnection c = url.openConnection();
+ c.setAllowUserInteraction(false);
+ c.setDoInput(true);
+ c.setDoOutput(false);
+ c.setUseCaches(false);
+ c.connect();
+ int len = c.getContentLength();
+ request.setExtData(SIZE, Integer.toString(len));
+ BufferedInputStream is = new BufferedInputStream(c.getInputStream());
+ byte data[] = new byte[len];
+ is.read(data, 0, len);
+ is.close();
+
+ // calculate digest
+ MessageDigest digester = MessageDigest.getInstance("SHA256");
+ byte digest[] = digester.digest(data);
+ request.setExtData(DIGEST, toHexString(digest));
+ } catch (Exception e) {
+ CMS.debug("FileSigningInput populate failure " + e);
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_FILE_NOT_FOUND"));
+ }
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(URL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_FILE_SIGNING_URL"));
+ } else if (name.equals(TEXT)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_FILE_SIGNING_TEXT"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/GenericInput.java b/pki/base/common/src/com/netscape/cms/profile/input/GenericInput.java
new file mode 100644
index 000000000..6358f272d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/GenericInput.java
@@ -0,0 +1,155 @@
+// --- 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.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.*;
+
+
+/**
+ * This class implements a generic input.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenericInput extends EnrollInput implements IProfileInput {
+
+ public static final String CONFIG_NUM = "gi_num";
+ public static final String CONFIG_DISPLAY_NAME = "gi_display_name";
+ public static final String CONFIG_PARAM_NAME = "gi_param_name";
+ public static final String CONFIG_ENABLE = "gi_param_enable";
+
+ public static final int DEF_NUM = 5;
+
+ public GenericInput() {
+ int num = getNum();
+ for (int i = 0; i < num; i++) {
+ addConfigName(CONFIG_PARAM_NAME + i);
+ addConfigName(CONFIG_DISPLAY_NAME + i);
+ addConfigName(CONFIG_ENABLE + i);
+ }
+ }
+
+ protected int getNum() {
+ int num = DEF_NUM;
+ String numC = getConfig(CONFIG_NUM);
+
+ if (numC != null) {
+ try {
+ num = Integer.parseInt(numC);
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return 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_GENERIC_NAME_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_GENERIC_NAME_TEXT");
+ }
+
+ /**
+ * Returns selected value names based on the configuration.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+ int num = getNum();
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_ENABLE + i);
+ if (enable != null && enable.equals("true")) {
+ v.addElement(getConfig(CONFIG_PARAM_NAME + i));
+ }
+ }
+ return v.elements();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ int num = getNum();
+ for (int i = 0; i < num; i++) {
+ String enable = getConfig(CONFIG_ENABLE + i);
+ if (enable != null && enable.equals("true")) {
+ String param = getConfig(CONFIG_PARAM_NAME + i);
+ request.setExtData(param, ctx.get(param));
+ }
+ }
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ int num = getNum();
+ for (int i = 0; i < num; i++) {
+ if (name.equals(CONFIG_PARAM_NAME + i)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GI_PARAM_NAME") + i);
+ } else if (name.equals(CONFIG_DISPLAY_NAME + i)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_GI_DISPLAY_NAME") + i);
+ } else if (name.equals(CONFIG_ENABLE + i)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "false",
+ CMS.getUserMessage(locale, "CMS_PROFILE_GI_ENABLE") + i);
+ }
+ } // for
+ return null;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ int num = getNum();
+ for (int i = 0; i < num; i++) {
+ String param = getConfig(CONFIG_PARAM_NAME + i);
+ if (param != null && param.equals(name)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ getConfig(CONFIG_DISPLAY_NAME + i));
+ }
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/ImageInput.java b/pki/base/common/src/com/netscape/cms/profile/input/ImageInput.java
new file mode 100644
index 000000000..ac913a93e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/ImageInput.java
@@ -0,0 +1,86 @@
+// --- 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.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.*;
+
+
+/**
+ * This class implements the image
+ * input that collects a picture.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ImageInput extends EnrollInput implements IProfileInput {
+
+ public static final String IMAGE_URL = "image_url";
+
+ public ImageInput() {
+ addValueName(IMAGE_URL);
+ }
+
+ /**
+ * 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_IMAGE_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IMAGE_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ request.setExtData(IMAGE_URL, ctx.get(IMAGE_URL));
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(IMAGE_URL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IMAGE_URL"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java b/pki/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java
new file mode 100644
index 000000000..cc8f9a70d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java
@@ -0,0 +1,187 @@
+// --- 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 org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the key generation input that
+ * populates parameters to the enrollment page for
+ * key generation.
+ * <p>
+ *
+ * This input normally is used with user-based or
+ * non certificate request profile.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyGenInput extends EnrollInput implements IProfileInput {
+
+ public static final String VAL_KEYGEN_REQUEST_TYPE =
+ EnrollProfile.CTX_CERT_REQUEST_TYPE;
+ public static final String VAL_KEYGEN_REQUEST =
+ EnrollProfile.CTX_CERT_REQUEST;
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public KeyGenInput() {
+ addValueName(VAL_KEYGEN_REQUEST_TYPE);
+ addValueName(VAL_KEYGEN_REQUEST);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEY_GEN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEY_GEN_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String keygen_request_type = ctx.get(VAL_KEYGEN_REQUEST_TYPE);
+ String keygen_request = ctx.get(VAL_KEYGEN_REQUEST);
+
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ if (keygen_request_type == null) {
+ CMS.debug("KeyGenInput: populate - invalid cert request type " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ ""));
+ }
+ if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_PKCS10)) {
+ PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), keygen_request);
+
+ if (pkcs10 == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+
+ mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request);
+ } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_KEYGEN)) {
+ DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), keygen_request);
+
+ if (keygen == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+
+ mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request);
+ } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CRMF)) {
+ CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), keygen_request);
+
+ if (msgs == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+ for (int x = 0; x < msgs.length; x++) {
+ verifyPOP(getLocale(request), msgs[x]);
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+
+ mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request);
+ } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CMC)) {
+ TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), keygen_request);
+
+ if (msgs == null) {
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
+ }
+ // This profile only handle the first request in CRMF
+ Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM);
+
+ if (seqNum == null) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_UNKNOWN_SEQ_NUM"));
+ }
+
+ mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request);
+ } else {
+ // error
+ CMS.debug("DualKeyGenInput: populate - " +
+ "invalid cert request type " + keygen_request_type);
+ throw new EProfileException(CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE",
+ keygen_request_type));
+ }
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_KEYGEN_REQUEST_TYPE)) {
+ return new Descriptor(IDescriptor.KEYGEN_REQUEST_TYPE, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE"));
+ } else if (name.equals(VAL_KEYGEN_REQUEST)) {
+ return new Descriptor(IDescriptor.KEYGEN_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ"));
+ }
+ return null;
+ }
+}
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/profile/input/SubjectDNInput.java b/pki/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java
new file mode 100644
index 000000000..1f2512ff3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java
@@ -0,0 +1,141 @@
+// --- 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 plugin accepts subject DN from end user.
+ */
+public class SubjectDNInput extends EnrollInput implements IProfileInput {
+
+ public static final String VAL_SUBJECT = "subject";
+
+ public SubjectDNInput() {
+ }
+
+ /**
+ * 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_SUBJECT_NAME_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SUBJECT_NAME_TEXT");
+ }
+
+
+ public String getConfig(String name) {
+ String config = super.getConfig(name);
+ if (config == null || config.equals(""))
+ return "true";
+ return config;
+ }
+
+ /**
+ * Returns selected value names based on the configuration.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+ v.addElement(VAL_SUBJECT);
+ return v.elements();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+ String subjectName = "";
+
+ subjectName = ctx.get(VAL_SUBJECT);
+ if (subjectName.equals("")) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ }
+ X500Name name = null;
+
+ try {
+ name = new X500Name(subjectName);
+ } catch (Exception e) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_INVALID_SUBJECT_NAME", subjectName));
+ }
+ parseSubjectName(name, info, request);
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_SUBJECT)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME"));
+ }
+ return null;
+ }
+
+ protected void parseSubjectName(X500Name subj, X509CertInfo info, IRequest req)
+ throws EProfileException {
+ try {
+ req.setExtData(EnrollProfile.REQUEST_SUBJECT_NAME,
+ new CertificateSubjectName(subj));
+ } catch (Exception e) {
+ CMS.debug("SubjectNameInput: parseSubject Name " +
+ e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java b/pki/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java
new file mode 100644
index 000000000..fec7ceabb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java
@@ -0,0 +1,382 @@
+// --- 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 subject name input
+ * that populates text fields to the enrollment
+ * page so that distinguished name parameters
+ * can be collected from the user.
+ * <p>
+ * The collected parameters could be used for
+ * fomulating the subject name in the certificate.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubjectNameInput extends EnrollInput implements IProfileInput {
+
+ public static final String CONFIG_UID = "sn_uid";
+ public static final String CONFIG_EMAIL = "sn_e";
+ public static final String CONFIG_CN = "sn_cn";
+ public static final String CONFIG_OU3 = "sn_ou3";
+ public static final String CONFIG_OU2 = "sn_ou2";
+ public static final String CONFIG_OU1 = "sn_ou1";
+ public static final String CONFIG_OU = "sn_ou";
+ public static final String CONFIG_O = "sn_o";
+ public static final String CONFIG_C = "sn_c";
+
+ public static final String VAL_UID = "sn_uid";
+ public static final String VAL_EMAIL = "sn_e";
+ public static final String VAL_CN = "sn_cn";
+ public static final String VAL_OU3 = "sn_ou3";
+ public static final String VAL_OU2 = "sn_ou2";
+ public static final String VAL_OU1 = "sn_ou1";
+ public static final String VAL_OU = "sn_ou";
+ public static final String VAL_O = "sn_o";
+ public static final String VAL_C = "sn_c";
+
+ public SubjectNameInput() {
+ addConfigName(CONFIG_UID);
+ addConfigName(CONFIG_EMAIL);
+ addConfigName(CONFIG_CN);
+ addConfigName(CONFIG_OU3);
+ addConfigName(CONFIG_OU2);
+ addConfigName(CONFIG_OU1);
+ addConfigName(CONFIG_OU);
+ addConfigName(CONFIG_O);
+ addConfigName(CONFIG_C);
+ }
+
+ /**
+ * 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_SUBJECT_NAME_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SUBJECT_NAME_TEXT");
+ }
+
+
+ public String getConfig(String name) {
+ String config = super.getConfig(name);
+ if (config == null || config.equals(""))
+ return "true";
+ return config;
+ }
+
+ /**
+ * Returns selected value names based on the configuration.
+ */
+ public Enumeration getValueNames() {
+ Vector v = new Vector();
+ String c_uid = getConfig(CONFIG_UID);
+ if (c_uid == null || c_uid.equals("")) {
+ v.addElement(VAL_UID); // default case
+ } else {
+ if (c_uid.equals("true")) {
+ v.addElement(VAL_UID);
+ }
+ }
+ String c_email = getConfig(CONFIG_EMAIL);
+ if (c_email == null || c_email.equals("")) {
+ v.addElement(VAL_EMAIL);
+ } else {
+ if (c_email.equals("true")) {
+ v.addElement(VAL_EMAIL);
+ }
+ }
+ String c_cn = getConfig(CONFIG_CN);
+ if (c_cn == null || c_cn.equals("")) {
+ v.addElement(VAL_CN);
+ } else {
+ if (c_cn.equals("true")) {
+ v.addElement(VAL_CN);
+ }
+ }
+ String c_ou3 = getConfig(CONFIG_OU3);
+ if (c_ou3 == null || c_ou3.equals("")) {
+ v.addElement(VAL_OU3);
+ } else {
+ if (c_ou3.equals("true")) {
+ v.addElement(VAL_OU3);
+ }
+ }
+ String c_ou2 = getConfig(CONFIG_OU2);
+ if (c_ou2 == null || c_ou2.equals("")) {
+ v.addElement(VAL_OU2);
+ } else {
+ if (c_ou2.equals("true")) {
+ v.addElement(VAL_OU2);
+ }
+ }
+ String c_ou1 = getConfig(CONFIG_OU1);
+ if (c_ou1 == null || c_ou1.equals("")) {
+ v.addElement(VAL_OU1);
+ } else {
+ if (c_ou1.equals("true")) {
+ v.addElement(VAL_OU1);
+ }
+ }
+ String c_ou = getConfig(CONFIG_OU);
+ if (c_ou == null || c_ou.equals("")) {
+ v.addElement(VAL_OU);
+ } else {
+ if (c_ou.equals("true")) {
+ v.addElement(VAL_OU);
+ }
+ }
+ String c_o = getConfig(CONFIG_O);
+ if (c_o == null || c_o.equals("")) {
+ v.addElement(VAL_O);
+ } else {
+ if (c_o.equals("true")) {
+ v.addElement(VAL_O);
+ }
+ }
+ String c_c = getConfig(CONFIG_C);
+ if (c_c == null || c_c.equals("")) {
+ v.addElement(VAL_C);
+ } else {
+ if (c_c.equals("true")) {
+ v.addElement(VAL_C);
+ }
+ }
+ return v.elements();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+ String subjectName = "";
+
+ String uid = ctx.get(VAL_UID);
+
+ if (uid != null && !uid.equals("")) {
+ subjectName += "UID=" + uid;
+ }
+ String email = ctx.get(VAL_EMAIL);
+
+ if (email != null && !email.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "E=" + email;
+ }
+ String cn = ctx.get(VAL_CN);
+
+ if (cn != null && !cn.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "CN=" + cn;
+ }
+ String ou3 = ctx.get(VAL_OU3);
+ if (ou3 != null && !ou3.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "OU=" + ou3;
+ }
+ String ou2 = ctx.get(VAL_OU2);
+ if (ou2 != null && !ou2.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "OU=" + ou2;
+ }
+ String ou1 = ctx.get(VAL_OU1);
+ if (ou1 != null && !ou1.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "OU=" + ou1;
+ }
+ String ou = ctx.get(VAL_OU);
+ if (ou != null && !ou.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "OU=" + ou;
+ }
+ String o = ctx.get(VAL_O);
+
+ if (o != null && !o.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "O=" + o;
+ }
+ String c = ctx.get(VAL_C);
+
+ if (c != null && !c.equals("")) {
+ if (!subjectName.equals("")) {
+ subjectName += ",";
+ }
+ subjectName += "C=" + c;
+ }
+ if (subjectName.equals("")) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ }
+ X500Name name = null;
+
+ try {
+ name = new X500Name(subjectName);
+ } catch (Exception e) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_INVALID_SUBJECT_NAME", subjectName));
+ }
+ parseSubjectName(name, info, request);
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_UID)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_UID"));
+ } else if (name.equals(CONFIG_EMAIL)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_UID"));
+ } else if (name.equals(CONFIG_CN)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_CN"));
+ } else if (name.equals(CONFIG_OU3)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU"));
+ } else if (name.equals(CONFIG_OU2)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU"));
+ } else if (name.equals(CONFIG_OU1)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU"));
+ } else if (name.equals(CONFIG_OU)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU"));
+ } else if (name.equals(CONFIG_O)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_O"));
+ } else if (name.equals(CONFIG_C)) {
+ return new Descriptor(IDescriptor.BOOLEAN, null,
+ "true",
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_C"));
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_UID)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_UID"));
+ } else if (name.equals(VAL_EMAIL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_EMAIL"));
+ } else if (name.equals(VAL_CN)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_CN"));
+ } else if (name.equals(VAL_OU3)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU") + " 3");
+ } else if (name.equals(VAL_OU2)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU") + " 2");
+ } else if (name.equals(VAL_OU1)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU") + " 1");
+ } else if (name.equals(VAL_OU)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_OU"));
+ } else if (name.equals(VAL_O)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_O"));
+ } else if (name.equals(VAL_C)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SN_C"));
+ }
+ return null;
+ }
+
+ protected void parseSubjectName(X500Name subj, X509CertInfo info, IRequest req)
+ throws EProfileException {
+ try {
+ req.setExtData(EnrollProfile.REQUEST_SUBJECT_NAME,
+ new CertificateSubjectName(subj));
+ } catch (Exception e) {
+ CMS.debug("SubjectNameInput: parseSubject Name " +
+ e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java b/pki/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java
new file mode 100644
index 000000000..eac2ffc69
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java
@@ -0,0 +1,107 @@
+// --- 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 submitter information
+ * input that collects certificate requestor's
+ * information such as name, email and phone.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubmitterInfoInput extends EnrollInput implements IProfileInput {
+
+ public static final String NAME = "requestor_name";
+ public static final String EMAIL = "requestor_email";
+ public static final String PHONE = "requestor_phone";
+
+ public SubmitterInfoInput() {
+ addValueName(NAME);
+ addValueName(EMAIL);
+ addValueName(PHONE);
+ }
+
+ /**
+ * 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_SUBMITTER_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SUBMITTER_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(NAME)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REQUESTOR_NAME"));
+ } else if (name.equals(EMAIL)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REQUESTOR_EMAIL"));
+ } else if (name.equals(PHONE)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_REQUESTOR_PHONE"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java b/pki/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java
new file mode 100644
index 000000000..20b8c571c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java
@@ -0,0 +1,160 @@
+// --- 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.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 com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the certificate request input from TPS.
+ * This input populates 2 main fields to the enrollment "page":
+ * 1/ token cuid, 2/ publickey
+ * <p>
+ *
+ * This input usually is used by an enrollment profile for
+ * certificate requests coming from TPS.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsHKeyCertReqInput extends EnrollInput implements IProfileInput {
+ public static final String VAL_TOKEN_CUID = "tokencuid";
+ public static final String VAL_PUBLIC_KEY = "publickey";
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public nsHKeyCertReqInput() {
+ addValueName(VAL_TOKEN_CUID);
+ addValueName(VAL_PUBLIC_KEY);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_TEXT");
+ }
+
+ /*
+ * Pretty print token cuid
+ */
+ public String toPrettyPrint(String cuid)
+ {
+ if (cuid == null)
+ return null;
+
+ if (cuid.length() != 20)
+ return null;
+
+ StringBuffer sb = new StringBuffer();
+ for (int i=0; i < cuid.length(); i++) {
+ if (i == 4 || i == 8 || i == 12 || i == 16) {
+ sb.append("-");
+ }
+ sb.append(cuid.charAt(i));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String tcuid = ctx.get(VAL_TOKEN_CUID);
+ // pretty print tcuid
+ String prettyPrintCuid = toPrettyPrint(tcuid);
+ if (prettyPrintCuid == null) {
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_TOKENKEY_NO_TOKENCUID",
+ ""));
+ }
+
+ request.setExtData("pretty_print_tokencuid", prettyPrintCuid);
+
+ String pk = ctx.get(VAL_PUBLIC_KEY);
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ if (tcuid == null) {
+ CMS.debug("nsHKeyCertReqInput: populate - tokencuid not found " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_TOKENKEY_NO_TOKENCUID",
+ ""));
+ }
+ if (pk == null) {
+ CMS.debug("nsHKeyCertReqInput: populate - public key not found " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_TOKENKEY_NO_PUBLIC_KEY",
+ ""));
+ }
+
+ mEnrollProfile.fillNSHKEY(getLocale(request), tcuid, pk, info, request);
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_TOKEN_CUID)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_TOKEN_CUID"));
+ } else if (name.equals(VAL_PUBLIC_KEY)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_PK"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java b/pki/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java
new file mode 100644
index 000000000..367c20646
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java
@@ -0,0 +1,138 @@
+// --- 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.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+
+
+/**
+ * This class implements the certificate request input from TPS.
+ * This input populates 2 main fields to the enrollment "page":
+ * 1/ id, 2/ publickey
+ * <p>
+ *
+ * This input usually is used by an enrollment profile for
+ * certificate requests coming from TPS.
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsNKeyCertReqInput extends EnrollInput implements IProfileInput {
+ public static final String VAL_SN = "screenname";
+ public static final String VAL_PUBLIC_KEY = "publickey";
+
+ public EnrollProfile mEnrollProfile = null;
+
+ public nsNKeyCertReqInput() {
+ addValueName(VAL_SN);
+ addValueName(VAL_PUBLIC_KEY);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ String sn = ctx.get(VAL_SN);
+ String pk = ctx.get(VAL_PUBLIC_KEY);
+ X509CertInfo info =
+ request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
+
+ if (sn == null) {
+ CMS.debug("nsNKeyCertReqInput: populate - id not found " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_TOKENKEY_NO_ID",
+ ""));
+ }
+ if (pk == null) {
+ CMS.debug("nsNKeyCertReqInput: populate - public key not found " +
+ "");
+ throw new EProfileException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_TOKENKEY_NO_PUBLIC_KEY",
+ ""));
+ }
+
+ mEnrollProfile.fillNSNKEY(getLocale(request), sn, pk, info, request);
+ request.setExtData(EnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_SN)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_UID"));
+ } else if (name.equals(VAL_PUBLIC_KEY)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_INPUT_TOKENKEY_CERT_REQ_PK"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java b/pki/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java
new file mode 100644
index 000000000..0ed01cb38
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java
@@ -0,0 +1,157 @@
+// --- 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.output;
+
+
+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 com.netscape.certsrv.ca.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmmf.*;
+import org.mozilla.jss.pkix.primitive.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the output plugin that outputs
+ * CMMF response for the issued certificate.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMMFOutput extends EnrollOutput implements IProfileOutput {
+
+ public static final String VAL_PRETTY_CERT = "pretty_cert";
+ public static final String VAL_CMMF_RESPONSE = "cmmf_response";
+
+ public CMMFOutput() {
+ addValueName(VAL_PRETTY_CERT);
+ addValueName(VAL_CMMF_RESPONSE);
+ }
+
+ /**
+ * 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_OUTPUT_CERT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_CERT_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(VAL_PRETTY_CERT)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_CERT_PP"));
+ } else if (name.equals(VAL_CMMF_RESPONSE)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_CMMF_B64"));
+ }
+ return null;
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ if (name.equals(VAL_PRETTY_CERT)) {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ ICertPrettyPrint prettyCert = CMS.getCertPrettyPrint(cert);
+
+ return prettyCert.toString(locale);
+ } else if (name.equals(VAL_CMMF_RESPONSE)) {
+ try {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+
+ byte[][] caPubs = new byte[cacerts.length][];
+
+ for (int j = 0; j < cacerts.length; j++) {
+ caPubs[j] = ((X509CertImpl) cacerts[j]).getEncoded();
+ }
+
+ CertRepContent certRepContent = null;
+ certRepContent = new CertRepContent(caPubs);
+
+ PKIStatusInfo status = new PKIStatusInfo(PKIStatusInfo.granted);
+ CertifiedKeyPair certifiedKP =
+ new CertifiedKeyPair(new CertOrEncCert(cert.getEncoded()));
+ CertResponse resp =
+ new CertResponse(new INTEGER(request.getRequestId().toString()),
+ status, certifiedKP);
+ certRepContent.addCertResponse(resp);
+
+ ByteArrayOutputStream certRepOut = new ByteArrayOutputStream();
+ certRepContent.encode(certRepOut);
+ byte[] certRepBytes = certRepOut.toByteArray();
+
+ return CMS.BtoA(certRepBytes);
+ } catch (Exception e) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/output/CertOutput.java b/pki/base/common/src/com/netscape/cms/profile/output/CertOutput.java
new file mode 100644
index 000000000..516560c0d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/output/CertOutput.java
@@ -0,0 +1,121 @@
+// --- 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.output;
+
+
+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 pretty print certificate output
+ * that displays the issued certificate in a pretty print format.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertOutput extends EnrollOutput implements IProfileOutput {
+ public static final String VAL_PRETTY_CERT = "pretty_cert";
+ public static final String VAL_B64_CERT = "b64_cert";
+
+ public CertOutput() {
+ addValueName(VAL_PRETTY_CERT);
+ addValueName(VAL_B64_CERT);
+ }
+
+ /**
+ * 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_OUTPUT_CERT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_CERT_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(VAL_PRETTY_CERT)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_CERT_PP"));
+ } else if (name.equals(VAL_B64_CERT)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_CERT_B64"));
+ }
+ return null;
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ if (name.equals(VAL_PRETTY_CERT)) {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+ ICertPrettyPrint prettyCert = CMS.getCertPrettyPrint(cert);
+
+ return prettyCert.toString(locale);
+ } else if (name.equals(VAL_B64_CERT)) {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+ return CMS.getEncodedCert(cert);
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java b/pki/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java
new file mode 100644
index 000000000..213d7a834
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java
@@ -0,0 +1,130 @@
+// --- 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.output;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+
+
+/**
+ * This class implements the basic enrollment output.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollOutput implements IProfileOutput {
+ private IConfigStore mConfig = null;
+ private Vector mValueNames = new Vector();
+ protected Vector mConfigNames = new Vector();
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void addValueName(String name) {
+ mValueNames.addElement(name);
+ }
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * @param ctx profile context
+ * @param request request
+ * @exception EProfileException failed to populate
+ */
+ public abstract void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException;
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ *
+ * @param locale user locale
+ * @param name property name
+ * @return property descriptor
+ */
+ public abstract IDescriptor getValueDescriptor(Locale locale, String name);
+
+
+ /**
+ * Retrieves the localizable name of this policy.
+ *
+ * @param locale user locale
+ * @return output policy name
+ */
+ public abstract String getName(Locale locale);
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale user locale
+ * @return output policy description
+ */
+ public abstract String getText(Locale locale);
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ return mValueNames.elements();
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ return request.getExtDataInString(name);
+ }
+
+ /**
+ * Sets the value of the given value parameter by name.
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value) throws EPropertyException {
+ request.setExtData(name, value);
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ }
+
+ public String getConfig(String name) {
+ return null;
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java b/pki/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java
new file mode 100644
index 000000000..e6a9a9082
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java
@@ -0,0 +1,157 @@
+// --- 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.output;
+
+
+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 com.netscape.certsrv.ca.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmmf.*;
+import org.mozilla.jss.pkix.primitive.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the output plugin that outputs
+ * PKCS7 for the issued certificate.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PKCS7Output extends EnrollOutput implements IProfileOutput {
+
+ public static final String VAL_PRETTY_CERT = "pretty_cert";
+ public static final String VAL_PKCS7 = "pkcs7";
+
+ public PKCS7Output() {
+ addValueName(VAL_PRETTY_CERT);
+ addValueName(VAL_PKCS7);
+ }
+
+ /**
+ * 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_OUTPUT_CERT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_CERT_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(VAL_PRETTY_CERT)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_CERT_PP"));
+ } else if (name.equals(VAL_PKCS7)) {
+ return new Descriptor(IDescriptor.PRETTY_PRINT, null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_PKCS7_B64"));
+ }
+ return null;
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ if (name.equals(VAL_PRETTY_CERT)) {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+ ICertPrettyPrint prettyCert = CMS.getCertPrettyPrint(cert);
+
+ return prettyCert.toString(locale);
+ } else if (name.equals(VAL_PKCS7)) {
+
+ try {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) cacerts[n];
+ }
+
+ userChain[0] = cert;
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+ String p7Str = CMS.BtoA(p7Bytes);
+
+ return p7Str;
+ } catch (Exception e) {
+ return "";
+ }
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java b/pki/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java
new file mode 100644
index 000000000..4e3720880
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java
@@ -0,0 +1,118 @@
+// --- 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.output;
+
+
+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 com.netscape.certsrv.ca.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.cmmf.*;
+import org.mozilla.jss.pkix.primitive.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the output plugin that outputs
+ * DER for the issued certificate for token keys
+ *
+ * @version $Revision$, $Date$
+ */
+public class nsNKeyOutput extends EnrollOutput implements IProfileOutput {
+
+ public static final String VAL_DER = "der";
+
+ public nsNKeyOutput() {
+ addValueName(VAL_DER);
+ }
+
+ /**
+ * 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_OUTPUT_CERT_TOKENKEY_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_CERT_TOKENKEY_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(VAL_DER)) {
+ return new Descriptor("der_b64", null,
+ null,
+ CMS.getUserMessage(locale,
+ "CMS_PROFILE_OUTPUT_DER_B64"));
+ }
+ return null;
+ }
+
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EProfileException {
+ if (name.equals(VAL_DER)) {
+
+ try {
+ X509CertImpl cert = request.getExtDataInCert(
+ EnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+ return CMS.BtoA(cert.getEncoded());
+ } catch (Exception e) {
+ return "";
+ }
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java b/pki/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java
new file mode 100644
index 000000000..1445d285c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java
@@ -0,0 +1,179 @@
+// --- 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.updater;
+
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cms.profile.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import java.util.*;
+
+/**
+ * This updater class will create the new user to the subsystem group and
+ * then add the subsystem certificate to the user.
+ *
+ * @version $Revision$, $Date$
+ */
+public class SubsystemGroupUpdater implements IProfileUpdater {
+
+ public IProfile mProfile = null;
+ public EnrollProfile mEnrollProfile = null;
+ public IConfigStore mConfig = null;
+ public ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ public Vector mConfigNames = new Vector();
+ public Vector mValueNames = new Vector();
+
+ public SubsystemGroupUpdater() {
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ mProfile = profile;
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (mConfig.getSubStore("params") == null) {
+ //
+ } else {
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public String getConfig(String name) {
+ try {
+ if (mConfig == null) {
+ return null;
+ }
+ if (mConfig.getSubStore("params") != null) {
+ return mConfig.getSubStore("params").getString(name);
+ }
+ } catch (EBaseException e) {
+ }
+ return "";
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void update(IRequest req, RequestStatus status)
+ throws EProfileException {
+
+ CMS.debug("SubsystemGroupUpdater update starts");
+ if (status != req.getRequestStatus()) {
+ return;
+ }
+
+ X509CertImpl cert = req.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return;
+
+ IConfigStore mainConfig = CMS.getConfigStore();
+
+ int num=0;
+ try {
+ num = mainConfig.getInteger("subsystem.count", 0);
+ } catch (Exception e) {}
+
+ IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+
+ String requestor_name = "subsystem";
+ try {
+ requestor_name = req.getExtDataInString("requestor_name");
+ } catch (Exception e1) {
+ // ignore
+ }
+
+ // i.e. tps-1.2.3.4-4
+ String id = requestor_name;
+
+ num++;
+ mainConfig.putInteger("subsystem.count", num);
+
+ try {
+ mainConfig.commit(false);
+ } catch (Exception e) {
+ }
+
+ IUser user = null;
+ CMS.debug("SubsystemGroupUpdater adduser");
+ try {
+ user = system.createUser(id);
+ user.setFullName(id);
+ user.setEmail("");
+ user.setPassword("");
+ user.setUserType("agentType");
+ user.setState("1");
+ user.setPhone("");
+ X509CertImpl[] certs = new X509CertImpl[1];
+ certs[0] = cert;
+ user.setX509Certificates(certs);
+ system.addUser(user);
+ CMS.debug("SubsystemGroupUpdater update: successfully add the user");
+ system.addUserCert(user);
+ CMS.debug("SubsystemGroupUpdater update: successfully add the user certificate");
+ } catch (LDAPException e) {
+ CMS.debug("UpdateSubsystemGroup: update " + e.toString());
+ if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+ throw new EProfileException(e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug("UpdateSubsystemGroup: update addUser " + e.toString());
+ throw new EProfileException(e.toString());
+ }
+
+ IGroup group = null;
+ String groupName = "Subsystem Group";
+
+ try {
+ group = system.getGroupFromName(groupName);
+ if (!group.isMember(id)) {
+ group.addMemberName(id);
+ system.modifyGroup(group);
+ CMS.debug("UpdateSubsystemGroup: update: successfully added the user to the group.");
+ }
+ } catch (Exception e) {
+ CMS.debug("UpdateSubsystemGroup update: modifyGroup " + e.toString());
+ }
+ }
+
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_UPDATER_SUBSYSTEM_NAME");
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_UPDATER_SUBSYSTEM_TEXT");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java b/pki/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java
new file mode 100644
index 000000000..334f0c98f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java
@@ -0,0 +1,592 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.publish.mappers;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+/* cert server imports */
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+/* LDAP imports */
+import netscape.ldap.*;
+
+/* security imports */
+import netscape.security.util.*;
+import netscape.security.x509.*;
+
+/* java sdk imports */
+import java.io.*;
+import java.security.*;
+import java.util.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * avaPattern is a string representing an ldap
+ * attribute formulated from the certificate
+ * subject name, extension or request attributes.
+ * <p>
+ *
+ * The syntax is
+ * <pre>
+ * avaPattern := constant-value |
+ * "$subj" "." attrName [ "." attrNumber ] |
+ * "$req" "." [ prefix .] attrName [ "." attrNumber ] |
+ * "$ext" "." extName [ "." nameType ] [ "." attrNumber ]
+ * </pre>
+ * <pre>
+ * Example: <i>$ext.SubjectAlternativeName.RFC822Name.1</i>
+ * cert subjectAltName is rfc822Name: jjames@mcom.com
+ * <p>
+ * The ldap attribute formulated will be : <br>
+ * jjames@mcom.com
+ * <p>
+ * The first rfc822name value in the subjAltName extension. <br>
+ * <p>
+ * </pre>
+ * If a request attribute or subject DN component does not exist,
+ * the attribute is skipped.
+ *
+ * @version $Revision$, $Date$
+ */
+class AVAPattern {
+ ////////////////
+ // parameters //
+ ////////////////
+
+ /* the value type of the dn component */
+ public static final String TYPE_REQ = "$req";
+ public static final String TYPE_SUBJ = "$subj";
+ public static final String TYPE_EXT = "$ext";
+ public static final String TYPE_CONSTANT = "constant";
+
+ public static final String[] GENERAL_NAME_TYPE = { "ANY",
+ "RFC822Name",
+ "DNSName",
+ "X400Name",
+ "DIRECTORYName",
+ "EDIName",
+ "URIName",
+ "IPAddress",
+ "OIDName"};
+
+ private static final char[] endChars = new char[] { '+', ',' };
+
+ private static final LdapV3DNStrConverter mLdapDNStrConverter =
+ new LdapV3DNStrConverter();
+
+ /* the list of request attributes needed by this AVA */
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attributes needed by this AVA*/
+ protected String[] mCertAttrs = null;
+
+ /* value type */
+ protected String mType = null;
+
+ /* value - could be name of a request attribute or
+ * cert subject attribute or extension name.
+ */
+ protected String mValue = null;
+
+ /* value type - general name type of an
+ * extension attribute if any.
+ */
+ protected String mGNType = null;
+
+ /* prefix - prefix of a request attribute if any. */
+ protected String mPrefix = null;
+
+ /* nth value of the ldap or dn attribute */
+ protected int mElement = 0;
+
+ protected String mTestDN = null;
+
+ /////////////
+ // methods //
+ /////////////
+
+ public AVAPattern(String component)
+ throws ELdapException {
+ if (component == null || component.length() == 0) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", component));
+ }
+
+ parse(new PushbackReader(new StringReader(component)));
+ }
+
+ public AVAPattern(PushbackReader in)
+ throws ELdapException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws ELdapException {
+ int c;
+
+ // skip spaces
+ //System.out.println("============ AVAPattern Begin ===========");
+ //System.out.println("skip spaces");
+
+ try {
+ while ((c = in.read()) == ' ' || c == '\t') {//System.out.println("spaces read "+(char)c);
+ ;
+ }
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+ }
+
+ if (c == -1) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+ }
+
+ if (c == '$') {
+ // check for $subj $ext or $req
+ try {
+ c = in.read();
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ if (c == -1) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $subj $ext or $req in ava pattern"));
+ }
+
+ if (c == 'r') {
+ try {
+ if (in.read() != 'e' ||
+ in.read() != 'q' ||
+ in.read() != '.') {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $req in ava pattern"));
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mType = TYPE_REQ;
+ //System.out.println("---- mtype $req");
+ } else if (c == 's') {
+ try {
+ if (in.read() != 'u' ||
+ in.read() != 'b' ||
+ in.read() != 'j' ||
+ in.read() != '.') {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $subj in ava pattern"));
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mType = TYPE_SUBJ;
+ //System.out.println("----- mtype $subj");
+ } else if (c == 'e') {
+ try {
+ if (in.read() != 'x' ||
+ in.read() != 't' ||
+ in.read() != '.') {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $ext in ava pattern"));
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mType = TYPE_EXT;
+ //System.out.println("----- mtype $ext");
+ } else {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "unknown keyword. expecting $subj $ext or $req."));
+ }
+
+ // get request attribute or
+ // cert subject or
+ // extension attribute
+
+ StringBuffer valueBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1 && c != '.' && c != '+') {
+ //System.out.println("mValue read "+(char)c);
+ valueBuf.append((char) c);
+ }
+
+ if (c == '+' || c == ',') { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mValue = valueBuf.toString().trim();
+ if (mValue.length() == 0) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "$subj $ext or $req attribute name expected"));
+ }
+ //System.out.println("----- mValue "+mValue);
+
+ // get nth dn xxx not nth request attribute .
+ if (c == '.') {
+ StringBuffer attrNumberBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '.'
+ && c != '+') {
+ //System.out.println("mElement read "+(char)c);
+ attrNumberBuf.append((char) c);
+ }
+
+ if (c == ',' || c == '+') { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ String attrNumber = attrNumberBuf.toString().trim();
+
+ if (attrNumber.length() == 0) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "nth element $req $ext or $subj expected"));
+ }
+
+ try {
+ mElement = Integer.parseInt(attrNumber) - 1;
+ } catch (NumberFormatException e) {
+
+ if (TYPE_REQ.equals(mType)) {
+ mPrefix = mValue;
+ mValue = attrNumber;
+ } else if (TYPE_EXT.equals(mType)) {
+ mGNType = attrNumber;
+ } else {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "Invalid format in nth element " +
+ "$req $ext or $subj"));
+ }
+
+ // get nth request attribute .
+ if (c == '.') {
+ StringBuffer attrNumberBuf1 = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1 && c != '+') {
+ //System.out.println("mElement read "+
+ // (char)c);
+ attrNumberBuf1.append((char) c);
+ }
+
+ if (c != -1) { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException ex) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", ex.toString()));
+ }
+
+ String attrNumber1 =
+ attrNumberBuf1.toString().trim();
+
+ if (attrNumber1.length() == 0) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "nth element $req or $ext expected"));
+ }
+
+ try {
+ mElement = Integer.parseInt(attrNumber1) - 1;
+ } catch (NumberFormatException ex) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "Invalid format in nth element " +
+ "$req or $ext."));
+ }
+ }
+ }
+ }
+ //System.out.println("----- mElement "+mElement);
+ } else {
+ // value is constant. treat as regular ava.
+ mType = TYPE_CONSTANT;
+
+ // parse ava value.
+ StringBuffer valueBuf = new StringBuffer();
+
+ valueBuf.append((char) c);
+
+ // read forward to get attribute value
+ try {
+ while ((c = in.read()) != ',' && c != -1) {
+ valueBuf.append((char) c);
+ }
+
+ if (c == '+' || c == ',') { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mValue = valueBuf.toString().trim();
+
+ /* try {
+ * AVA ava = mLdapDNStrConverter.parseAVA(
+ * valueBuf.toString());
+ * mValue = ava.toLdapDNString();
+ * //System.out.println("----- mValue "+mValue);
+ * } catch (IOException e) {
+ * throw new ECompSyntaxErr(e.toString());
+ * }
+ */
+ }
+ }
+
+ public String formAVA(IRequest req,
+ X500Name subject,
+ CertificateExtensions extensions)
+ throws ELdapException {
+ if (TYPE_CONSTANT.equals(mType)) {
+ return mValue;
+ }
+
+ if (TYPE_SUBJ.equals(mType)) {
+ String dn = subject.toString();
+
+ if (mTestDN != null) {
+ dn = mTestDN;
+ }
+
+ //System.out.println("AVAPattern Using dn "+mTestDN);
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+
+ String value = null;
+
+ int nFound = -1;
+
+ for (int i = 0; i < rdns.length; i++) {
+ String[] avas = explodeRDN(rdns[i]);
+
+ for (int j = 0; j < avas.length; j++) {
+ String[] exploded = explodeAVA(avas[j]);
+
+ if (exploded[0].equalsIgnoreCase(mValue) &&
+ ++nFound == mElement) {
+ value = exploded[1];
+ break;
+ }
+ }
+ }
+
+ if (value == null) {
+ return null;
+ }
+
+ return value;
+ }
+
+ if (TYPE_EXT.equals(mType)) {
+
+ if (extensions != null) {
+
+ for (int i = 0; i < extensions.size(); i++) {
+ Extension ext = (Extension)
+ extensions.elementAt(i);
+
+ String extName =
+ OIDMap.getName(ext.getExtensionId());
+
+ int index = extName.lastIndexOf(".");
+
+ if (index != -1) {
+ extName = extName.substring(index + 1);
+ }
+
+ if (extName.equals(mValue)) {
+ // Check the extensions one by one.
+ // For now, just give subjectAltName
+ // as an example.
+ if (mValue.equalsIgnoreCase(
+ SubjectAlternativeNameExtension.NAME)) {
+ try {
+ GeneralNames subjectNames = (GeneralNames)
+ ((SubjectAlternativeNameExtension)
+ ext).get(
+ SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ if (subjectNames.size() == 0) {
+ break;
+ }
+
+ int j = 0;
+
+ for (Enumeration n =
+ subjectNames.elements();
+ n.hasMoreElements();) {
+
+ GeneralName gn = (GeneralName)
+ n.nextElement();
+
+ String gname = gn.toString();
+
+ index = gname.indexOf(":");
+
+ if (index == -1) {
+ break;
+ }
+
+ String gType =
+ gname.substring(0, index);
+
+ if (mGNType != null) {
+ if (mGNType.equalsIgnoreCase(gType)) {
+ if (mElement == j) {
+ gname =
+ gname.substring(index + 2);
+ return gname;
+ } else {
+ j++;
+ }
+ }
+ } else {
+ if (mElement == j) {
+ gname =
+ gname.substring(index + 2);
+ return gname;
+ }
+ j++;
+ }
+ }
+ } catch (IOException e) {
+ CMS.debug(
+ "AVAPattern: Publishing attr not formed " +
+ "from extension " +
+ "-- no attr : " +
+ mValue);
+ }
+ }
+ }
+ }
+ }
+
+ CMS.debug(
+ "AVAPattern: Publishing:attr not formed " +
+ "from extension " +
+ "-- no attr : " +
+ mValue);
+
+ return null;
+ }
+
+ if (TYPE_REQ.equals(mType)) {
+ // mPrefix and mValue are looked up case-insensitive
+ String reqAttr = req.getExtDataInString(mPrefix, mValue);
+ if (reqAttr == null) {
+ throw new
+ ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_REQUEST", mValue, ""));
+ }
+
+ return reqAttr;
+ }
+
+ return null;
+ }
+
+ public String getReqAttr() {
+ if (TYPE_REQ.equals(mType)) {
+ return mValue;
+ } else {
+ return null;
+ }
+ }
+
+ public String getCertAttr() {
+ if (TYPE_SUBJ.equals(mType)) {
+ return mValue;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Explode RDN into AVAs.
+ * Does not handle escaped '+'
+ * Java ldap library does not yet support multiple avas per rdn.
+ * If RDN is malformed returns empty array.
+ */
+ public static String[] explodeRDN(String rdn) {
+ int plus = rdn.indexOf('+');
+
+ if (plus == -1) {
+ return new String[] { rdn };
+ }
+
+ Vector avas = new Vector();
+
+ StringTokenizer token = new StringTokenizer(rdn, "+");
+
+ while (token.hasMoreTokens()) {
+ avas.addElement(token.nextToken());
+ }
+
+ String[] theAvas = new String[avas.size()];
+
+ avas.copyInto(theAvas);
+
+ return theAvas;
+ }
+
+ /**
+ * Explode AVA into name and value.
+ * Does not handle escaped '='
+ * If AVA is malformed empty array is returned.
+ */
+ public static String[] explodeAVA(String ava) {
+ int equals = ava.indexOf('=');
+
+ if (equals == -1) {
+ return null;
+ }
+
+ return new String[] { ava.substring(0, equals).trim(),
+ ava.substring(equals + 1).trim() };
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
new file mode 100644
index 000000000..6bf4ca8d5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
@@ -0,0 +1,366 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a request to an entry in the LDAP server.
+ * Takes a dnPattern to form the baseDN from the request attributes
+ * and certificate subject name.Do a base search for the entry
+ * in the directory to publish the cert or crl.
+ * The restriction of this mapper is that the ldap dn components must
+ * be part of certificate subject name or request attributes or constant.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
+ protected static final String PROP_DNPATTERN = "dnPattern";
+ protected static final String PROP_CREATECA = "createCAEntry";
+ protected String mDnPattern = null;
+ protected boolean mCreateCAEntry = true;
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+
+ /* the subject DN pattern */
+ protected MapDNPattern mPattern = null;
+
+ /* the list of request attriubutes to retrieve*/
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attriubutes to retrieve*/
+ protected String[] mCertAttrs = null;
+
+ /* default dn pattern if left blank or not set in the config */
+ public static final String DEFAULT_DNPATTERN =
+ "UID=$req.HTTP_PARAMS.UID, OU=people, O=$subj.o, C=$subj.c";
+
+ /**
+ * Constructor.
+ *
+ * @param dnPattern The base DN.
+ */
+ public LdapCaSimpleMap(String dnPattern) {
+ try {
+ init(dnPattern);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ }
+
+ /**
+ * constructor if initializing from config store.
+ */
+ public LdapCaSimpleMap() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ "dnPattern;string;Describes how to form the Ldap Subject name in" +
+ " the directory. Example 1: 'uid=CertMgr, o=Fedora'. Example 2:" +
+ " 'uid=$req.HTTP_PARAMS.uid, E=$ext.SubjectAlternativeName.RFC822Name, ou=$subj.ou'. " +
+ "$req means: take the attribute from the request. " +
+ "$subj means: take the attribute from the certificate subject name. " +
+ "$ext means: take the attribute from the certificate extension",
+ "createCAEntry;boolean;If checked, CA entry will be created automatically",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-ldappublish-mapper-casimplemapper",
+ IExtendedPluginInfo.HELP_TEXT + ";Describes how to form the LDAP DN of the entry to publish to"
+ };
+
+ return params;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * for initializing from config store.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ String dnPattern = mConfig.getString(PROP_DNPATTERN);
+
+ mCreateCAEntry = mConfig.getBoolean(PROP_CREATECA, true);
+ init(dnPattern);
+ }
+
+ /**
+ * common initialization routine.
+ */
+ protected void init(String dnPattern)
+ throws EBaseException {
+ if (mInited)
+ return;
+
+ mDnPattern = dnPattern;
+ if (mDnPattern == null || mDnPattern.length() == 0)
+ mDnPattern = DEFAULT_DNPATTERN;
+ try {
+ mPattern = new MapDNPattern(mDnPattern);
+ String[] mReqAttrs = mPattern.getReqAttrs();
+ String[] mCertAttrs = mPattern.getCertAttrs();
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_PATTERN_INIT", dnPattern, e.toString()));
+ throw new EBaseException("falied to init with pattern " +
+ dnPattern + " " + e);
+ }
+
+ mInited = true;
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN pattern to form a DN for a LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occured.
+ */
+ public String map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ return map(conn, null, obj);
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN pattern to form a DN for a LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param req the request to map.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occured.
+ */
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+ String dn = null;
+
+ try {
+ dn = formDN(req, obj);
+ if (dn == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_NOT_FORMED"));
+ String s1 = "";
+
+ if (req != null)
+ s1 = req.getRequestId().toString();
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_DN_MATCH", s1));
+ }
+ int scope = LDAPv2.SCOPE_BASE;
+ String filter = "(objectclass=*)";
+
+ // search for entry
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "searching for dn: " + dn + " filter:"
+ + filter + " scope: base");
+
+ LDAPSearchResults results =
+ conn.search(dn, scope, filter, attrs, false);
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY", dn,
+ ((req == null) ? "" : req.getRequestId().toString())));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_MORE_THAN_ONE_ENTRY",
+ ((req == null) ? "" : req.getRequestId().toString())));
+ }
+ if (entry != null)
+ return entry.getDN();
+ else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_ENTRY_NOT_FOUND", dn,
+ ((req == null) ? "" : req.getRequestId().toString())));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND",
+ "null entry"));
+ }
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT && mCreateCAEntry) {
+ try {
+ createCAEntry(conn, dn);
+ log(ILogger.LL_INFO, "CA Entry " + dn + " Created");
+ return dn;
+ } catch (LDAPException e1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", dn, e1.toString()));
+ if (e1.getLDAPResultCode() == LDAPException.CONSTRAINT_VIOLATION) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CA_ENTRY_NOT_CREATED"));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CA_ENTRY_NOT_CREATED1"));
+ }
+ throw new
+ ELdapException(CMS.getUserMessage("CMS_LDAP_CREATE_CA_FAILED", dn));
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", dn, e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_EXCEPTION_CAUGHT", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ private void createCAEntry(LDAPConnection conn, String dn)
+ throws LDAPException {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ // OID 2.5.6.16
+ String caOc[] = new String[] {"top",
+ "person",
+ "organizationalPerson",
+ "inetOrgPerson"};
+
+ String oOc[] = {"top",
+ "organization"};
+ String oiOc[] = {"top",
+ "organizationalunit"};
+
+ DN dnobj = new DN(dn);
+ String attrval[] = dnobj.explodeDN(true);
+
+ attrs.add(new LDAPAttribute("cn", attrval[0]));
+ attrs.add(new LDAPAttribute("sn", attrval[0]));
+ attrs.add(new LDAPAttribute("objectclass", caOc));
+ LDAPEntry entry = new LDAPEntry(dn, attrs);
+
+ conn.add(entry);
+ }
+
+ /**
+ * form a dn from component in the request and cert subject name
+ * @param req The request
+ * @param obj The certificate or crl
+ */
+ private String formDN(IRequest req, Object obj) throws EBaseException {
+ X500Name subjectDN = null;
+ CertificateExtensions certExt = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+
+ subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+
+ CMS.debug("LdapCaSimpleMap: cert subject dn:" + subjectDN.toString());
+ X509CertInfo info = (X509CertInfo)
+ ((X509CertImpl) cert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ certExt = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ } catch (java.security.cert.CertificateParsingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (java.security.cert.CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (ClassCastException e) {
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ subjectDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapCaSimpleMap: crl issuer dn: " +
+ subjectDN.toString());
+ }catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_OBJ_NOT_SUPPORTED",
+ ((req == null) ? "" : req.getRequestId().toString())));
+ return null;
+ }
+ }
+ try {
+ String dn = mPattern.formDN(req, subjectDN, certExt);
+
+ return dn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_FORM_DN",
+ ((req == null) ? "" : req.getRequestId().toString()), e.toString()));
+ throw new EBaseException("falied to form dn for request: " +
+ ((req == null) ? "" : req.getRequestId().toString()) + " " + e);
+ }
+ }
+
+ public String getImplName() {
+ return "LdapCaSimpleMap";
+ }
+
+ public String getDescription() {
+ return "LdapCaSimpleMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_DNPATTERN + "=");
+ v.addElement(PROP_CREATECA + "=true");
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ try {
+ if (mDnPattern == null) {
+ v.addElement(PROP_DNPATTERN + "=");
+ }else {
+ v.addElement(PROP_DNPATTERN + "=" +
+ mConfig.getString(PROP_DNPATTERN));
+ }
+ v.addElement(PROP_CREATECA + "=" + mConfig.getBoolean(PROP_CREATECA, true));
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCaSimpleMapper: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java
new file mode 100644
index 000000000..7a0bc4130
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java
@@ -0,0 +1,179 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a X509 certificate to a LDAP entry using AVAs in the certificate's
+ * subject name to form the ldap search dn and filter.
+ * Takes a optional root search dn.
+ * The DN comps are used to form a LDAP entry to begin a subtree search.
+ * The filter comps are used to form a search filter for the subtree.
+ * If none of the DN comps matched, baseDN is used for the subtree.
+ * If the baseDN is null and none of the DN comps matched, it is an error.
+ * If none of the DN comps and filter comps matched, it is an error.
+ * If just the filter comps is null, a base search is performed.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCertCompsMap
+ extends LdapDNCompsMap implements ILdapMapper {
+ ILogger mLogger = CMS.getLogger();
+
+ public LdapCertCompsMap() {
+ // need to support baseDN, dnComps, and filterComps
+ // via configuration
+ }
+
+ /**
+ * Constructor.
+ *
+ * The DN comps are used to form a LDAP entry to begin a subtree search.
+ * The filter comps are used to form a search filter for the subtree.
+ * If none of the DN comps matched, baseDN is used for the subtree.
+ * If the baseDN is null and none of the DN comps matched, it is an error.
+ * If none of the DN comps and filter comps matched, it is an error.
+ * If just the filter comps is null, a base search is performed.
+ *
+ * @param baseDN The base DN.
+ * @param dnComps Components to form the LDAP base dn for search.
+ * @param filterComps Components to form the LDAP search filter.
+ */
+ public LdapCertCompsMap(String baseDN, ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ init(baseDN, dnComps, filterComps);
+ }
+
+ public String getImplName() {
+ return "LdapCertCompsMap";
+ }
+
+ public String getDescription() {
+ return "LdapCertCompsMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = super.getDefaultParams();
+
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = super.getInstanceParams();
+
+ return v;
+ }
+
+ /**
+ * constructor using non-standard certificate attribute.
+ */
+ public LdapCertCompsMap(String certAttr, String baseDN,
+ ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ super(certAttr, baseDN, dnComps, filterComps);
+ }
+
+ protected void init(String baseDN, ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ super.init(baseDN, dnComps, filterComps);
+ }
+
+ /**
+ * Maps a certificate to LDAP entry.
+ * Uses DN components and filter components to form a DN and
+ * filter for a LDAP search.
+ * If the formed DN is null the baseDN will be used.
+ * If the formed DN is null and baseDN is null an error is thrown.
+ * If the filter is null a base search is performed.
+ * If both are null an error is thrown.
+ *
+ * @param conn - the LDAP connection.
+ * @param obj - the X509Certificate.
+ */
+ public String
+ map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+ String result = null;
+ // form dn and filter for search.
+ X500Name subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+
+ CMS.debug("LdapCertCompsMap: " + subjectDN.toString());
+
+ byte[] certbytes = cert.getEncoded();
+
+ result = super.map(conn, subjectDN, certbytes);
+ return result;
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_DECODE_CERT", e.toString()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (ClassCastException e) {
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+ String result = null;
+ X500Name issuerDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapCertCompsMap: " + issuerDN.toString());
+
+ byte[] crlbytes = crl.getEncoded();
+
+ result = super.map(conn, issuerDN, crlbytes);
+ return result;
+ } catch (CRLException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_DECODE_CRL", ex.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CRL_FAILED", ex.toString()));
+ } catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_NOT_SUPPORTED_OBJECT"));
+ return null;
+ }
+ }
+ }
+
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return map(conn, obj);
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCertCompsMap: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java
new file mode 100644
index 000000000..dde5950bc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java
@@ -0,0 +1,193 @@
+// --- 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.publish.mappers;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a X509 certificate to a LDAP entry by using the subject name
+ * of the certificate as the LDAP entry DN.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCertExactMap implements ILdapMapper, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+ protected IConfigStore mConfig = null;
+ boolean mInited = false;
+
+ /**
+ * constructs a certificate subject name mapper with search base.
+ */
+ public LdapCertExactMap() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited == true)
+ return;
+ mConfig = config;
+ mInited = true;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-mapper-certexactmapper",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Literally uses the subject name of the certificate as the DN to publish to"
+ };
+
+ return params;
+ }
+
+ public String getImplName() {
+ return "LdapCertExactMap";
+ }
+
+ public String getDescription() {
+ return "LdapCertExactMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ /**
+ * Finds the entry for the certificate by looking for the cert
+ * subject name in the subject name attribute.
+ *
+ * @param conn - the LDAP connection.
+ * @param obj - the X509Certificate.
+ */
+ public String
+ map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+
+ X500Name subjectDN = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+
+ subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+
+ CMS.debug("LdapCertExactMap: cert subject dn:" + subjectDN.toString());
+ } catch (ClassCastException e) {
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ subjectDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapCertExactMap: crl issuer dn: " +
+ subjectDN.toString());
+ }catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_NOT_SUPPORTED_OBJECT"));
+ return null;
+ }
+ }
+ try {
+ boolean hasCert = false;
+ boolean hasSubjectName = false;
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "Searching for " + subjectDN.toString());
+
+ LDAPSearchResults results =
+ conn.search(subjectDN.toString(), LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", attrs, false);
+
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY", "", subjectDN.toString()));
+ }
+ if (entry != null) {
+ log(ILogger.LL_INFO, "entry found");
+ return entry.getDN();
+ }
+ return null;
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ /*
+ catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_GET_SUBJECT", e.toString()));
+ throw new ELdapException(
+ LdapResources.GET_CERT_SUBJECT_DN_FAILED, e);
+ }
+ catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_DECODE_CERT", e.toString()));
+ throw new ELdapException(
+ LdapResources.GET_DER_ENCODED_CERT_FAILED, e);
+ }
+ */
+ }
+
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return map(conn, obj);
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCertExactMap: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java
new file mode 100644
index 000000000..6fcebad01
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java
@@ -0,0 +1,337 @@
+// --- 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.publish.mappers;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a X509 certificate to a LDAP entry by finding an LDAP entry
+ * which has an attribute whose contents are equal to the cert subject name.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCertSubjMap implements ILdapMapper, IExtendedPluginInfo {
+ public static final String LDAP_CERTSUBJNAME_ATTR = "certSubjectName";
+ protected String mSearchBase = null;
+ protected String mCertSubjNameAttr = LDAP_CERTSUBJNAME_ATTR;
+ protected boolean mUseAllEntries = false;
+
+ private ILogger mLogger = CMS.getLogger();
+ protected IConfigStore mConfig = null;
+ boolean mInited = false;
+
+ public LdapCertSubjMap() {
+ // need to setup the mSearchBase via configuration
+ }
+
+ /**
+ * constructs a certificate subject name mapper with search base.
+ * @param searchBase the dn to start searching for the certificate
+ * subject name.
+ */
+ public LdapCertSubjMap(String searchBase) {
+ if (searchBase == null)
+ throw new IllegalArgumentException(
+ "a null argument to constructor " + this.getClass().getName());
+ mSearchBase = searchBase;
+ mInited = true;
+ }
+
+ /**
+ * Constructor using non-ES cert map attribute name.
+ *
+ * @param searchBase entry to start search.
+ * @param certSubjNameAttr attribute for certificate subject names.
+ * @param certAttr attribute to find certificate.
+ */
+ public LdapCertSubjMap(String searchBase,
+ String certSubjNameAttr, String certAttr) {
+ if (searchBase == null ||
+ certSubjNameAttr == null || certAttr == null)
+ throw new IllegalArgumentException(
+ "a null argument to constructor " + this.getClass().getName());
+ mCertSubjNameAttr = certSubjNameAttr;
+ mSearchBase = searchBase;
+ mInited = true;
+ }
+
+ public LdapCertSubjMap(String searchBase,
+ String certSubjNameAttr, String certAttr, boolean useAllEntries) {
+ if (searchBase == null ||
+ certSubjNameAttr == null || certAttr == null)
+ throw new IllegalArgumentException(
+ "a null argument to constructor " + this.getClass().getName());
+ mCertSubjNameAttr = certSubjNameAttr;
+ mSearchBase = searchBase;
+ mUseAllEntries = useAllEntries;
+ mInited = true;
+ }
+
+ public String getImplName() {
+ return "LdapCertSubjMap";
+ }
+
+ public String getDescription() {
+ return "LdapCertSubjMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("certSubjNameAttr=" + mCertSubjNameAttr);
+ v.addElement("searchBase=");
+ v.addElement("useAllEntries=" + mUseAllEntries);
+ return v;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "certSubjNameAttr;string;Name of Ldap attribute containing cert subject name",
+ "searchBase;string;Base DN to search from",
+ "useAllEntries;boolean;Use all entries for publishing",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-mapper-certsubjmapper",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin assumes you want to publish to an LDAP entry which has " +
+ "an attribute whose contents are equal to the cert subject name"
+ };
+
+ return params;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ if (mCertSubjNameAttr == null) {
+ v.addElement("certSubjNameAttr=");
+ } else {
+ v.addElement("certSubjNameAttr=" + mCertSubjNameAttr);
+ }
+ if (mSearchBase == null) {
+ v.addElement("searchBase=");
+ } else {
+ v.addElement("searchBase=" + mSearchBase);
+ }
+ v.addElement("useAllEntries=" + mUseAllEntries);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited == true)
+ return;
+ mConfig = config;
+ mCertSubjNameAttr = config.getString("certSubjNameAttr",
+ LDAP_CERTSUBJNAME_ATTR);
+ mSearchBase = config.getString("searchBase");
+ mUseAllEntries = config.getBoolean("useAllEntries", false);
+ mInited = true;
+ }
+
+ /**
+ * Finds the entry for the certificate by looking for the cert
+ * subject name in the subject name attribute.
+ *
+ * @param conn - the LDAP connection.
+ * @param obj - the X509Certificate.
+ */
+ public String
+ map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+ X500Name subjectDN = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+
+ subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+
+ CMS.debug("LdapCertSubjMap: cert subject dn:" + subjectDN.toString());
+ } catch (ClassCastException e) {
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ subjectDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapCertSubjMap: crl issuer dn: " +
+ subjectDN.toString());
+ }catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_NOT_SUPPORTED_OBJECT"));
+ return null;
+ }
+ }
+ try {
+ boolean hasCert = false;
+ boolean hasSubjectName = false;
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "search " + mSearchBase +
+ " (" + mCertSubjNameAttr + "=" + subjectDN + ") " + mCertSubjNameAttr);
+
+ LDAPSearchResults results =
+ conn.search(mSearchBase, LDAPv2.SCOPE_SUB,
+ "(" + mCertSubjNameAttr + "=" + subjectDN + ")", attrs, false);
+
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY", "", subjectDN.toString()));
+ }
+ if (entry != null) {
+ log(ILogger.LL_INFO, "entry found");
+ return entry.getDN();
+ }
+ return null;
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", "LDAPException", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ /*
+ catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_GET_SUBJECT", e.toString()));
+ throw new ELdapException(
+ LdapResources.GET_CERT_SUBJECT_DN_FAILED, e);
+ }
+ catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_DECODE_CERT", e.toString()));
+ throw new ELdapException(
+ LdapResources.GET_DER_ENCODED_CERT_FAILED, e);
+ }
+ */
+ }
+
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return map(conn, obj);
+ }
+
+ public Vector mapAll(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ Vector v = new Vector();
+
+ if (conn == null)
+ return null;
+ X500Name subjectDN = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+ subjectDN = (X500Name) ((X509Certificate) cert).getSubjectDN();
+ CMS.debug("LdapCertSubjMap: cert subject dn:" + subjectDN.toString());
+ } catch (ClassCastException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_NOT_SUPPORTED_OBJECT"));
+ return v;
+ }
+ try {
+ boolean hasCert = false;
+ boolean hasSubjectName = false;
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "search " + mSearchBase +
+ " (" + mCertSubjNameAttr + "=" + subjectDN + ") " + mCertSubjNameAttr);
+
+ LDAPSearchResults results =
+ conn.search(mSearchBase, LDAPv2.SCOPE_SUB,
+ "(" + mCertSubjNameAttr + "=" + subjectDN + ")", attrs, false);
+
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = results.next();
+ String dn = entry.getDN();
+ v.addElement(dn);
+ CMS.debug("LdapCertSubjMap: dn="+dn);
+ }
+ CMS.debug("LdapCertSubjMap: Number of entries: " + v.size());
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", "LDAPException", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ return v;
+ }
+
+ public Vector mapAll(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return mapAll(conn, obj);
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCertSubjMap: " + msg);
+ }
+
+ /**
+ * return search base
+ */
+ public String getSearchBase() {
+ return mSearchBase;
+ }
+
+ /**
+ * return certificate subject attribute
+ */
+ public String getCertSubjNameAttr() {
+ return mCertSubjNameAttr;
+ }
+
+ public boolean useAllEntries() {
+ return mUseAllEntries;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java
new file mode 100644
index 000000000..3a55b4ebe
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java
@@ -0,0 +1,159 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Default crl mapper.
+ * maps the crl to a ldap entry by using components in the issuer name
+ * to find the CA's entry.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCrlIssuerCompsMap
+ extends LdapDNCompsMap implements ILdapMapper {
+ ILogger mLogger = CMS.getLogger();
+
+ public LdapCrlIssuerCompsMap() {
+ // need to support baseDN, dnComps, and filterComps
+ // via configuration
+ }
+
+ /**
+ * Constructor.
+ *
+ * The DN comps are used to form a LDAP entry to begin a subtree search.
+ * The filter comps are used to form a search filter for the subtree.
+ * If none of the DN comps matched, baseDN is used for the subtree.
+ * If the baseDN is null and none of the DN comps matched, it is an error.
+ * If none of the DN comps and filter comps matched, it is an error.
+ * If just the filter comps is null, a base search is performed.
+ *
+ * @param baseDN The base DN.
+ * @param dnComps Components to form the LDAP base dn for search.
+ * @param filterComps Components to form the LDAP search filter.
+ */
+ public LdapCrlIssuerCompsMap(String baseDN, ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ init(baseDN, dnComps, filterComps);
+ }
+
+ /**
+ * constructor using non-standard certificate attribute.
+ */
+ public LdapCrlIssuerCompsMap(String crlAttr, String baseDN,
+ ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ super(crlAttr, baseDN, dnComps, filterComps);
+ }
+
+ public String getImplName() {
+ return "LdapCrlIssuerCompsMap";
+ }
+
+ public String getDescription() {
+ return "LdapCrlIssuerCompsMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = super.getDefaultParams();
+
+ //v.addElement("crlAttr=" + LdapCrlPublisher.LDAP_CRL_ATTR);
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = super.getInstanceParams();
+
+ return v;
+ }
+
+ protected void init(String baseDN, ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ //mLdapAttr = LdapCrlPublisher.LDAP_CRL_ATTR;
+ super.init(baseDN, dnComps, filterComps);
+ }
+
+ /**
+ * Maps a crl to LDAP entry.
+ * Uses issuer DN components and filter components to form a DN and
+ * filter for a LDAP search.
+ * If the formed DN is null the baseDN will be used.
+ * If the formed DN is null and baseDN is null an error is thrown.
+ * If the filter is null a base search is performed.
+ * If both are null an error is thrown.
+ *
+ * @param conn - the LDAP connection.
+ * @param obj - the X509Certificate.
+ * @return the result. LdapCertMapResult is also used for CRL.
+ */
+ public String
+ map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ try {
+ String result = null;
+ X500Name issuerDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapCrlIssuerCompsMap: " + issuerDN.toString());
+
+ byte[] crlbytes = crl.getEncoded();
+
+ result = super.map(conn, issuerDN, crlbytes);
+ return result;
+ } catch (CRLException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_DECODE_CRL", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CRL_FAILED", e.toString()));
+ }
+ }
+
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return map(conn, obj);
+ }
+
+ /**
+ * overrides super's log().
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCrlCompsMap: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java
new file mode 100644
index 000000000..49fce4994
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java
@@ -0,0 +1,439 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a Subject name to an entry in the LDAP server.
+ * subject name to form the ldap search dn and filter.
+ * Takes a optional root search dn.
+ * The DN comps are used to form a LDAP entry to begin a subtree search.
+ * The filter comps are used to form a search filter for the subtree.
+ * If none of the DN comps matched, baseDN is used for the subtree.
+ * If the baseDN is null and none of the DN comps matched, it is an error.
+ * If none of the DN comps and filter comps matched, it is an error.
+ * If just the filter comps is null, a base search is performed.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapDNCompsMap
+ implements ILdapPlugin, IExtendedPluginInfo {
+ //protected String mLdapAttr = null;
+ protected String mBaseDN = null;
+ protected ObjectIdentifier[] mDnComps = null;
+ protected ObjectIdentifier[] mFilterComps = null;
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+
+ /**
+ * Constructor.
+ *
+ * The DN comps are used to form a LDAP entry to begin a subtree search.
+ * The filter comps are used to form a search filter for the subtree.
+ * If none of the DN comps matched, baseDN is used for the subtree.
+ * If the baseDN is null and none of the DN comps matched, it is an error.
+ * If none of the DN comps and filter comps matched, it is an error.
+ * If just the filter comps is null, a base search is performed.
+ *
+ * @param baseDN The base DN.
+ * @param dnComps Components to form the LDAP base dn for search.
+ * @param filterComps Components to form the LDAP search filter.
+ */
+ public LdapDNCompsMap(String ldapAttr, String baseDN,
+ ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ //mLdapAttr = ldapAttr;
+ init(baseDN, dnComps, filterComps);
+ }
+
+ /**
+ * constructor if initializing from config store.
+ */
+ public LdapDNCompsMap() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * for initializing from config store.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ String baseDN = mConfig.getString("baseDN");
+ ObjectIdentifier[] dnComps =
+ getCompsFromString(mConfig.getString("dnComps"));
+ ObjectIdentifier[] filterComps =
+ getCompsFromString(mConfig.getString("filterComps"));
+
+ init(baseDN, dnComps, filterComps);
+ }
+
+ public String getImplName() {
+ return "LdapDNCompsMap";
+ }
+
+ public String getDescription() {
+ return "LdapDNCompsMap";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] s = {
+ "baseDN;string;Base to search from. E.g ou=Engineering,o=Fedora",
+ "dnComps;string;Comma-separated list of attributes to put in the DN",
+ "filterComps;string;Comma-separated list of attributes to form the filter",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-mapper-dncompsmapper",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";More complex mapper. Used when there is not enough information " +
+ "in the cert request to form the complete LDAP DN. Using this " +
+ "plugin, you can specify additional LDAP filters to narrow down the " +
+ "search"
+ };
+
+ return s;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("baseDN=");
+ v.addElement("dnComps=");
+ v.addElement("filterComps=");
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ try {
+ if (mBaseDN == null) {
+ v.addElement("baseDN=");
+ } else {
+ v.addElement("baseDN=" + mConfig.getString("baseDN"));
+ }
+ if (mDnComps == null) {
+ v.addElement("dnComps=");
+ } else {
+ v.addElement("dnComps=" +
+ mConfig.getString("dnComps"));
+ }
+ if (mFilterComps == null) {
+ v.addElement("filterComps=");
+ } else {
+ v.addElement("filterComps=" +
+ mConfig.getString("filterComps"));
+ }
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ /**
+ * common initialization routine.
+ */
+ protected void init(String baseDN, ObjectIdentifier[] dnComps,
+ ObjectIdentifier[] filterComps) {
+ if (mInited)
+ return;
+
+ mBaseDN = baseDN;
+ if (dnComps != null)
+ mDnComps = (ObjectIdentifier[]) dnComps.clone();
+ if (filterComps != null)
+ mFilterComps = (ObjectIdentifier[]) filterComps.clone();
+
+ // log debug info.
+ for (int i = 0; i < mDnComps.length; i++) {
+ CMS.debug(
+ "LdapDNCompsMap: dnComp " + X500NameAttrMap.getDefault().getName(mDnComps[i]));
+ }
+ for (int i = 0; i < mFilterComps.length; i++) {
+ CMS.debug("LdapDNCompsMap: filterComp " +
+ X500NameAttrMap.getDefault().getName(mFilterComps[i]));
+ }
+ mInited = true;
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN components and filter components to form a DN and
+ * filter for a LDAP search.
+ * If the formed DN is null the baseDN will be used.
+ * If the formed DN is null and baseDN is null an error is thrown.
+ * If the filter is null a base search is performed.
+ * If both are null an error is thrown.
+ *
+ * @param conn the LDAP connection.
+ * @param x500name the dn to map.
+ * @param obj the object
+ * @exception ELdapException if any LDAP exceptions occured.
+ * @return the DN of the entry.
+ */
+ public String map(LDAPConnection conn, X500Name x500name,
+ byte[] obj)
+ throws ELdapException {
+ try {
+ if (conn == null)
+ return null;
+
+ CMS.debug("LdapDNCompsMap: " + x500name.toString());
+
+ String[] dnAndFilter = formDNandFilter(x500name);
+ String dn = dnAndFilter[0];
+ String filter = dnAndFilter[1];
+
+ if (dn == null) {
+ // #362332
+ // if (filter == null) {
+ // log(ILogger.LL_FAILURE, "No dn and filter formed");
+ // throw new ELdapException(
+ // LdapResources.NO_DN_AND_FILTER_COMPS,
+ // x500name.toString());
+ // }
+ if (mBaseDN == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_BASE"));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_DN_COMPS_AND_BASEDN",
+ x500name.toString()));
+ }
+ dn = mBaseDN;
+ }
+ int scope = LDAPv2.SCOPE_SUB;
+
+ if (filter == null) {
+ scope = LDAPv2.SCOPE_BASE;
+ filter = "(objectclass=*)";
+ }
+
+ // search for entry
+ String[] attrs;
+
+ attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "searching for " + dn + " " + filter + " " +
+ ((scope == LDAPv2.SCOPE_SUB) ? "sub" : "base"));
+
+ LDAPSearchResults results =
+ conn.search(dn, scope, filter, attrs, false);
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY", "", x500name.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_MORE_THAN_ONE_ENTRY",
+ x500name.toString()));
+ }
+ if (entry != null) {
+ return entry.getDN();
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_ENTRY_NOT_FOUND", "", x500name.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND",
+ "null entry"));
+ }
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", "LDAPException", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapDNCompsMap: " + msg);
+ }
+
+ /**
+ * form a dn and filter from component in the cert subject name
+ * @param subjName subject name
+ */
+ public String[] formDNandFilter(X500Name subjName)
+ throws ELdapException {
+ Vector dnRdns = new Vector();
+ SearchFilter filter = new SearchFilter();
+ X500NameAttrMap attrMap = X500NameAttrMap.getDefault();
+ String dnStr = null, filterStr = null;
+ ObjectIdentifier EOid = attrMap.getOid("E");
+ ObjectIdentifier mailOid = attrMap.getOid("MAIL");
+
+ try {
+ // get the base DN & filter.
+ for (Enumeration n = subjName.getRDNs(); n.hasMoreElements();) {
+ RDN rdn = (RDN) n.nextElement();
+ // NOTE assumes one AVA per RDN.
+ AVA ava = rdn.getAssertion()[0];
+ ObjectIdentifier oid = ava.getOid();
+
+ for (int i = 0; i < mDnComps.length; i++) {
+ if (mDnComps[i].equals(oid)) {
+ if (oid == EOid) {
+ DerValue val = ava.getValue();
+ AVA newAVA = new AVA(mailOid, val);
+ RDN newRDN = new RDN(new AVA[] { newAVA }
+ );
+
+ CMS.debug(
+ "LdapDNCompsMap: Converted " + rdn.toLdapDNString() + " to " +
+ newRDN.toLdapDNString() + " in DN");
+ rdn = newRDN;
+ }
+ dnRdns.addElement(rdn);
+ CMS.debug(
+ "LdapDNCompsMap: adding dn comp " + rdn.toLdapDNString());
+ break;
+ }
+ }
+ for (int i = 0; i < mFilterComps.length; i++) {
+ if (mFilterComps[i].equals(oid)) {
+ if (oid == EOid) {
+ DerValue val = ava.getValue();
+ AVA newAVA = new AVA(mailOid, val);
+
+ CMS.debug(
+ "LdapDNCompsMap: Converted " + ava.toLdapDNString() + " to " +
+ newAVA.toLdapDNString() + " in filter");
+ ava = newAVA;
+ }
+ filter.addElement(ava.toLdapDNString());
+ CMS.debug(
+ "LdapDNCompsMap: adding filter comp " + ava.toLdapDNString());
+ break;
+ }
+ }
+
+ // XXX should be an error when string is null?
+ // return to caller to decide.
+ if (dnRdns.size() != 0) {
+ dnStr = new X500Name(dnRdns).toLdapDNString();
+ }
+ if (filter.size() != 0) {
+ filterStr = filter.toFilterString();
+ }
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_FROM_SUBJ_TO_DN", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FORM_DN_COMPS_FAILED", e.toString()));
+ }
+
+ return new String[] { dnStr, filterStr };
+ }
+
+ public ObjectIdentifier[] getDnComps() {
+ return (ObjectIdentifier[]) mDnComps.clone();
+ }
+
+ public ObjectIdentifier[] getFilterComps() {
+ return (ObjectIdentifier[]) mFilterComps.clone();
+ }
+
+ /**
+ * class for forming search filters for ldap searching from
+ * name=value components. components are anded.
+ */
+ public static class SearchFilter extends Vector {
+ public String toFilterString() {
+ StringBuffer buf = new StringBuffer();
+
+ if (elementCount == 0) {
+ return null;
+ }
+ if (elementCount == 1) {
+ buf.append("(" + (String) elementData[0] + ")");
+ return buf.toString();
+ }
+ buf.append("(&");
+ for (int i = 0; i < elementCount; i++) {
+ buf.append("(" + (String) elementData[i] + ")");
+ }
+ buf.append(")");
+ return buf.toString();
+ }
+ }
+
+ /**
+ * useful routine for parsing components given as string to
+ * arrays of objectidentifiers.
+ * The string is expected to be comma separated AVA attribute names.
+ * For example, "uid,cn,o,ou". Attribute names are case insensitive.
+ * @param val the string specifying the comps
+ * @exception ELdapException if any error occurs.
+ */
+ public static ObjectIdentifier[] getCompsFromString(String val)
+ throws ELdapException {
+ StringTokenizer tokens;
+ ObjectIdentifier[] comps;
+ String attr;
+ ObjectIdentifier oid;
+
+ if (val == null || val.length() == 0)
+ return new ObjectIdentifier[0];
+
+ tokens = new StringTokenizer(val, ", \t\n\r");
+ comps = new ObjectIdentifier[tokens.countTokens()];
+ if (comps.length == 0) {
+ return new ObjectIdentifier[0];
+ }
+ int i = 0;
+
+ while (tokens.hasMoreTokens()) {
+ attr = tokens.nextToken().trim();
+ // mail -> E hack to look for E in subject names.
+ if (attr.equalsIgnoreCase("mail"))
+ attr = "E";
+ oid = X500NameAttrMap.getDefault().getOid(attr);
+ if (oid != null) {
+ comps[i++] = oid;
+ } else {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_UNKNOWN_ATTR_IN_DN_FILTER_COMPS", attr));
+ }
+ }
+ return comps;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java
new file mode 100644
index 000000000..ff445bb5e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java
@@ -0,0 +1,639 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.publish.mappers;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+/* cert server imports */
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+/* LDAP imports */
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/* security imports */
+import netscape.security.util.*;
+import netscape.security.x509.*;
+
+/* java sdk imports */
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.util.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * Maps a request to an entry in the LDAP server.
+ * Takes a dnPattern to form the baseDN from the
+ * request attributes and certificate subject name.
+ * Does a base search for the entry in the directory
+ * to publish the cert or crl. The restriction of
+ * this mapper is that the ldap dn components must
+ * be part of certificate subject name or request
+ * attributes or constant. The difference of this
+ * mapper and LdapSimpleMap is that if the ldap
+ * entry is not found, it has the option to create
+ * the ldap entry given the dn and attributes
+ * formulated.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapEnhancedMap
+ implements ILdapMapper, IExtendedPluginInfo {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ //////////////////////////////////////
+ // local LdapEnhancedMap parameters //
+ //////////////////////////////////////
+
+ private boolean mInited = false;
+
+ // the subject DN pattern
+ protected MapDNPattern mPattern = null;
+
+ // the list of request attriubutes to retrieve
+ protected String[] mReqAttrs = null;
+
+ // the list of cert attributes to retrieve
+ protected String[] mCertAttrs = null;
+
+ protected String[] mLdapValues = null;
+
+ ////////////////////////////
+ // ILdapMapper parameters //
+ ////////////////////////////
+
+ /* mapper plug-in fields */
+ protected static final String PROP_DNPATTERN = "dnPattern";
+ protected static final String PROP_CREATE = "createEntry";
+ // the object class of the entry to be created. xxxx not done yet
+ protected static final String PROP_OBJCLASS = "objectClass";
+ // req/cert/ext attribute --> directory attribute table
+ protected static final String PROP_ATTRNUM = "attrNum";
+ protected static final String PROP_ATTR_NAME = "attrName";
+ protected static final String PROP_ATTR_PATTERN = "attrPattern";
+
+ /* mapper plug-in fields initialization values */
+ private static final int DEFAULT_NUM_ATTRS = 1;
+
+ /* Holds mapper plug-in fields accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ private static Vector defaultParams = new Vector();
+
+ static {
+ defaultParams.addElement(PROP_DNPATTERN + "=");
+ defaultParams.addElement(PROP_CREATE + "=true");
+ defaultParams.addElement(PROP_ATTRNUM + "=" + DEFAULT_NUM_ATTRS);
+ for (int i = 0; i < DEFAULT_NUM_ATTRS; i++) {
+ defaultParams.addElement(PROP_ATTR_NAME + i + "=");
+ defaultParams.addElement(PROP_ATTR_PATTERN + i + "=");
+ }
+ }
+
+ /* mapper plug-in values */
+ protected String mDnPattern = null;
+ protected boolean mCreateEntry = true;
+ private int mNumAttrs = DEFAULT_NUM_ATTRS;
+ protected String[] mLdapNames = null;
+ protected String[] mLdapPatterns = null;
+
+ /* miscellaneous constants local to this mapper plug-in */
+ // default dn pattern if left blank or not set in the config
+ public static final String DEFAULT_DNPATTERN =
+ "UID=$req.HTTP_PARAMS.UID, " +
+ "OU=people, O=$subj.o, C=$subj.c";
+ private static final int MAX_ATTRS = 10;
+ protected static final int DEFAULT_ATTRNUM = 1;
+
+ /* miscellaneous variables local to this mapper plug-in */
+ protected IConfigStore mConfig = null;
+ protected AVAPattern[] mPatterns = null;
+
+ ////////////////////////////////////
+ // IExtendedPluginInfo parameters //
+ ////////////////////////////////////
+
+
+
+ ///////////////////////
+ // Logger parameters //
+ ///////////////////////
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public LdapEnhancedMap() {
+ }
+
+ ///////////////////////////////////
+ // local LdapEnhancedMap methods //
+ ///////////////////////////////////
+
+ /**
+ * common initialization routine.
+ */
+ protected void init(String dnPattern)
+ throws EBaseException {
+ if (mInited) {
+ return;
+ }
+
+ mDnPattern = dnPattern;
+ if (mDnPattern == null ||
+ mDnPattern.length() == 0) {
+ mDnPattern = DEFAULT_DNPATTERN;
+ }
+
+ try {
+ mPattern = new MapDNPattern(mDnPattern);
+ String[] mReqAttrs = mPattern.getReqAttrs();
+ String[] mCertAttrs = mPattern.getCertAttrs();
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_PATTERN_INIT",
+ dnPattern, e.toString()));
+ throw new EBaseException(
+ "falied to init with pattern " +
+ dnPattern + " " + e);
+ }
+
+ mInited = true;
+ }
+
+ /**
+ * form a dn from component in the request and cert subject name
+ * @param req The request
+ * @param obj The certificate or crl
+ */
+ private String formDN(IRequest req, Object obj)
+ throws EBaseException {
+ CertificateExtensions certExt = null;
+ X500Name subjectDN = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+
+ subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+ CMS.debug(
+ "LdapEnhancedMap: cert subject dn:" +
+ subjectDN.toString());
+
+ //certExt = (CertificateExtensions)
+ // ((X509CertImpl)cert).get(
+ // X509CertInfo.EXTENSIONS);
+ X509CertInfo info = (X509CertInfo)
+ ((X509CertImpl) cert).get(
+ X509CertImpl.NAME +
+ "." +
+ X509CertImpl.INFO);
+
+ certExt = (CertificateExtensions)
+ info.get(CertificateExtensions.NAME);
+ } catch (java.security.cert.CertificateParsingException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (java.security.cert.CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (ClassCastException e) {
+
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ subjectDN = (X500Name)
+ ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug(
+ "LdapEnhancedMap: crl issuer dn: " +
+
+ subjectDN.toString());
+ } catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_PUBLISH_OBJ_NOT_SUPPORTED",
+ ((req == null) ? ""
+ : req.getRequestId().toString())));
+ return null;
+ }
+ }
+
+ try {
+ mLdapValues = new String[mNumAttrs];
+
+ for (int i = 0; i < mNumAttrs; i++) {
+ if (mPatterns[i] != null) {
+ mLdapValues[i] = mPatterns[i].formAVA(
+ req,
+ subjectDN,
+ certExt);
+ }
+ }
+
+ String dn = mPattern.formDN(req, subjectDN, certExt);
+
+ return dn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_CANT_FORM_DN",
+ ((req == null) ? ""
+ : req.getRequestId().toString()), e.toString()));
+
+ throw new EBaseException(
+ "failed to form dn for request: " +
+ ((req == null) ? ""
+ : req.getRequestId().toString()) +
+ " " + e);
+ }
+ }
+
+ private void createEntry(LDAPConnection conn, String dn)
+ throws LDAPException {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ // OID 2.5.6.16
+ String caOc[] = { "top",
+ "person",
+ "organizationalPerson",
+ "inetOrgPerson" };
+
+ DN dnobj = new DN(dn);
+ String attrval[] = dnobj.explodeDN(true);
+
+ attrs.add(new LDAPAttribute("cn", attrval[0]));
+ attrs.add(new LDAPAttribute("sn", attrval[0]));
+ attrs.add(new LDAPAttribute("objectclass", caOc));
+
+ for (int i = 0; i < mNumAttrs; i++) {
+ if (mLdapNames[i] != null &&
+ !mLdapNames[i].trim().equals("") &&
+ mLdapValues[i] != null &&
+ !mLdapValues[i].trim().equals("")) {
+ attrs.add(new LDAPAttribute(mLdapNames[i],
+ mLdapValues[i]));
+ }
+ }
+
+ LDAPEntry entry = new LDAPEntry(dn, attrs);
+
+ conn.add(entry);
+ }
+
+ /////////////////////////
+ // ILdapMapper methods //
+ /////////////////////////
+
+ /**
+ * for initializing from config store.
+ *
+ * implementation for extended
+ * ILdapPlugin interface method
+ */
+ public void init(IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mDnPattern = mConfig.getString(PROP_DNPATTERN,
+ DEFAULT_DNPATTERN);
+
+ mCreateEntry = mConfig.getBoolean(PROP_CREATE,
+ true);
+
+ mNumAttrs = mConfig.getInteger(PROP_ATTRNUM,
+ 0);
+
+ mLdapNames = new String[mNumAttrs];
+
+ mLdapPatterns = new String[mNumAttrs];
+
+ mPatterns = new AVAPattern[mNumAttrs];
+ for (int i = 0; i < mNumAttrs; i++) {
+ mLdapNames[i] =
+ mConfig.getString(PROP_ATTR_NAME +
+ Integer.toString(i),
+ "");
+
+ mLdapPatterns[i] =
+ mConfig.getString(PROP_ATTR_PATTERN +
+ Integer.toString(i),
+ "");
+
+ if (mLdapPatterns[i] != null &&
+ !mLdapPatterns[i].trim().equals("")) {
+ mPatterns[i] = new AVAPattern(mLdapPatterns[i]);
+ }
+ }
+
+ init(mDnPattern);
+ }
+
+ /**
+ * implementation for extended
+ * ILdapPlugin interface method
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String getImplName() {
+ return "LdapEnhancedMap";
+ }
+
+ public String getDescription() {
+ return "LdapEnhancedMap";
+ }
+
+ public Vector getDefaultParams() {
+ return defaultParams;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ try {
+ if (mDnPattern == null) {
+ v.addElement(PROP_DNPATTERN + "=");
+ }else {
+ v.addElement(PROP_DNPATTERN + "=" +
+ mConfig.getString(PROP_DNPATTERN));
+ }
+
+ v.addElement(PROP_CREATE + "=" +
+ mConfig.getBoolean(PROP_CREATE,
+ true));
+
+ v.addElement(PROP_ATTRNUM + "=" +
+ mConfig.getInteger(PROP_ATTRNUM,
+ DEFAULT_NUM_ATTRS));
+
+ for (int i = 0; i < mNumAttrs; i++) {
+ if (mLdapNames[i] != null) {
+ v.addElement(PROP_ATTR_NAME + i +
+ "=" + mLdapNames[i]);
+ } else {
+ v.addElement(PROP_ATTR_NAME + i +
+ "=");
+ }
+
+ if (mLdapPatterns[i] != null) {
+ v.addElement(PROP_ATTR_PATTERN + i +
+ "=" + mLdapPatterns[i]);
+ } else {
+ v.addElement(PROP_ATTR_PATTERN + i +
+ "=");
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ return v;
+ }
+
+ /**
+ * Maps an X500 subject name to an LDAP entry.
+ * Uses DN pattern to form a DN for an LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occurred.
+ */
+ public String map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ return map(conn, null, obj);
+ }
+
+ /**
+ * Maps an X500 subject name to an LDAP entry.
+ * Uses DN pattern to form a DN for an LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param req the request to map.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occurred.
+ */
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ if (conn == null) {
+ return null;
+ }
+
+ String dn = null;
+
+ try {
+ dn = formDN(req, obj);
+ if (dn == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_NOT_FORMED"));
+
+ String s1 = "";
+
+ if (req != null)
+ s1 = req.getRequestId().toString();
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_DN_MATCH", s1));
+ }
+
+ int scope = LDAPv2.SCOPE_BASE;
+ String filter = "(objectclass=*)";
+
+ // search for entry
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO,
+ "searching for dn: " +
+ dn + " filter:" +
+ filter + " scope: base");
+
+ LDAPSearchResults results = conn.search(dn,
+ scope,
+ filter,
+ attrs,
+ false);
+
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY",
+ dn +
+ ((req == null) ? ""
+ : req.getRequestId().toString())));
+
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_MORE_THAN_ONE_ENTRY",
+ ((req == null) ? ""
+ : req.getRequestId().toString())));
+ }
+
+ if (entry != null) {
+ return entry.getDN();
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_ENTRY_NOT_FOUND",
+ dn +
+ ((req == null) ? ""
+ : req.getRequestId().toString())));
+
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND",
+ "null entry"));
+ }
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else if (e.getLDAPResultCode() ==
+ LDAPException.NO_SUCH_OBJECT && mCreateEntry) {
+
+ try {
+ createEntry(conn, dn);
+
+ log(ILogger.LL_INFO,
+ "Entry " +
+ dn +
+ " Created");
+
+ return dn;
+ } catch (LDAPException e1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION",
+ dn,
+ e.toString()));
+
+ log(ILogger.LL_FAILURE,
+ "Entry is not created. " +
+ "This may because there are " +
+ "entries in the directory " +
+ "hierachy not exit.");
+
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CREATE_ENTRY", dn));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION",
+ dn,
+ e.toString()));
+
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_EXCEPTION_CAUGHT",
+ e.toString()));
+
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ /////////////////////////////////
+ // IExtendedPluginInfo methods //
+ /////////////////////////////////
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_DNPATTERN +
+ ";string;Describes how to form the Ldap " +
+ "Subject name in the directory. " +
+ "Example 1: 'uid=CertMgr, o=Fedora'. " +
+ "Example 2: 'uid=$req.HTTP_PARAMS.uid, " +
+ "E=$ext.SubjectAlternativeName.RFC822Name, " +
+ "ou=$subj.ou'. " +
+ "$req means: take the attribute from the " +
+ "request. " +
+ "$subj means: take the attribute from the " +
+ "certificate subject name. " +
+ "$ext means: take the attribute from the " +
+ "certificate extension");
+ v.addElement(PROP_CREATE +
+ ";boolean;If checked, An entry will be " +
+ "created automatically");
+ v.addElement(PROP_ATTRNUM +
+ ";string;How many attributes to add.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-mapper-enhancedmapper");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Describes how to form the LDAP DN of the " +
+ "entry to publish to");
+
+ for (int i = 0; i < MAX_ATTRS; i++) {
+ v.addElement(PROP_ATTR_NAME +
+ Integer.toString(i) +
+ ";string;" +
+ "The name of LDAP attribute " +
+ "to be added. e.g. mail");
+ v.addElement(PROP_ATTR_PATTERN +
+ Integer.toString(i) +
+ ";string;" +
+ "How to create the LDAP attribute value. " +
+ "e.g. $req.HTTP_PARAMS.csrRequestorEmail, " +
+ "$subj.E or " +
+ "$ext.SubjectAlternativeName.RFC822Name");
+ }
+
+ String params[] =
+ com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+
+ return params;
+ }
+
+ ////////////////////
+ // Logger methods //
+ ////////////////////
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapEnhancedMapper: " + msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java
new file mode 100644
index 000000000..6e9e0e74a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java
@@ -0,0 +1,320 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Maps a request to an entry in the LDAP server.
+ * Takes a dnPattern to form the baseDN from the request attributes
+ * and certificate subject name.Do a base search for the entry
+ * in the directory to publish the cert or crl.
+ * The restriction of this mapper is that the ldap dn components must
+ * be part of certificate subject name or request attributes or constant.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapSimpleMap implements ILdapMapper, IExtendedPluginInfo {
+ protected static final String PROP_DNPATTERN = "dnPattern";
+ protected String mDnPattern = null;
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+
+ /* the subject DN pattern */
+ protected MapDNPattern mPattern = null;
+
+ /* the list of request attriubutes to retrieve*/
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attriubutes to retrieve*/
+ protected String[] mCertAttrs = null;
+
+ /* default dn pattern if left blank or not set in the config */
+ public static final String DEFAULT_DNPATTERN =
+ "UID=$req.HTTP_PARAMS.UID, OU=people, O=$subj.o, C=$subj.c";
+
+ /**
+ * Constructor.
+ *
+ * @param dnPattern The base DN.
+ */
+ public LdapSimpleMap(String dnPattern) {
+ try {
+ init(dnPattern);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+
+ }
+
+ /**
+ * constructor if initializing from config store.
+ */
+ public LdapSimpleMap() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ "dnPattern;string;Describes how to form the Ldap Subject name in" +
+ " the directory. Example 1: 'uid=CertMgr, o=Fedora'. Example 2:" +
+ " 'uid=$req.HTTP_PARAMS.uid, E=$ext.SubjectAlternativeName.RFC822Name, ou=$subj.ou'. " +
+ "$req means: take the attribute from the request. " +
+ "$subj means: take the attribute from the certificate subject name. " +
+ "$ext means: take the attribute from the certificate extension",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-ldappublish-mapper-simplemapper",
+ IExtendedPluginInfo.HELP_TEXT + ";Describes how to form the LDAP DN of the entry to publish to"
+ };
+
+ return params;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * for initializing from config store.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ String dnPattern = mConfig.getString(PROP_DNPATTERN);
+
+ init(dnPattern);
+ }
+
+ /**
+ * common initialization routine.
+ */
+ protected void init(String dnPattern)
+ throws EBaseException {
+ if (mInited)
+ return;
+
+ mDnPattern = dnPattern;
+ if (mDnPattern == null || mDnPattern.length() == 0)
+ mDnPattern = DEFAULT_DNPATTERN;
+ try {
+ mPattern = new MapDNPattern(mDnPattern);
+ String[] mReqAttrs = mPattern.getReqAttrs();
+ String[] mCertAttrs = mPattern.getCertAttrs();
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_PATTERN_INIT",
+ dnPattern, e.toString()));
+ throw new EBaseException("falied to init with pattern " +
+ dnPattern + " " + e);
+ }
+
+ mInited = true;
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN pattern to form a DN for a LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occured.
+ */
+ public String map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ return map(conn, null, obj);
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN pattern to form a DN for a LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param req the request to map.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occured.
+ */
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ if (conn == null)
+ return null;
+ String dn = null;
+
+ try {
+ dn = formDN(req, obj);
+ if (dn == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_NOT_FORMED"));
+ String s1 = "";
+
+ if (req != null)
+ s1 = req.getRequestId().toString();
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_DN_MATCH", s1));
+ }
+ int scope = LDAPv2.SCOPE_BASE;
+ String filter = "(objectclass=*)";
+
+ // search for entry
+ String[] attrs = new String[] { LDAPv3.NO_ATTRS };
+
+ log(ILogger.LL_INFO, "searching for dn: " + dn + " filter:"
+ + filter + " scope: base");
+
+ LDAPSearchResults results =
+ conn.search(dn, scope, filter, attrs, false);
+ LDAPEntry entry = results.next();
+
+ if (results.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_MORE_THAN_ONE_ENTRY", dn, ((req == null) ? "" : req.getRequestId().toString())));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_MORE_THAN_ONE_ENTRY",
+ ((req == null) ? "" : req.getRequestId().toString())));
+ }
+ if (entry != null)
+ return entry.getDN();
+ else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_ENTRY_NOT_FOUND", dn, ((req == null) ? "" : req.getRequestId().toString())));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND",
+ "null entry"));
+ }
+ } catch (ELdapException e) {
+ throw e;
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_DN_MAP_EXCEPTION", "", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_EXCEPTION_CAUGHT", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH_FOUND", e.toString()));
+ }
+ }
+
+ /**
+ * form a dn from component in the request and cert subject name
+ * @param req The request
+ * @param obj The certificate or crl
+ */
+ private String formDN(IRequest req, Object obj) throws
+ EBaseException, ELdapException {
+ X500Name subjectDN = null;
+ CertificateExtensions certExt = null;
+
+ try {
+ X509Certificate cert = (X509Certificate) obj;
+
+ subjectDN =
+ (X500Name) ((X509Certificate) cert).getSubjectDN();
+
+ CMS.debug("LdapSimpleMap: cert subject dn:" + subjectDN.toString());
+ //certExt = (CertificateExtensions)
+ // ((X509CertImpl)cert).get(X509CertInfo.EXTENSIONS);
+ X509CertInfo info = (X509CertInfo)
+ ((X509CertImpl) cert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ certExt = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ } catch (java.security.cert.CertificateParsingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (java.security.cert.CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_GET_EXT", e.toString()));
+ } catch (ClassCastException e) {
+ try {
+ X509CRLImpl crl = (X509CRLImpl) obj;
+
+ subjectDN =
+ (X500Name) ((X509CRLImpl) crl).getIssuerDN();
+
+ CMS.debug("LdapSimpleMap: crl issuer dn: " +
+ subjectDN.toString());
+ }catch (ClassCastException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_PUBLISH_OBJ_NOT_SUPPORTED",
+ ((req == null) ? "" : req.getRequestId().toString())));
+ return null;
+ }
+ }
+ try {
+ String dn = mPattern.formDN(req, subjectDN, certExt);
+
+ return dn;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_FORM_DN",
+ ((req == null) ? "" : req.getRequestId().toString()), e.toString()));
+ throw e;
+ }
+ }
+
+ public String getImplName() {
+ return "LdapSimpleMap";
+ }
+
+ public String getDescription() {
+ return "LdapSimpleMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_DNPATTERN + "=");
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ try {
+ if (mDnPattern == null) {
+ v.addElement(PROP_DNPATTERN + "=");
+ }else {
+ v.addElement(PROP_DNPATTERN + "=" +
+ mConfig.getString(PROP_DNPATTERN));
+ }
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapSimpleMapper: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java b/pki/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java
new file mode 100644
index 000000000..129c12659
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java
@@ -0,0 +1,634 @@
+// --- 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.publish.mappers;
+
+
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+import java.io.*;
+import java.security.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a ldap dn from
+ * request attributes and cert subject name.<p>
+ *
+ * dnpattern is a string representing a ldap dn pattern to formulate from
+ * the certificate subject name attributes and request attributes .
+ * If empty or not set, the certificate subject name
+ * will be used as the ldap dn. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$subj" "." attrName [ "." attrNumber ] |
+ * name "=" "$ext" "." extName [ "." nameType ] [ "." attrNumber ]
+ * name "=" "$req" "." attrName [ "." attrNumber ] |
+ * "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>cn=Certificate Manager,ou=people,o=mcom.com</i>
+ * cert subject name: dn: CN=Certificate Manager, OU=people, O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * CN=Certificate Manager, OU=people, O=mcom.com
+ * <p>
+ * note: Subordinate ca enrollment will use ca mapper. Use predicate
+ * to distinguish the ca itself and the subordinates.
+ *
+ * Example2: <i>UID=$req.HTTP_PARAMS.uid, OU=$subj.ou, OU=people, , O=mcom.com</i>
+ * cert subject name: dn: UID=jjames, OU=IS, OU=people, , O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * UID=jjames, OU=IS, OU=people, O=mcom.com
+ * <p>
+ * UID = the 'uid' attribute value in the request. <br>
+ * OU = the 'ou' value in the cert subject name. <br>
+ * O = the string mcom.com. <br>
+ * <p>
+ * Example3: <i>UID=$req.HTTP_PARAMS.uid, E=$ext.SubjectAlternativeName.RFC822Name.1, O=mcom.com</i>
+ * cert subject name: dn: UID=jjames, OU=IS, OU=people, O=mcom.com
+ * cert subjectAltName is rfc822Name: jjames@mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * UID=jjames, E=jjames@mcom.com, O=mcom.com
+ * <p>
+ * UID = the 'uid' attribute value in the request. <br>
+ * E = The first rfc822name value in the subjAltName extension. <br>
+ * O = the string mcom.com. <br>
+ * <p>
+ * </pre>
+ * If an request attribute or subject DN component does not exist,
+ * the attribute is skipped. There is potential risk that a wrong dn
+ * will be mapped into.
+ *
+ * @version $Revision$, $Date$
+ */
+class MapAVAPattern {
+
+ /* the value type of the dn component */
+ public static final String TYPE_REQ = "$req";
+ public static final String TYPE_SUBJ = "$subj";
+ public static final String TYPE_EXT = "$ext";
+ public static final String TYPE_RDN = "$rdn";
+ public static final String TYPE_CONSTANT = "constant";
+
+ public static final String[] GENERAL_NAME_TYPE = { "ANY",
+ "RFC822Name",
+ "DNSName",
+ "X400Name",
+ "DIRECTORYName",
+ "EDIName",
+ "URIName",
+ "IPAddress",
+ "OIDName"};
+ private static final char[] endChars = new char[] { '+', ',' };
+
+ private static final LdapV3DNStrConverter mLdapDNStrConverter =
+ new LdapV3DNStrConverter();
+
+ /* the list of request attributes needed by this AVA */
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attributes needed by this AVA*/
+ protected String[] mCertAttrs = null;
+
+ /* value type */
+ protected String mType = null;
+
+ /* the attribute in the AVA pair */
+ protected String mAttr = null;
+
+ /* value - could be name of a request attribute or
+ * cert subject dn attribute. */
+ protected String mValue = null;
+
+ /* value type - general name type of an extension attribute if any. */
+ protected String mGNType = null;
+
+ /* prefix - prefix of a request attribute if any. */
+ protected String mPrefix = null;
+
+ /* nth value of the ldap or dn attribute */
+ protected int mElement = 0;
+
+ protected String mTestDN = null;
+
+ public MapAVAPattern(String component)
+ throws ELdapException {
+ if (component == null || component.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", component));
+ parse(new PushbackReader(new StringReader(component)));
+ }
+
+ public MapAVAPattern(PushbackReader in)
+ throws ELdapException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws ELdapException {
+ int c;
+
+ // mark ava beginning.
+
+ // skip spaces
+ //System.out.println("============ AVAPattern Begin ===========");
+ //System.out.println("skip spaces");
+
+ try {
+ while ((c = in.read()) == ' ' || c == '\t') {//System.out.println("spaces read "+(char)c);
+ ;
+ }
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "All blank"));
+
+ // $rdn "." number syntax.
+
+ if (c == '$') {
+ //System.out.println("$rdn syntax");
+ mType = TYPE_RDN;
+ try {
+ if (in.read() != 'r' ||
+ in.read() != 'd' ||
+ in.read() != 'n' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $ syntax, expecting $rdn"));
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $ syntax, expecting $rdn"));
+ }
+
+ StringBuffer rdnNumberBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '+') {
+ //System.out.println("rdnNumber read "+(char)c);
+ rdnNumberBuf.append((char) c);
+ }
+ if (c != -1) // either ',' or '+'
+ in.unread(c);
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ String rdnNumber = rdnNumberBuf.toString().trim();
+
+ if (rdnNumber.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "$rdn number not set in ava pattern"));
+ try {
+ mElement = Integer.parseInt(rdnNumber) - 1;
+ } catch (NumberFormatException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Invalid $rdn number in ava pattern"));
+ }
+ return;
+ }
+
+ // name "=" ... syntax.
+
+ // read name
+ //System.out.println("reading name");
+
+ StringBuffer attrBuf = new StringBuffer();
+
+ try {
+ while (c != '=' && c != -1 && c != ',' && c != '+') {
+ attrBuf.append((char) c);
+ c = in.read();
+ //System.out.println("name read "+(char)c);
+ }
+ if (c == ',' || c == '+')
+ in.unread(c);
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ if (c != '=')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "Missing \"=\" in ava pattern"));
+
+ // read value
+ //System.out.println("reading value");
+
+ // skip spaces
+ //System.out.println("skip spaces for value");
+ try {
+ while ((c = in.read()) == ' ' || c == '\t') {//System.out.println("spaces2 read "+(char)c);
+ ;
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "no value after = in ava pattern"));
+
+ if (c == '$') {
+ // check for $subj $ext or $req
+ try {
+ c = in.read();
+ //System.out.println("check $dn or $attr read "+(char)c);
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ if (c == -1)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $subj or $req in ava pattern"));
+ if (c == 'r') {
+ try {
+ if (in.read() != 'e' ||
+ in.read() != 'q' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $req in ava pattern"));
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ mType = TYPE_REQ;
+ //System.out.println("---- mtype $req");
+ } else if (c == 's') {
+ try {
+ if (in.read() != 'u' ||
+ in.read() != 'b' ||
+ in.read() != 'j' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $subj in ava pattern"));
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ mType = TYPE_SUBJ;
+ //System.out.println("----- mtype $subj");
+ } else if (c == 'e') {
+ try {
+ if (in.read() != 'x' ||
+ in.read() != 't' ||
+ in.read() != '.')
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "expecting $ext in ava pattern"));
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ mType = TYPE_EXT;
+ //System.out.println("----- mtype $ext");
+ } else {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "unknown keyword. expecting $subj $ext or $req."));
+ }
+
+ // get request attr name of subject dn pattern from above.
+ String attrName = attrBuf.toString().trim();
+
+ //System.out.println("----- attrName "+attrName);
+ if (attrName.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", "attribute name expected"));
+ mAttr = attrName;
+
+ /*
+ try {
+ ObjectIdentifier attrOid =
+ mLdapDNStrConverter.parseAVAKeyword(attrName);
+ mAttr = mLdapDNStrConverter.encodeOID(attrOid);
+ //System.out.println("----- mAttr "+mAttr);
+ }
+ catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", e.toString()));
+ }
+ */
+
+ // get request attribute or cert subject dn attribute
+
+ StringBuffer valueBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1 && c != '.' && c != '+') {
+ //System.out.println("mValue read "+(char)c);
+ valueBuf.append((char) c);
+ }
+ if (c == '+' || c == ',') // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+
+ mValue = valueBuf.toString().trim();
+ if (mValue.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "$subj or $req attribute name expected"));
+ //System.out.println("----- mValue "+mValue);
+
+ // get nth dn xxx not nth request attribute .
+ if (c == '.') {
+ StringBuffer attrNumberBuf = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '.'
+ && c != '+') {
+ //System.out.println("mElement read "+(char)c);
+ attrNumberBuf.append((char) c);
+ }
+ if (c == ',' || c == '+') // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ String attrNumber = attrNumberBuf.toString().trim();
+
+ if (attrNumber.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "nth element $req $ext or $subj expected"));
+ try {
+ mElement = Integer.parseInt(attrNumber) - 1;
+ } catch (NumberFormatException e) {
+ if (TYPE_REQ.equals(mType)) {
+ mPrefix = mValue;
+ mValue = attrNumber;
+ } else if (TYPE_EXT.equals(mType)) {
+ mGNType = attrNumber;
+ } else
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "Invalid format in nth element $req $ext or $subj"));
+
+ // get nth request attribute .
+ if (c == '.') {
+ StringBuffer attrNumberBuf1 = new StringBuffer();
+
+ try {
+ while ((c = in.read()) != ',' && c != -1 && c != '+') {
+ //System.out.println("mElement read "+(char)c);
+ attrNumberBuf1.append((char) c);
+ }
+ if (c != -1) // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ } catch (IOException ex) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", ex.toString()));
+ }
+ String attrNumber1 = attrNumberBuf1.toString().trim();
+
+ if (attrNumber1.length() == 0)
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "nth element $req expected"));
+ try {
+ mElement = Integer.parseInt(attrNumber1) - 1;
+ } catch (NumberFormatException ex) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX",
+ "Invalid format in nth element $req."));
+
+ }
+ }
+ }
+ }
+ //System.out.println("----- mElement "+mElement);
+ } else {
+ // value is constant. treat as regular ava.
+ mType = TYPE_CONSTANT;
+ //System.out.println("----- mType constant");
+ // parse ava value.
+ StringBuffer valueBuf = new StringBuffer();
+
+ valueBuf.append((char) c);
+ // read forward to get attribute value
+ try {
+ while ((c = in.read()) != ',' &&
+ c != -1) {
+ valueBuf.append((char) c);
+ }
+ if (c == '+' || c == ',') { // either ',' or '+'
+ in.unread(c); // pushback last , or +
+ }
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ try {
+ AVA ava = mLdapDNStrConverter.parseAVA(attrBuf + "=" + valueBuf);
+
+ mValue = ava.toLdapDNString();
+ //System.out.println("----- mValue "+mValue);
+ } catch (IOException e) {
+ throw new ECompSyntaxErr(CMS.getUserMessage("CMS_AUTHENTICATION_COMPONENT_SYNTAX", e.toString()));
+ }
+ }
+ }
+
+ public String formAVA(IRequest req, X500Name subject, CertificateExtensions extensions)
+ throws ELdapException {
+ if (TYPE_CONSTANT.equals(mType))
+ return mValue;
+
+ if (TYPE_RDN.equals(mType)) {
+ String dn = subject.toString();
+
+ if (mTestDN != null)
+ dn = mTestDN;
+ //System.out.println("AVAPattern Using dn "+mTestDN);
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+
+ if (mElement >= rdns.length)
+ return null;
+ return rdns[mElement];
+ }
+
+ if (TYPE_SUBJ.equals(mType)) {
+ String dn = subject.toString();
+
+ if (mTestDN != null)
+ dn = mTestDN;
+ //System.out.println("AVAPattern Using dn "+mTestDN);
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+ String value = null;
+ int nFound = -1;
+
+ for (int i = 0; i < rdns.length; i++) {
+ String[] avas = explodeRDN(rdns[i]);
+
+ for (int j = 0; j < avas.length; j++) {
+ String[] exploded = explodeAVA(avas[j]);
+
+ if (exploded[0].equalsIgnoreCase(mValue) &&
+ ++nFound == mElement) {
+ value = exploded[1];
+ break;
+ }
+ }
+ }
+ if (value == null) {
+ CMS.debug(
+ "MapAVAPattern: attr " + mAttr +
+ " not formed from: cert subject " +
+ dn +
+ "-- no subject component : " + mValue);
+ return null;
+ }
+ return mAttr + "=" + value;
+ }
+
+ if (TYPE_EXT.equals(mType)) {
+ if (extensions != null) {
+ for (int i = 0; i < extensions.size(); i++) {
+ Extension ext = (Extension)
+ extensions.elementAt(i);
+ String extName = OIDMap.getName(ext.getExtensionId());
+ int index = extName.lastIndexOf(".");
+
+ if (index != -1)
+ extName = extName.substring(index + 1);
+ if (
+ extName.equals(mValue)) {
+ // Check the extensions one by one.
+ // For now, just give subjectAltName as an example.
+ if
+ (mValue.equalsIgnoreCase(SubjectAlternativeNameExtension.NAME)) {
+ try {
+ GeneralNames subjectNames = (GeneralNames)
+ ((SubjectAlternativeNameExtension) ext).get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ if (subjectNames.size() == 0)
+ break;
+ int j = 0;
+
+ for (Enumeration n = subjectNames.elements(); n.hasMoreElements();) {
+ GeneralName gn = (GeneralName) n.nextElement();
+ String gname = gn.toString();
+
+ index = gname.indexOf(":");
+ if (index == -1) break;
+ String gType = gname.substring(0, index);
+
+ if (mGNType != null) {
+ if (mGNType.equalsIgnoreCase(gType)) {
+ if (mElement == j) {
+ gname =
+ gname.substring(index + 2);
+ return mAttr + "=" + gname;
+ } else {
+ j++;
+ }
+ }
+ } else {
+ if (mElement == j) {
+ gname =
+ gname.substring(index + 2);
+ return mAttr + "=" + gname;
+ }
+ j++;
+ }
+ }
+ } catch (IOException e) {
+ CMS.debug(
+ "MapAVAPattern: Publishing attr not formed from extension." +
+ "-- no attr : " + mValue);
+ }
+ }
+ }
+ }
+ }
+ CMS.debug(
+ "MapAVAPattern: Publishing:attr not formed from extension " +
+ "-- no attr : " + mValue);
+
+ return null;
+ }
+
+ if (TYPE_REQ.equals(mType)) {
+ // mPrefix and mValue are looked up case-insensitive
+ String reqAttr = req.getExtDataInString(mPrefix, mValue);
+ if (reqAttr == null) {
+ throw new
+ ELdapException(CMS.getUserMessage("CMS_LDAP_NO_REQUEST",
+ mValue, mAttr));
+ }
+ return mAttr + "=" + reqAttr;
+ }
+
+ return null;
+ }
+
+ public String getReqAttr() {
+ if (TYPE_REQ.equals(mType))
+ return mValue;
+ else
+ return null;
+ }
+
+ public String getCertAttr() {
+ if (TYPE_SUBJ.equals(mType))
+ return mValue;
+ else
+ return null;
+ }
+
+ /**
+ * Explode RDN into AVAs.
+ * Does not handle escaped '+'
+ * Java ldap library does not yet support multiple avas per rdn.
+ * If RDN is malformed returns empty array.
+ */
+ public static String[] explodeRDN(String rdn) {
+ int plus = rdn.indexOf('+');
+
+ if (plus == -1)
+ return new String[] { rdn };
+ Vector avas = new Vector();
+ StringTokenizer token = new StringTokenizer(rdn, "+");
+
+ while (token.hasMoreTokens())
+ avas.addElement(token.nextToken());
+ String[] theAvas = new String[avas.size()];
+
+ avas.copyInto(theAvas);
+ return theAvas;
+ }
+
+ /**
+ * Explode AVA into name and value.
+ * Does not handle escaped '='
+ * If AVA is malformed empty array is returned.
+ */
+ public static String[] explodeAVA(String ava) {
+ int equals = ava.indexOf('=');
+
+ if (equals == -1)
+ return null;
+ return new String[] {
+ ava.substring(0, equals).trim(), ava.substring(equals + 1).trim()};
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java b/pki/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java
new file mode 100644
index 000000000..2785cc6cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java
@@ -0,0 +1,202 @@
+// --- 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.publish.mappers;
+
+
+import com.netscape.certsrv.logging.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a ldap dn from
+ * request attributes and cert subject name.<p>
+ *
+ * dnpattern is a string representing a ldap dn pattern to formulate from
+ * the certificate subject name attributes and request attributes .
+ * If empty or not set, the certificate subject name
+ * will be used as the ldap dn. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$subj" "." attrName [ "." attrNumber ] |
+ * name "=" "$req" "." attrName [ "." attrNumber ] |
+ * "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>cn=Certificate Manager,ou=people,o=mcom.com</i>
+ * cert subject name: dn: CN=Certificate Manager, OU=people, O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * CN=Certificate Manager, OU=people, O=mcom.com
+ * <p>
+ * note: Subordinate ca enrollment will use ca mapper. Use predicate
+ * to distinguish the ca itself and the subordinates.
+ *
+ * Example2: <i>UID=$req.HTTP_PARAMS.uid, OU=$subj.ou, O=people, , O=mcom.com</i>
+ * cert subject name: dn: UID=jjames, OU=IS, O=people, , O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * UID=jjames, OU=IS, OU=people, O=mcom.com
+ * <p>
+ * UID = the 'uid' attribute value in the request. <br>
+ * OU = the 'ou' value in the cert subject name. <br>
+ * O = the string people, mcom.com. <br>
+ * <p>
+ * </pre>
+ * If an request attribute or subject DN component does not exist,
+ * the attribute is skipped. There is potential risk that a wrong dn
+ * will be mapped into.
+ *
+ * @version $Revision$, $Date$
+ */
+public class MapDNPattern {
+
+ /* the list of request attriubutes to retrieve*/
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attriubutes to retrieve*/
+ protected String[] mCertAttrs = null;
+
+ /* rdn patterns */
+ protected MapRDNPattern[] mRDNPatterns = null;
+
+ /* original pattern string */
+ protected String mPatternString = null;
+
+ protected String mTestDN = null;
+
+ /**
+ * Construct a DN pattern by parsing a pattern string.
+ * @param pattern the DN pattern
+ * @exception EBaseException If parsing error occurs.
+ */
+ public MapDNPattern(String pattern)
+ throws ELdapException {
+ if (pattern == null || pattern.equals("")) {
+ CMS.debug(
+ "MapDNPattern: null pattern");
+ } else {
+ mPatternString = pattern;
+ PushbackReader in = new PushbackReader(new StringReader(pattern));
+
+ parse(in);
+ }
+ }
+
+ public MapDNPattern(PushbackReader in)
+ throws ELdapException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws ELdapException {
+ Vector rdnPatterns = new Vector();
+ MapRDNPattern rdnPattern = null;
+ int lastChar = -1;
+
+ do {
+ rdnPattern = new MapRDNPattern(in);
+ rdnPatterns.addElement(rdnPattern);
+ try {
+ lastChar = in.read();
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ }
+ while (lastChar == ',');
+
+ mRDNPatterns = new MapRDNPattern[rdnPatterns.size()];
+ rdnPatterns.copyInto(mRDNPatterns);
+
+ Vector reqAttrs = new Vector();
+
+ for (int i = 0; i < mRDNPatterns.length; i++) {
+ String[] rdnAttrs = mRDNPatterns[i].getReqAttrs();
+
+ if (rdnAttrs != null && rdnAttrs.length > 0)
+ for (int j = 0; j < rdnAttrs.length; j++)
+ reqAttrs.addElement(rdnAttrs[j]);
+ }
+ mReqAttrs = new String[reqAttrs.size()];
+ reqAttrs.copyInto(mReqAttrs);
+
+ Vector certAttrs = new Vector();
+
+ for (int i = 0; i < mRDNPatterns.length; i++) {
+ String[] rdnAttrs = mRDNPatterns[i].getCertAttrs();
+
+ if (rdnAttrs != null && rdnAttrs.length > 0)
+ for (int j = 0; j < rdnAttrs.length; j++)
+ certAttrs.addElement(rdnAttrs[j]);
+ }
+ mCertAttrs = new String[certAttrs.size()];
+ certAttrs.copyInto(mCertAttrs);
+ }
+
+ /**
+ * Form a Ldap v3 DN string from a request and a cert subject name.
+ * @param req the request for (un)publish
+ * @param subject the subjectDN of the certificate
+ * @return Ldap v3 DN string to use for base ldap search.
+ */
+ public String formDN(IRequest req, X500Name subject, CertificateExtensions ext)
+ throws ELdapException {
+ StringBuffer formedDN = new StringBuffer();
+
+ for (int i = 0; i < mRDNPatterns.length; i++) {
+ if (mTestDN != null)
+ mRDNPatterns[i].mTestDN = mTestDN;
+ String rdn = mRDNPatterns[i].formRDN(req, subject, ext);
+
+ if (rdn != null && rdn.length() != 0) {
+ if (formedDN.length() != 0)
+ formedDN.append(",");
+ formedDN.append(rdn);
+ } else {
+ throw new ELdapException("pattern not matched");
+ }
+ }
+ return formedDN.toString();
+ }
+
+ public String[] getReqAttrs() {
+ return (String[]) mReqAttrs.clone();
+ }
+
+ public String[] getCertAttrs() {
+ return (String[]) mCertAttrs.clone();
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java b/pki/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java
new file mode 100644
index 000000000..e26252dda
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java
@@ -0,0 +1,218 @@
+// --- 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.publish.mappers;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * class for parsing a DN pattern used to construct a ldap dn from
+ * request attributes and cert subject name.<p>
+ *
+ * dnpattern is a string representing a ldap dn pattern to formulate from
+ * the certificate subject name attributes and request attributes .
+ * If empty or not set, the certificate subject name
+ * will be used as the ldap dn. <p>
+ *
+ * The syntax is
+ * <pre>
+ * dnPattern := rdnPattern *[ "," rdnPattern ]
+ * rdnPattern := avaPattern *[ "+" avaPattern ]
+ * avaPattern := name "=" value |
+ * name "=" "$subj" "." attrName [ "." attrNumber ] |
+ * name "=" "$req" "." attrName [ "." attrNumber ] |
+ * "$rdn" "." number
+ * </pre>
+ * <pre>
+ * Example1: <i>cn=Certificate Manager,ou=people,o=mcom.com</i>
+ * cert subject name: dn: CN=Certificate Manager, OU=people, O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * CN=Certificate Manager, OU=people, O=mcom.com
+ * <p>
+ * note: Subordinate ca enrollment will use ca mapper. Use predicate
+ * to distinguish the ca itself and the subordinates.
+ *
+ * Example2: <i>UID=$req.HTTP_PARAMS.uid, OU=$subj.ou, O=people, , O=mcom.com</i>
+ * cert subject name: dn: UID=jjames, OU=IS, O=people, , O=mcom.com
+ * request attributes: uid: cmanager
+ * <p>
+ * The dn formulated will be : <br>
+ * UID=jjames, OU=IS, OU=people, O=mcom.com
+ * <p>
+ * UID = the 'uid' attribute value in the request. <br>
+ * OU = the 'ou' value in the cert subject name. <br>
+ * O = the string people, mcom.com. <br>
+ * <p>
+ * </pre>
+ * If an request attribute or subject DN component does not exist,
+ * the attribute is skipped.There is potential risk that a wrong dn
+ * will be mapped into.
+ *
+ * @version $Revision$, $Date$
+ */
+class MapRDNPattern {
+
+ /* the list of request attributes needed by this RDN */
+ protected String[] mReqAttrs = null;
+
+ /* the list of cert attributes needed by this RDN */
+ protected String[] mCertAttrs = null;
+
+ /* AVA patterns */
+ protected MapAVAPattern[] mAVAPatterns = null;
+
+ /* original pattern string */
+ protected String mPatternString = null;
+
+ protected String mTestDN = null;
+
+ /**
+ * Construct a DN pattern by parsing a pattern string.
+ * @param pattenr the DN pattern
+ * @exception ELdapException If parsing error occurs.
+ */
+ public MapRDNPattern(String pattern)
+ throws ELdapException {
+ if (pattern == null || pattern.equals("")) {
+ CMS.debug(
+ "MapDNPattern: null pattern");
+ } else {
+ mPatternString = pattern;
+ PushbackReader in = new PushbackReader(new StringReader(pattern));
+
+ parse(in);
+ }
+ }
+
+ /**
+ * Construct a DN pattern from a input stream of pattern
+ */
+ public MapRDNPattern(PushbackReader in)
+ throws ELdapException {
+ parse(in);
+ }
+
+ private void parse(PushbackReader in)
+ throws ELdapException {
+ //System.out.println("_________ begin rdn _________");
+ Vector avaPatterns = new Vector();
+ MapAVAPattern avaPattern = null;
+ int lastChar;
+
+ do {
+ avaPattern = new MapAVAPattern(in);
+ avaPatterns.addElement(avaPattern);
+ //System.out.println("added AVAPattern"+
+ //" mType "+avaPattern.mType+
+ //" mAttr "+avaPattern.mAttr+
+ //" mValue "+avaPattern.mValue+
+ //" mElement "+avaPattern.mElement);
+ try {
+ lastChar = in.read();
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ }
+ while (lastChar == '+');
+
+ if (lastChar != -1) {
+ try {
+ in.unread(lastChar); // pushback last ,
+ } catch (IOException e) {
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ mAVAPatterns = new MapAVAPattern[avaPatterns.size()];
+ avaPatterns.copyInto(mAVAPatterns);
+
+ Vector reqAttrs = new Vector();
+
+ for (int i = 0; i < mAVAPatterns.length; i++) {
+ String avaAttr = mAVAPatterns[i].getReqAttr();
+
+ if (avaAttr == null || avaAttr.length() == 0)
+ continue;
+ reqAttrs.addElement(avaAttr);
+ }
+ mReqAttrs = new String[reqAttrs.size()];
+ reqAttrs.copyInto(mReqAttrs);
+
+ Vector certAttrs = new Vector();
+
+ for (int i = 0; i < mAVAPatterns.length; i++) {
+ String avaAttr = mAVAPatterns[i].getCertAttr();
+
+ if (avaAttr == null || avaAttr.length() == 0)
+ continue;
+ certAttrs.addElement(avaAttr);
+ }
+ mCertAttrs = new String[certAttrs.size()];
+ certAttrs.copyInto(mCertAttrs);
+ }
+
+ /**
+ * Form a Ldap v3 DN string from a request and a cert subject name.
+ * @param req the request for (un)publish
+ * @param subject the subjectDN of the certificate
+ * @return Ldap v3 DN string to use for base ldap search.
+ */
+ public String formRDN(IRequest req, X500Name subject, CertificateExtensions ext)
+ throws ELdapException {
+ StringBuffer formedRDN = new StringBuffer();
+
+ for (int i = 0; i < mAVAPatterns.length; i++) {
+ if (mTestDN != null)
+ mAVAPatterns[i].mTestDN = mTestDN;
+ String ava = mAVAPatterns[i].formAVA(req, subject, ext);
+
+ if (ava != null && ava.length() > 0) {
+ if (formedRDN.length() != 0)
+ formedRDN.append("+");
+ formedRDN.append(ava);
+ }
+ }
+ //System.out.println("formed RDN "+formedRDN.toString());
+ return formedRDN.toString();
+ }
+
+ public String[] getReqAttrs() {
+ return (String[]) mReqAttrs.clone();
+ }
+
+ public String[] getCertAttrs() {
+ return (String[]) mCertAttrs.clone();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/NoMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/NoMap.java
new file mode 100644
index 000000000..85fdaae04
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/NoMap.java
@@ -0,0 +1,108 @@
+// --- 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.publish.mappers;
+
+
+import netscape.ldap.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * No Map
+ *
+ * @version $Revision$, $Date$
+ */
+public class NoMap implements ILdapMapper, IExtendedPluginInfo {
+
+ public IConfigStore mConfig = null;
+
+ /**
+ * constructor if initializing from config store.
+ */
+ public NoMap() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-ldappublish-mapper-simplemapper",
+ IExtendedPluginInfo.HELP_TEXT + ";Describes how to form the name of the entry to publish to"
+ };
+
+ return params;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * for initializing from config store.
+ */
+ public void init(IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ }
+
+ /**
+ * Maps a X500 subject name to LDAP entry.
+ * Uses DN pattern to form a DN for a LDAP base search.
+ *
+ * @param conn the LDAP connection.
+ * @param obj the object to map.
+ * @exception ELdapException if any LDAP exceptions occured.
+ */
+ public String map(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ return null;
+ }
+
+ public String map(LDAPConnection conn, IRequest req, Object obj)
+ throws ELdapException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "NoMap";
+ }
+
+ public String getDescription() {
+ return "NoMap";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ return v;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java
new file mode 100644
index 000000000..18af1a98b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java
@@ -0,0 +1,424 @@
+// --- 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.publish.publishers;
+
+
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import java.util.zip.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import org.mozilla.jss.util.Base64OutputStream;
+
+/**
+ * This publisher writes certificate and CRL into
+ * a directory.
+ *
+ * @version $Revision$, $Date$
+ */
+public class FileBasedPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ private static final String PROP_DIR = "directory";
+ private static final String PROP_DER = "Filename.der";
+ private static final String PROP_B64 = "Filename.b64";
+ private static final String PROP_LNK = "latestCrlLink";
+ private static final String PROP_GMT = "timeStamp";
+ private static final String PROP_EXT = "crlLinkExt";
+ private static final String PROP_ZIP = "zipCRLs";
+ private static final String PROP_LEV = "zipLevel";
+ private IConfigStore mConfig = null;
+ private String mDir = null;
+ private ILogger mLogger = CMS.getLogger();
+ private String mCrlIssuingPointId;
+ protected boolean mDerAttr = true;
+ protected boolean mB64Attr = false;
+ protected boolean mLatestCRL = false;
+ protected boolean mZipCRL = false;
+ protected String mTimeStamp = null;
+ protected String mLinkExt = null;
+ protected int mZipLevel = 9;
+
+ public void setIssuingPointId(String crlIssuingPointId)
+ {
+ mCrlIssuingPointId = crlIssuingPointId;
+ }
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName() {
+ return "FileBasedPublisher";
+ }
+
+ /**
+ * Returns the description of the ldap publisher.
+ */
+
+ public String getDescription() {
+ return "This publisher writes the Certificates and CRLs into files.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_DIR + ";string;Directory in which to put the files (absolute path or relative path to cert-* instance directory).",
+ PROP_DER + ";boolean;Store certificates or CRLs into *.der files.",
+ PROP_B64 + ";boolean;Store certificates or CRLs into *.b64 files.",
+ PROP_GMT + ";choice(LocalTime,GMT);Use local time or GMT to time stamp CRL file name with CRL's 'thisUpdate' field.",
+ PROP_LNK + ";boolean;Generate link to the latest binary CRL. It requires '"+PROP_DER+"' to be enabled.",
+ PROP_EXT + ";string;Name extension used by link to the latest CRL. Default name extension is 'der'.",
+ PROP_ZIP + ";boolean;Generate compressed CRLs.",
+ PROP_LEV + ";choice(0,1,2,3,4,5,6,7,8,9);Set compression level from 0 to 9.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-filepublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Stores the certificates or CRLs into files. Certificate is named as cert-<serialno>.der or *.b64, and CRL is named as <IssuingPoint>-<thisUpdate-time>.der or *.b64."
+ };
+
+ return params;
+ }
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ String dir = "";
+ String ext = "";
+
+ try {
+ dir = mConfig.getString(PROP_DIR);
+ } catch (EBaseException e) {
+ }
+ try {
+ ext = mConfig.getString(PROP_EXT);
+ } catch (EBaseException e) {
+ }
+ try {
+ mTimeStamp = mConfig.getString(PROP_GMT);
+ } catch (EBaseException e) {
+ }
+ try {
+ mZipLevel = mConfig.getInteger(PROP_LEV, 9);
+ } catch (EBaseException e) {
+ }
+ try {
+ if (mTimeStamp == null || (!mTimeStamp.equals("GMT")))
+ mTimeStamp = "LocalTime";
+ v.addElement(PROP_DIR+"=" + dir);
+ v.addElement(PROP_DER+"=" + mConfig.getBoolean(PROP_DER,true));
+ v.addElement(PROP_B64+"=" + mConfig.getBoolean(PROP_B64,false));
+ v.addElement(PROP_GMT+"=" + mTimeStamp);
+ v.addElement(PROP_LNK+"=" + mConfig.getBoolean(PROP_LNK,false));
+ v.addElement(PROP_EXT+"=" + ext);
+ v.addElement(PROP_ZIP+"=" + mConfig.getBoolean(PROP_ZIP,false));
+ v.addElement(PROP_LEV+"=" + mZipLevel);
+ } catch (Exception e) {
+ }
+ return v;
+ }
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_DIR+"=");
+ v.addElement(PROP_DER+"=true");
+ v.addElement(PROP_B64+"=false");
+ v.addElement(PROP_GMT+"=LocalTime");
+ v.addElement(PROP_LNK+"=false");
+ v.addElement(PROP_EXT+"=");
+ v.addElement(PROP_ZIP+"=false");
+ v.addElement(PROP_LEV+"=9");
+ return v;
+ }
+
+ /**
+ * Initializes this plugin.
+ */
+ public void init(IConfigStore config) {
+ mConfig = config;
+ String dir = null;
+ String ext = null;
+
+ try {
+ dir = mConfig.getString(PROP_DIR, null);
+ mDerAttr = mConfig.getBoolean(PROP_DER, true);
+ mB64Attr = mConfig.getBoolean(PROP_B64, false);
+ mTimeStamp = mConfig.getString(PROP_GMT, "LocalTime");
+ mLatestCRL = mConfig.getBoolean(PROP_LNK, false);
+ mLinkExt = mConfig.getString(PROP_EXT, null);
+ mZipCRL = mConfig.getBoolean(PROP_ZIP, false);
+ mZipLevel = mConfig.getInteger(PROP_LEV, 9);
+ } catch (EBaseException e) {
+ }
+ if (dir == null) {
+ throw new RuntimeException("No Directory Specified");
+ }
+
+ // convert to forward slash
+ dir = dir.replace('\\', '/');
+ config.putString(PROP_DIR, dir);
+
+ File dirCheck = new File(dir);
+
+ if (dirCheck.isDirectory()) {
+ mDir = dir;
+ } else {
+ // maybe it is relative path
+ String mInstanceRoot = null;
+
+ try {
+ mInstanceRoot = CMS.getConfigStore().getString("instanceRoot");
+ } catch (Exception e) {
+ throw new RuntimeException("Invalid Instance Dir " + e);
+ }
+ dirCheck = new File(mInstanceRoot +
+ File.separator + dir);
+ if (dirCheck.isDirectory()) {
+ mDir = mInstanceRoot + File.separator + dir;
+ } else {
+ throw new RuntimeException("Invalid Directory " + dir);
+ }
+ }
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ private String[] getCrlNamePrefix(X509CRL crl, boolean useGMT) {
+ String[] namePrefix = {"crl", "crl"};
+
+ if (mCrlIssuingPointId != null && mCrlIssuingPointId.length() != 0) {
+ namePrefix[0] = mCrlIssuingPointId;
+ namePrefix[1] = mCrlIssuingPointId;
+ }
+ java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyyMMdd-HHmmss");
+ TimeZone tz = TimeZone.getTimeZone("GMT");
+ if (useGMT) format.setTimeZone(tz);
+ String timeStamp = format.format(crl.getThisUpdate()).toString();
+ namePrefix[0] += "-" + timeStamp;
+ if (((netscape.security.x509.X509CRLImpl)crl).isDeltaCRL()) {
+ namePrefix[0] += "-delta";
+ namePrefix[1] += "-delta";
+ }
+
+ return namePrefix;
+ }
+
+ private void createLink(String linkName, String fileName) {
+ String cmd = "ln -s " + fileName + " " + linkName + ".new";
+ if (com.netscape.cmsutil.util.Utils.exec(cmd)) {
+ File oldLink = new File(linkName + ".old");
+ if (oldLink.exists()) { // remove old link if exists
+ oldLink.delete();
+ }
+ File link = new File(linkName);
+ if (link.exists()) { // current link becomes an old link
+ link.renameTo(new File(linkName + ".old"));
+ }
+ File newLink = new File(linkName + ".new");
+ if (newLink.exists()) { // new link becomes current link
+ newLink.renameTo(new File(linkName));
+ }
+ oldLink = new File(linkName + ".old");
+ if (oldLink.exists()) { // remove a new old link
+ oldLink.delete();
+ }
+ } else {
+ CMS.debug("FileBasedPublisher: createLink: '" + cmd + "' --- failed");
+ }
+ }
+
+ /**
+ * Publishs a object to the ldap directory.
+ *
+ * @param conn a Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to publish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to publish
+ * (java.security.cert.X509Certificate or,
+ * java.security.cert.X509CRL)
+ */
+ public void publish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ CMS.debug("FileBasedPublisher: publish");
+ try {
+ if (object instanceof X509Certificate) {
+ X509Certificate cert = (X509Certificate) object;
+ BigInteger sno = cert.getSerialNumber();
+ String name = mDir +
+ File.separator + "cert-" +
+ sno.toString();
+ if (mDerAttr)
+ {
+ String fileName = name + ".der";
+ FileOutputStream fos = new FileOutputStream(fileName);
+ fos.write(cert.getEncoded());
+ fos.close();
+ }
+ if (mB64Attr)
+ {
+ String fileName = name + ".b64";
+ FileOutputStream fos = new FileOutputStream(fileName);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 =
+ new Base64OutputStream(new PrintStream(new FilterOutputStream(output)));
+ b64.write(cert.getEncoded());
+ b64.flush();
+ (new PrintStream(fos)).print(output.toString("8859_1"));
+ fos.close();
+ }
+ } else if (object instanceof X509CRL) {
+ X509CRL crl = (X509CRL) object;
+ String[] namePrefix = getCrlNamePrefix(crl, mTimeStamp.equals("GMT"));
+ String baseName = mDir + File.separator + namePrefix[0];
+ String tempFile = baseName + ".temp";
+ FileOutputStream fos;
+ ZipOutputStream zos;
+ byte [] encodedArray = null;
+ File destFile = null;
+ String destName = null;
+ File renameFile = null;
+
+ if (mDerAttr) {
+ fos = new FileOutputStream(tempFile);
+ encodedArray = crl.getEncoded();
+ fos.write(encodedArray);
+ fos.close();
+ if (mZipCRL) {
+ zos = new ZipOutputStream(new FileOutputStream(baseName+".zip"));
+ zos.setLevel(mZipLevel);
+ zos.putNextEntry(new ZipEntry(baseName+".der"));
+ zos.write(encodedArray, 0, encodedArray.length);
+ zos.closeEntry();
+ zos.close();
+ }
+ destName = baseName + ".der";
+ destFile = new File(destName);
+
+ if (destFile.exists())
+ destFile.delete();
+ renameFile = new File(tempFile);
+ renameFile.renameTo(destFile);
+
+ if (mLatestCRL) {
+ String linkExt = ".";
+ if (mLinkExt != null && mLinkExt.length() > 0) {
+ linkExt += mLinkExt;
+ } else {
+ linkExt += "der";
+ }
+ String linkName = mDir + File.separator + namePrefix[1] + linkExt;
+ createLink(linkName, destName);
+ if (mZipCRL) {
+ linkName = mDir + File.separator + namePrefix[1] + ".zip";
+ createLink(linkName, baseName+".zip");
+ }
+ }
+ }
+
+ // output base64 file
+ if(mB64Attr==true)
+ {
+ if (encodedArray ==null)
+ encodedArray = crl.getEncoded();
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ fos = new FileOutputStream(tempFile);
+ fos.write(com.netscape.osutil.OSUtil.BtoA(encodedArray).getBytes());
+ fos.close();
+ destName = baseName + ".b64";
+ destFile = new File(destName);
+
+ if(destFile.exists())
+ destFile.delete();
+ renameFile = new File(tempFile);
+ renameFile.renameTo(destFile);
+ }
+ }
+ } catch (IOException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_FILE_PUBLISHER_ERROR", e.toString()));
+ } catch (CertificateEncodingException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_FILE_PUBLISHER_ERROR", e.toString()));
+ } catch (CRLException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_FILE_PUBLISHER_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Unpublishs a object to the ldap directory.
+ *
+ * @param conn the Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to unpublish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to unpublish
+ * (java.security.cert.X509Certificate)
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ CMS.debug("FileBasedPublisher: unpublish");
+ String name = mDir + File.separator;
+ String fileName;
+
+ if (object instanceof X509Certificate) {
+ X509Certificate cert = (X509Certificate) object;
+ BigInteger sno = cert.getSerialNumber();
+ name += "cert-" + sno.toString();
+ } else if (object instanceof X509CRL) {
+ X509CRL crl = (X509CRL) object;
+ String[] namePrefix = getCrlNamePrefix(crl, mTimeStamp.equals("GMT"));
+ name += namePrefix[0];
+
+ fileName = name + ".zip";
+ File f = new File(fileName);
+ f.delete();
+ }
+ fileName = name + ".der";
+ File f = new File(fileName);
+ f.delete();
+
+ fileName = name + ".b64";
+ f = new File(fileName);
+ f.delete();
+ }
+ /**
+ * returns the Der attribute where it'll be published.
+ */
+ public boolean getDerAttr() {
+ return mDerAttr;
+ }
+ /**
+ * returns the B64 attribute where it'll be published.
+ */
+ public boolean getB64Attr() {
+ return mB64Attr;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
new file mode 100644
index 000000000..5b6533e13
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
@@ -0,0 +1,408 @@
+// --- 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.publish.publishers;
+
+
+import netscape.ldap.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Interface for publishing a CA certificate to
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCaCertPublisher
+ implements ILdapPublisher, IExtendedPluginInfo {
+ public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
+ public static final String LDAP_CA_OBJECTCLASS = "pkiCA";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
+
+ protected String mCaCertAttr = LDAP_CACERT_ATTR;
+ protected String mCaObjectclass = LDAP_CA_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+ private String mcrlIssuingPointId;
+
+
+ /**
+ * constructor constructs default values.
+ */
+ public LdapCaCertPublisher() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ "caCertAttr;string;Name of Ldap attribute in which to store certificate",
+ "caObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be " +
+ "'certificationAuthority' (if using RFC 2256) or 'pkiCA' (if using RFC 4523)",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-cacertpublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin knows how to publish the CA cert to " +
+ "'certificateAuthority' and 'pkiCA' -type entries"
+ };
+
+ return s;
+ }
+
+ public String getImplName() {
+ return "LdapCaCertPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapCaCertPublisher";
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("caCertAttr=" + mCaCertAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("caCertAttr=" + mCaCertAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass",
+ LDAP_CA_OBJECTCLASS);
+ mObjAdded = mConfig.getString("caObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("caObjectClassDeleted", "");
+ mInited = true;
+ }
+
+ // don't think anyone would ever use this but just in case.
+ public LdapCaCertPublisher(String caCertAttr, String caObjectclass) {
+ mCaCertAttr = caCertAttr;
+ mCaObjectclass = caObjectclass;
+ mInited = true;
+ }
+
+ /**
+ * Gets the CA object class to convert to.
+ */
+ public String getCAObjectclass() {
+ return mCaObjectclass;
+ }
+
+ /**
+ * returns the ca cert attribute where it'll be published.
+ */
+ public String getCaCertAttrName() {
+ return mCaCertAttr;
+ }
+
+ /**
+ * publish a CA certificate
+ * Adds the cert to the multi-valued certificate attribute as a
+ * DER encoded binary blob. Does not check if cert already exists.
+ * Converts the class to certificateAuthority.
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the certificate
+ * @param certObj the certificate object.
+ */
+ public void publish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (conn == null) {
+ log(ILogger.LL_INFO, "LdapCaCertPublisher: no LDAP connection");
+ return;
+ }
+
+ try {
+ mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ // Bugscape #56124 - support multiple publishing directory
+ // see if we should create local connection
+ LDAPConnection altConn = null;
+ try {
+ String host = mConfig.getString("host", null);
+ String port = mConfig.getString("port", null);
+ if (host != null && port != null) {
+ int portVal = Integer.parseInt(port);
+ int version = Integer.parseInt(mConfig.getString("version", "2"));
+ String cert_nick = mConfig.getString("clientCertNickname", null);
+ LDAPSSLSocketFactoryExt sslSocket = null;
+ if (cert_nick != null) {
+ sslSocket = CMS.getLdapJssSSLSocketFactory(cert_nick);
+ }
+ String mgr_dn = mConfig.getString("bindDN", null);
+ String mgr_pwd = mConfig.getString("bindPWD", null);
+
+ altConn = CMS.getBoundConnection(host, portVal,
+ version,
+ sslSocket, mgr_dn, mgr_pwd);
+ conn = altConn;
+ }
+ } catch (LDAPException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ } catch (EBaseException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ }
+
+
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ /* search for attribute names to determine existence of attributes */
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CRL_ATTR, LDAP_ARL_ATTR }, true);
+ LDAPEntry entry = res.next();
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
+
+ /* search for objectclass and caCert values */
+ LDAPSearchResults res1 =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass", mCaCertAttr }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+ LDAPAttribute certs = entry1.getAttribute(mCaCertAttr);
+
+ boolean hasCert =
+ LdapUserCertPublisher.ByteValueExists(certs, certEnc);
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ if (hasCert) {
+ log(ILogger.LL_INFO, "publish: CA " + dn + " already has Cert");
+ } else {
+ /*
+ fix for 360458 - if no cert, use add, if has cert but
+ not equal, use replace
+ */
+ if (certs == null) {
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(mCaCertAttr, certEnc));
+ log(ILogger.LL_INFO, "CA cert added");
+ } else {
+ modSet.add(LDAPModification.REPLACE,
+ new LDAPAttribute(mCaCertAttr, certEnc));
+ log(ILogger.LL_INFO, "CA cert replaced");
+ }
+ }
+
+ String[] oclist = mCaObjectclass.split(",");
+
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (!hasoc) {
+ log(ILogger.LL_INFO, "adding CA objectclass " + oc + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute("objectclass", oc));
+
+ if ((!attrsAdded) && oc.equalsIgnoreCase("certificationAuthority")) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (crls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ attrsAdded = true;
+ }
+ }
+ }
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CA objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("caObjectClassAdded", "");
+ mConfig.putString("caObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
+
+ if (modSet.size() > 0) conn.modify(dn, modSet);
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_DECODE_CERT", dn));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISHER_EXCEPTION", "", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CACERT_ERROR", e.toString()));
+ }
+ } finally {
+ if (altConn != null) {
+ try {
+ altConn.disconnect();
+ } catch (LDAPException e) {
+ // safely ignored
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * deletes the certificate from CA's certificate attribute.
+ * if it's the last cert will also remove the certificateAuthority
+ * objectclass.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ try {
+ mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { mCaCertAttr, "objectclass" }, false);
+
+ LDAPEntry entry = res.next();
+ LDAPAttribute certs = entry.getAttribute(mCaCertAttr);
+ LDAPAttribute ocs = entry.getAttribute("objectclass");
+
+ boolean hasCert =
+ LdapUserCertPublisher.ByteValueExists(certs, certEnc);
+
+ if (!hasCert) {
+ log(ILogger.LL_INFO, "unpublish: " + dn + " has not cert already");
+ //throw new ELdapException(
+ // LdapResources.ALREADY_UNPUBLISHED_1, dn);
+ return;
+ }
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(mCaCertAttr, certEnc));
+ if (certs.size() == 1) {
+ // if last ca cert, remove oc also.
+
+ String[] oclist = mCaObjectclass.split(",");
+ for (int i =0 ; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasOC = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (hasOC) {
+ log(ILogger.LL_INFO, "unpublish: deleting CA oc" + oc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", oc));
+ }
+ }
+ }
+ conn.modify(dn, modSet);
+ } catch (CertificateEncodingException e) {
+ CMS.debug("LdapCaCertPublisher: unpublish: Cannot decode cert for " + dn);
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_CACERT_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ /**
+ * handy routine for logging in this class.
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCaPublisher: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java
new file mode 100644
index 000000000..654a93150
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java
@@ -0,0 +1,332 @@
+// --- 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.publish.publishers;
+
+
+import java.io.*;
+import java.util.*;
+import netscape.ldap.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Interface for mapping a X509 certificate to a LDAP entry
+ * Publishes a certificate as binary and its subject name.
+ * there is one subject name value for each certificate.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCertSubjPublisher implements ILdapPublisher {
+ public static final String LDAP_CERTSUBJNAME_ATTR = "certSubjectName";
+ protected String mCertAttr = LdapUserCertPublisher.LDAP_USERCERT_ATTR;
+ protected String mSubjNameAttr = LDAP_CERTSUBJNAME_ATTR;
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+
+ /**
+ * constructor using default certificate subject name and attribute for
+ * publishing subject name.
+ */
+ public LdapCertSubjPublisher() {
+ }
+
+ public String getImplName() {
+ return "LdapCertSubjPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapCertSubjPublisher";
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ v.addElement("subjectNameAttr=" + mSubjNameAttr);
+ return v;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ v.addElement("subjectNameAttr=" + mSubjNameAttr);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCertAttr = mConfig.getString("certAttr",
+ LdapUserCertPublisher.LDAP_USERCERT_ATTR);
+ mSubjNameAttr = mConfig.getString("certSubjectName",
+ LDAP_CERTSUBJNAME_ATTR);
+ mInited = true;
+ }
+
+ /**
+ * constrcutor using specified certificate attribute and
+ * certificate subject name attribute.
+ */
+ public LdapCertSubjPublisher(String certAttr, String subjNameAttr) {
+ mCertAttr = certAttr;
+ mSubjNameAttr = subjNameAttr;
+ }
+
+ public String getCertAttr() {
+ return mCertAttr;
+ }
+
+ public String getSubjNameAttr() {
+ return mSubjNameAttr;
+ }
+
+ public void setSubjNameAttr(String subjNameAttr) {
+ mSubjNameAttr = subjNameAttr;
+ }
+
+ public void setCertAttr(String certAttr) {
+ mCertAttr = certAttr;
+ }
+
+ /**
+ * publish a user certificate
+ * Adds the cert to the multi-valued certificate attribute as a
+ * DER encoded binary blob. Does not check if cert already exists.
+ * Then adds the subject name of the cert to the subject name attribute.
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the certificate
+ * @param certObj the certificate object.
+ * @exception ELdapException if cert or subject name already exists,
+ * if cert encoding fails, if getting cert subject name fails.
+ * Use ELdapException.getException() to find underlying exception.
+ */
+ public void publish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (conn == null) {
+ log(ILogger.LL_INFO, "LdapCertSubjPublisher: no LDAP connection");
+ return;
+ }
+
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ try {
+ boolean hasCert = false, hasSubjname = false;
+ byte[] certEnc = cert.getEncoded();
+ String subjName = ((X500Name) cert.getSubjectDN()).toLdapDNString();
+
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { mCertAttr, mSubjNameAttr }, false);
+
+ LDAPEntry entry = res.next();
+ LDAPAttribute certs = entry.getAttribute(mCertAttr);
+ LDAPAttribute subjnames = entry.getAttribute(mSubjNameAttr);
+
+ // check if has cert already.
+ if (certs != null) {
+ hasCert = LdapUserCertPublisher.ByteValueExists(certs, certEnc);
+ }
+
+ // check if has subject name already.
+ if (subjnames != null) {
+ hasSubjname =
+ LdapUserCertPublisher.StringValueExists(subjnames, subjName);
+ }
+
+ // if has both, done.
+ if (hasCert && hasSubjname) {
+ log(ILogger.LL_INFO,
+ "publish: " + subjName + " already has cert & subject name");
+ return;
+ }
+
+ // add cert if not already there.
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ if (!hasCert) {
+ log(ILogger.LL_INFO, "publish: adding cert to " + subjName);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(mCertAttr, certEnc));
+ }
+ // add subject name if not already there.
+ if (!hasSubjname) {
+ log(ILogger.LL_INFO, "publish: adding " + subjName + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(mSubjNameAttr, subjName));
+ }
+ conn.modify(dn, modSet);
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISHER_EXCEPTION", "", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * deletes the certificate from the list of certificates.
+ * does not check if certificate is already there.
+ * also takes out the subject name if no other certificate remain
+ * with the same subject name.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ try {
+ boolean hasCert = false, hasSubjname = false;
+ boolean hasAnotherCert = false;
+ X509Certificate cert = (X509Certificate) certObj;
+ String subjName = ((X500Name) cert.getSubjectDN()).toLdapDNString();
+
+ byte[] certEnc = cert.getEncoded();
+
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { mCertAttr, mSubjNameAttr }, false);
+
+ LDAPEntry entry = res.next();
+ LDAPAttribute certs = entry.getAttribute(mCertAttr);
+ LDAPAttribute subjnames = entry.getAttribute(mSubjNameAttr);
+
+ // check for cert and other certs with same subject name.
+ if (certs != null) {
+ hasCert = LdapUserCertPublisher.ByteValueExists(certs, certEnc);
+ // check for other certs with the same subject name
+ Enumeration vals = certs.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ if (Utils.byteArraysAreEqual(certEnc, val)) {
+ hasCert = true;
+ continue;
+ }
+ try {
+ X509CertImpl certval = new X509CertImpl(val);
+ // XXX use some sort of X500name equals function here.
+ String subjnam =
+ ((X500Name) certval.getSubjectDN()).toLdapDNString();
+
+ if (subjnam.equalsIgnoreCase(subjName)) {
+ hasAnotherCert = true;
+ }
+ } catch (CertificateEncodingException e) {
+ // ignore this certificate.
+ CMS.debug(
+ "LdapCertSubjPublisher: unpublish: an invalid cert in dn entry encountered");
+ } catch (CertificateException e) {
+ // ignore this certificate.
+ CMS.debug(
+ "LdapCertSubjPublisher: unpublish: an invalid cert in dn entry encountered");
+ }
+ }
+ }
+
+ // check if doesn't have subject name already.
+ if (subjnames != null) {
+ hasSubjname =
+ LdapUserCertPublisher.StringValueExists(subjnames, subjName);
+ }
+
+ // if doesn't have both, done.
+ if (!hasCert && !hasSubjname) {
+ log(ILogger.LL_INFO,
+ "unpublish: " + subjName + " already has not cert & subjname");
+ return;
+ }
+
+ // delete cert if there.
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ if (hasCert) {
+ log(ILogger.LL_INFO,
+ "unpublish: deleting cert " + subjName + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(mCertAttr, certEnc));
+ }
+ // delete subject name if no other cert has the same name.
+ if (hasSubjname && !hasAnotherCert) {
+ log(ILogger.LL_INFO,
+ "unpublish: deleting subject name " + subjName + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(mSubjNameAttr, subjName));
+ }
+ conn.modify(dn, modSet);
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_DECODING_CERT_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_LDAP_DN_STRING_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCertSubjPublisher: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
new file mode 100644
index 000000000..ca8a07ef4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
@@ -0,0 +1,306 @@
+// --- 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.publish.publishers;
+
+
+import netscape.ldap.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * module for publishing a cross certificate pair to ldap
+ * crossCertificatePair attribute
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCertificatePairPublisher
+ implements ILdapPublisher, IExtendedPluginInfo {
+ public static final String LDAP_CROSS_CERT_PAIR_ATTR = "crossCertificatePair;binary";
+ public static final String LDAP_CA_OBJECTCLASS = "pkiCA";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
+ public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
+
+ protected String mCrossCertPairAttr = LDAP_CROSS_CERT_PAIR_ATTR;
+ protected String mCaObjectclass = LDAP_CA_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
+
+ private ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected IConfigStore mConfig = null;
+
+ /**
+ * constructor constructs default values.
+ */
+ public LdapCertificatePairPublisher() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ "crossCertPairAttr;string;Name of Ldap attribute in which to store cross certificates",
+ "caObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be " +
+ "'certificationAuthority' (if using RFC 2256) or 'pkiCA' (if using RFC 4523)",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-crosscertpairpublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin knows how to publish the CA cert to " +
+ "'certificateAuthority' and 'pkiCA' -type entries"
+ };
+
+ return s;
+ }
+
+ public String getImplName() {
+ return "LdapCertificatePairPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapCertificatePairPublisher";
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("crossCertPairAttr=" + mCrossCertPairAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public Vector getInstanceParamsWithExtras() {
+ return getInstanceParams();
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("crossCertPairAttr=" + mCrossCertPairAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCrossCertPairAttr = mConfig.getString("crossCertPairAttr", LDAP_CROSS_CERT_PAIR_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass",
+ LDAP_CA_OBJECTCLASS);
+ mObjAdded = mConfig.getString("caObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("caObjectClassDeleted", "");
+
+ mInited = true;
+ }
+
+ // don't think anyone would ever use this but just in case.
+ public LdapCertificatePairPublisher(String crossCertPairAttr, String caObjectclass) {
+ mCrossCertPairAttr = crossCertPairAttr;
+ mCaObjectclass = caObjectclass;
+ mInited = true;
+ }
+
+ /**
+ * Gets the Certificate Authority object class to convert to.
+ */
+ public String getCAObjectclass() {
+ return mCaObjectclass;
+ }
+
+ /**
+ * returns the cross cert pair attribute where it'll be published.
+ */
+ public String getXCertAttrName() {
+ return mCrossCertPairAttr;
+ }
+
+ /**
+ * publish a certificatePair
+ * -should not be called from listeners.
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the XcertificatePair
+ * @param pair the Xcertificate bytes object.
+ */
+ public synchronized void publish(LDAPConnection conn, String dn, Object pair)
+ throws ELdapException {
+ publish(conn, dn, (byte[]) pair);
+ }
+
+ /**
+ * publish a certificatePair
+ * -should not be called from listeners.
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the XcertificatePair
+ * @param pair the cross cert bytes
+ */
+ public synchronized void publish(LDAPConnection conn, String dn,
+ byte[] pair)
+ throws ELdapException {
+
+ if (conn == null) {
+ log(ILogger.LL_INFO, "LdapCertificatePairPublisher: no LDAP connection");
+ return;
+ }
+
+ try {
+ mCrossCertPairAttr = mConfig.getString("crossCertPairAttr", LDAP_CROSS_CERT_PAIR_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ try {
+ // search for attributes to determine if they exist
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CACERT_ATTR, LDAP_CRL_ATTR, LDAP_ARL_ATTR }, true);
+ LDAPEntry entry = res.next();
+ LDAPAttribute certs = entry.getAttribute(LDAP_CACERT_ATTR);
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
+
+ // search for objectclass and crosscertpair attributes and values
+ LDAPSearchResults res1 =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass", mCrossCertPairAttr }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+ LDAPAttribute certPairs = entry1.getAttribute("crosscertificatepair;binary");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ boolean hasCert = LdapUserCertPublisher.ByteValueExists(certPairs, pair);
+ if (LdapUserCertPublisher.ByteValueExists(certPairs, pair)) {
+ CMS.debug("LdapCertificatePairPublisher: cross cert pair bytes exist in publishing directory, do not publish again.");
+ return;
+ }
+ if (hasCert) {
+ log(ILogger.LL_INFO, "publish: CA " + dn + " already has cross cert pair bytes");
+ } else {
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(mCrossCertPairAttr, pair));
+ log(ILogger.LL_INFO, "cross cert pair published with dn=" + dn);
+ }
+
+ String[] oclist = mCaObjectclass.split(",");
+
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (!hasoc) {
+ log(ILogger.LL_INFO, "adding CA objectclass " + oc + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute("objectclass", oc));
+
+ if ((!attrsAdded) && oc.equalsIgnoreCase("certificationAuthority")) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (crls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ if (certs == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CACERT_ATTR, ""));
+ attrsAdded = true;
+ }
+ }
+ }
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CRL objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("caObjectClassAdded", "");
+ mConfig.putString("caObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
+
+ if (modSet.size() > 0) conn.modify(dn, modSet);
+ CMS.debug("LdapCertificatePairPublisher: in publish() just published");
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISHER_EXCEPTION", "", e.toString()));
+ throw new ELdapException("error publishing cross cert pair:" + e.toString());
+ }
+ }
+ return;
+ }
+
+ /**
+ * unsupported
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ CMS.debug("LdapCertificatePairPublisher: unpublish() is unsupported in this revision");
+ }
+
+ /**
+ * handy routine for logging in this class.
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCertificatePairPublisher: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
new file mode 100644
index 000000000..074d21ee0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
@@ -0,0 +1,367 @@
+// --- 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.publish.publishers;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * For publishing master or global CRL.
+ * Publishes (replaces) the CRL in the CA's LDAP entry.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ private ILogger mLogger = CMS.getLogger();
+ protected IConfigStore mConfig = null;
+ boolean mInited = false;
+
+ public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
+ public static final String LDAP_CRL_OBJECTCLASS = "pkiCA,deltaCRL";
+
+ protected String mCrlAttr = LDAP_CRL_ATTR;
+ protected String mCrlObjectClass = LDAP_CRL_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
+
+ /**
+ * constructs ldap crl publisher with default values
+ */
+ public LdapCrlPublisher() {
+ }
+
+ public String getImplName() {
+ return "LdapCrlPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapCrlPublisher";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "crlAttr;string;Name of Ldap attribute in which to store the CRL",
+ "crlObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be a comma-" +
+ "separated list such as 'certificationAuthority,certificationAuthority-V2' " +
+ "(if using RFC 2256) or 'pkiCA, deltaCRL' (if using RFC 4523)",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-crlpublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin knows how to publish CRL's to " +
+ "'certificateAuthority' and 'pkiCA' -type entries"
+ };
+
+ return params;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("crlAttr=" + mCrlAttr);
+ v.addElement("crlObjectClass=" + mCrlObjectClass);
+ return v;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("crlAttr=" + mCrlAttr);
+ v.addElement("crlObjectClass=" + mCrlObjectClass);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass",
+ LDAP_CRL_OBJECTCLASS);
+ mObjAdded = mConfig.getString("crlObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("crlObjectClassDeleted", "");
+
+ mInited = true;
+ }
+
+ public LdapCrlPublisher(String crlAttr, String crlObjectClass) {
+ mCrlAttr = crlAttr;
+ mCrlObjectClass = crlObjectClass;
+ }
+
+ /**
+ * Gets the CA object class to convert to.
+ */
+ public String getCRLObjectclass() {
+ return mCrlObjectClass;
+ }
+
+ /**
+ * Replaces the CRL in the certificateRevocationList attribute.
+ * CRL's are published as a DER encoded blob.
+ */
+ public void publish(LDAPConnection conn, String dn, Object crlObj)
+ throws ELdapException {
+ if (conn == null) {
+ log(ILogger.LL_INFO, "publish CRL: no LDAP connection");
+ return;
+ }
+
+ try {
+ mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass", LDAP_CRL_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ // Bugscape #56124 - support multiple publishing directory
+ // see if we should create local connection
+ LDAPConnection altConn = null;
+ try {
+ String host = mConfig.getString("host", null);
+ String port = mConfig.getString("port", null);
+ if (host != null && port != null) {
+ int portVal = Integer.parseInt(port);
+ int version = Integer.parseInt(mConfig.getString("version", "2"));
+ String cert_nick = mConfig.getString("clientCertNickname", null);
+ LDAPSSLSocketFactoryExt sslSocket = null;
+ if (cert_nick != null) {
+ sslSocket = CMS.getLdapJssSSLSocketFactory(cert_nick);
+ }
+ String mgr_dn = mConfig.getString("bindDN", null);
+ String mgr_pwd = mConfig.getString("bindPWD", null);
+
+ altConn = CMS.getBoundConnection(host, portVal,
+ version,
+ sslSocket, mgr_dn, mgr_pwd);
+ conn = altConn;
+ }
+ } catch (LDAPException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ } catch (EBaseException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ }
+
+ try {
+ byte[] crlEnc = ((X509CRL) crlObj).getEncoded();
+ log(ILogger.LL_INFO, "publish CRL: " + dn);
+
+ /* search for attribute names to determine existence of attributes */
+ LDAPSearchResults res = null;
+ if (mCrlAttr.equals(LDAP_CRL_ATTR)) {
+ res = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CACERT_ATTR, LDAP_ARL_ATTR }, true);
+ } else {
+ res = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CRL_ATTR, LDAP_CACERT_ATTR, LDAP_ARL_ATTR }, true);
+ }
+
+ LDAPEntry entry = res.next();
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
+ LDAPAttribute certs = entry.getAttribute(LDAP_CACERT_ATTR);
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+
+ /* get object class values */
+ LDAPSearchResults res1 = null;
+ res1 = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass" }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ String[] oclist = mCrlObjectClass.split(",");
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (!hasoc) {
+ log(ILogger.LL_INFO, "adding CRL objectclass " + oc + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute("objectclass", oc));
+
+ if ((!attrsAdded) && oc.equalsIgnoreCase("certificationAuthority")) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (certs == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CACERT_ATTR, ""));
+
+ if ((crls == null) && (!mCrlAttr.equals(LDAP_CRL_ATTR)))
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ attrsAdded = true;
+ }
+ }
+ }
+
+ modSet.add(LDAPModification.REPLACE, new LDAPAttribute(mCrlAttr, crlEnc));
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CRL objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("crlObjectClassAdded", "");
+ mConfig.putString("crlObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
+
+ conn.modify(dn, modSet);
+ } catch (CRLException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CRL_ERROR", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CRL_ERROR", e.toString()));
+ }
+ } finally {
+ if (altConn != null) {
+ try {
+ altConn.disconnect();
+ } catch (LDAPException e) {
+ // safely ignored
+ }
+ }
+ }
+
+ }
+
+ /**
+ * There shouldn't be a need to call this.
+ * CRLs are always replaced but this is implemented anyway in case
+ * there is ever a reason to remove a global CRL.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object crlObj)
+ throws ELdapException {
+ try {
+ byte[] crlEnc = ((X509CRL) crlObj).getEncoded();
+
+ try {
+ mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass", LDAP_CRL_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+
+ LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mCrlAttr, "objectclass" }, false);
+ LDAPEntry e = res.next();
+ LDAPAttribute crls = e.getAttribute(mCrlAttr);
+ LDAPAttribute ocs = e.getAttribute("objectclass");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ boolean hasOC = false;
+ boolean hasCRL =
+ LdapUserCertPublisher.ByteValueExists(crls, crlEnc);
+
+ if (hasCRL) {
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(mCrlAttr, crlEnc));
+ }
+
+ String[] oclist = mCrlObjectClass.split(",");
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ if (LdapUserCertPublisher.StringValueExists(ocs, oc)) {
+ log(ILogger.LL_INFO, "unpublish: deleting CRL object class " + oc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectClass", oc));
+ hasOC = true;
+ }
+ }
+
+ if (hasCRL || hasOC) {
+ conn.modify(dn, modSet);
+ } else {
+ log(ILogger.LL_INFO,
+ "unpublish: " + dn + " already has not CRL");
+ }
+ } catch (CRLException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CRL_ERROR", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_CRL_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapCrlPublisher: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java
new file mode 100644
index 000000000..543088ecb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java
@@ -0,0 +1,342 @@
+// --- 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.publish.publishers;
+
+
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+
+
+/**
+ * Interface for mapping a X509 certificate to a LDAP entry
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapEncryptCertPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ public static final String LDAP_USERCERT_ATTR = "userCertificate;binary";
+ public static final String PROP_REVOKE_CERT = "revokeCert";
+
+ protected String mCertAttr = LDAP_USERCERT_ATTR;
+ private ILogger mLogger = CMS.getLogger();
+ private IConfigStore mConfig = null;
+ private boolean mInited = false;
+ private boolean mRevokeCert;
+
+ public LdapEncryptCertPublisher() {
+ }
+
+ public String getImplName() {
+ return "LdapEncryptCertPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapEncryptCertPublisher";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "certAttr;string;LDAP attribute in which to store the certificate",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-usercertpublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin knows how to publish user certificates"
+ };
+
+ return params;
+
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCertAttr = mConfig.getString("certAttr", LDAP_USERCERT_ATTR);
+ mRevokeCert = mConfig.getBoolean(PROP_REVOKE_CERT, true);
+ mInited = true;
+ }
+
+ public LdapEncryptCertPublisher(String certAttr) {
+ mCertAttr = certAttr;
+ }
+
+ /**
+ * publish a user certificate
+ * Adds the cert to the multi-valued certificate attribute as a
+ * DER encoded binary blob. Does not check if cert already exists.
+ *
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the certificate
+ * @param certObj the certificate object.
+ */
+ public void publish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (conn == null)
+ return;
+
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ log(ILogger.LL_INFO, "Publishing " + cert);
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ // check if cert already exists.
+ LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mCertAttr }, false);
+ LDAPEntry entry = res.next();
+ LDAPAttribute attr = getModificationAttribute(entry.getAttribute(mCertAttr), certEnc);
+
+ if (attr == null) {
+ log(ILogger.LL_INFO, "publish: " + dn + " already has cert.");
+ return;
+ }
+
+ // publish
+ LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
+
+ conn.modify(dn, mod);
+ } catch (CertificateEncodingException e) {
+ CMS.debug("LdapEncryptCertPublisher: error in publish: " + e.toString());
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ /**
+ * unpublish a user certificate
+ * deletes the certificate from the list of certificates.
+ * does not check if certificate is already there.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ // check if cert already deleted.
+ LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mCertAttr }, false);
+ LDAPEntry entry = res.next();
+
+ if (!ByteValueExists(entry.getAttribute(mCertAttr), certEnc)) {
+ log(ILogger.LL_INFO, dn + " already has not cert");
+ return;
+ }
+
+ LDAPModification mod = new LDAPModification(LDAPModification.DELETE,
+ new LDAPAttribute(mCertAttr, certEnc));
+
+ conn.modify(dn, mod);
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapUserCertPublisher: " + msg);
+ }
+
+ public LDAPAttribute getModificationAttribute(
+ LDAPAttribute attr, byte[] bval) {
+
+ LDAPAttribute at = new LDAPAttribute(attr.getName(), bval);
+ if (at == null) {
+ return at;
+ }
+
+ // determine if the given cert is a signing or an encryption
+ // certificate
+ X509CertImpl thisCert = null;
+
+ try {
+ thisCert = new X509CertImpl(bval);
+ } catch (Exception e) {
+ }
+ if (thisCert == null) {
+ return at;
+ }
+
+ Enumeration vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ try {
+ X509CertImpl cert = new X509CertImpl(val);
+
+ log(ILogger.LL_INFO, "Checking " + cert);
+ if (CMS.isEncryptionCert(thisCert) &&
+ CMS.isEncryptionCert(cert)) {
+ // skip
+ log(ILogger.LL_INFO, "SKIP ENCRYPTION " + cert);
+ revokeCert(cert);
+ } else if (CMS.isSigningCert(thisCert) &&
+ CMS.isSigningCert(cert)) {
+ // skip
+ log(ILogger.LL_INFO, "SKIP SIGNING " + cert);
+ revokeCert(cert);
+ } else {
+ at.addValue(val);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CHECK_FAILED", e.toString()));
+ }
+ }
+ return at;
+ }
+
+ private RevokedCertImpl formCRLEntry(
+ BigInteger serialNo, RevocationReason reason)
+ throws EBaseException {
+ CRLReasonExtension reasonExt = new CRLReasonExtension(reason);
+ CRLExtensions crlentryexts = new CRLExtensions();
+
+ try {
+ crlentryexts.set(CRLReasonExtension.NAME, reasonExt);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_SET_CRL_REASON", reason.toString(), e.toString()));
+
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_INTERNAL_ERROR", e.toString()));
+ }
+ RevokedCertImpl crlentry =
+ new RevokedCertImpl(serialNo, new Date(), crlentryexts);
+
+ return crlentry;
+ }
+
+ private void revokeCert(X509CertImpl cert)
+ throws EBaseException {
+ try {
+ if (mConfig.getBoolean(PROP_REVOKE_CERT, true) == false) {
+ return;
+ }
+ } catch (EBaseException e) {
+ return;
+ }
+ BigInteger serialNum = cert.getSerialNumber();
+ // need to revoke certificate also
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ ICAService service = (ICAService) ca.getCAService();
+ RevokedCertImpl crlEntry = formCRLEntry(
+ serialNum, RevocationReason.KEY_COMPROMISE);
+
+ service.revokeCert(crlEntry);
+ }
+
+ /**
+ * checks if a byte attribute has a certain value.
+ */
+ public static boolean ByteValueExists(LDAPAttribute attr, byte[] bval) {
+ if (attr == null) {
+ return false;
+ }
+ Enumeration vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ if (Utils.byteArraysAreEqual(val, bval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * checks if a attribute has a string value.
+ */
+ public static boolean StringValueExists(LDAPAttribute attr, String sval) {
+ if (attr == null) {
+ return false;
+ }
+ Enumeration vals = attr.getStringValues();
+ String val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (String) vals.nextElement();
+ if (val.equalsIgnoreCase(sval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java
new file mode 100644
index 000000000..fbc5cf6d1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java
@@ -0,0 +1,315 @@
+// --- 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.publish.publishers;
+
+
+import netscape.ldap.*;
+import java.security.cert.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Interface for mapping a X509 certificate to a LDAP entry
+ *
+ * @version $Revision$, $Date$
+ */
+public class LdapUserCertPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ public static final String LDAP_USERCERT_ATTR = "userCertificate;binary";
+
+ protected String mCertAttr = LDAP_USERCERT_ATTR;
+ private ILogger mLogger = CMS.getLogger();
+ private IConfigStore mConfig = null;
+ private boolean mInited = false;
+
+ public LdapUserCertPublisher() {
+ }
+
+ public String getImplName() {
+ return "LdapUserCertPublisher";
+ }
+
+ public String getDescription() {
+ return "LdapUserCertPublisher";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ "certAttr;string;LDAP attribute in which to store the certificate",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-usercertpublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This plugin knows how to publish user certificates"
+ };
+
+ return params;
+
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+ mConfig = config;
+ mCertAttr = mConfig.getString("certAttr", LDAP_USERCERT_ATTR);
+ mInited = true;
+ }
+
+ public LdapUserCertPublisher(String certAttr) {
+ mCertAttr = certAttr;
+ }
+
+ /**
+ * publish a user certificate
+ * Adds the cert to the multi-valued certificate attribute as a
+ * DER encoded binary blob. Does not check if cert already exists.
+ *
+ * @param conn the LDAP connection
+ * @param dn dn of the entry to publish the certificate
+ * @param certObj the certificate object.
+ */
+ public void publish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+ if (conn == null)
+ return;
+
+ // Bugscape #56124 - support multiple publishing directory
+ // see if we should create local connection
+ LDAPConnection altConn = null;
+ try {
+ String host = mConfig.getString("host", null);
+ String port = mConfig.getString("port", null);
+ if (host != null && port != null) {
+ int portVal = Integer.parseInt(port);
+ int version = Integer.parseInt(mConfig.getString("version", "2"));
+ String cert_nick = mConfig.getString("clientCertNickname", null);
+ LDAPSSLSocketFactoryExt sslSocket = null;
+ if (cert_nick != null) {
+ sslSocket = CMS.getLdapJssSSLSocketFactory(cert_nick);
+ }
+ String mgr_dn = mConfig.getString("bindDN", null);
+ String mgr_pwd = mConfig.getString("bindPWD", null);
+
+ altConn = CMS.getBoundConnection(host, portVal,
+ version,
+ sslSocket, mgr_dn, mgr_pwd);
+ conn = altConn;
+ }
+ } catch (LDAPException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ } catch (EBaseException e) {
+ CMS.debug("Failed to create alt connection " + e);
+ }
+
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ boolean deleteCert = false;
+ try {
+ deleteCert = mConfig.getBoolean("deleteCert", false);
+ } catch (Exception e) {
+ }
+
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ // check if cert already exists.
+ LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mCertAttr }, false);
+ LDAPEntry entry = res.next();
+
+ if (ByteValueExists(entry.getAttribute(mCertAttr), certEnc)) {
+ log(ILogger.LL_INFO, "publish: " + dn + " already has cert.");
+ return;
+ }
+
+ // publish
+ LDAPModification mod = null;
+ if (deleteCert) {
+ mod = new LDAPModification(LDAPModification.REPLACE,
+ new LDAPAttribute(mCertAttr, certEnc));
+ } else {
+ mod = new LDAPModification(LDAPModification.ADD,
+ new LDAPAttribute(mCertAttr, certEnc));
+ }
+
+ conn.modify(dn, mod);
+
+ // log a successful message to the "transactions" log
+ mLogger.log( ILogger.EV_AUDIT,
+ ILogger.S_LDAP,
+ ILogger.LL_INFO,
+ AuditFormat.LDAP_PUBLISHED_FORMAT,
+ new Object[] { "LdapUserCertPublisher",
+ cert.getSerialNumber().toString(16),
+ cert.getSubjectDN() } );
+ } catch (CertificateEncodingException e) {
+ CMS.debug("LdapUserCertPublisher: error in publish: " + e.toString());
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ } finally {
+ if (altConn != null) {
+ try {
+ altConn.disconnect();
+ } catch (LDAPException e) {
+ // safely ignored
+ }
+ }
+ }
+ return;
+ }
+
+ /**
+ * unpublish a user certificate
+ * deletes the certificate from the list of certificates.
+ * does not check if certificate is already there.
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object certObj)
+ throws ELdapException {
+
+ boolean disableUnpublish = false;
+ try {
+ disableUnpublish = mConfig.getBoolean("disableUnpublish", false);
+ } catch (Exception e) {
+ }
+
+ if (disableUnpublish) {
+ CMS.debug("UserCertPublisher: disable unpublish");
+ return;
+ }
+
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ X509Certificate cert = (X509Certificate) certObj;
+
+ try {
+ byte[] certEnc = cert.getEncoded();
+
+ // check if cert already deleted.
+ LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
+ "(objectclass=*)", new String[] { mCertAttr }, false);
+ LDAPEntry entry = res.next();
+
+ if (!ByteValueExists(entry.getAttribute(mCertAttr), certEnc)) {
+ log(ILogger.LL_INFO, dn + " already has not cert");
+ return;
+ }
+
+ LDAPModification mod = new LDAPModification(LDAPModification.DELETE,
+ new LDAPAttribute(mCertAttr, certEnc));
+
+ conn.modify(dn, mod);
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("PUBLISH_NO_LDAP_SERVER"));
+ throw new ELdapServerDownException(CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE", conn.getHost(), "" + conn.getPort()));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR"));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_USERCERT_ERROR", e.toString()));
+ }
+ }
+ return;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "LdapUserCertPublisher: " + msg);
+ }
+
+ /**
+ * checks if a byte attribute has a certain value.
+ */
+ public static boolean ByteValueExists(LDAPAttribute attr, byte[] bval) {
+ if (attr == null) {
+ return false;
+ }
+ Enumeration vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ if (val.length == 0)
+ continue;
+ if (Utils.byteArraysAreEqual(val, bval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * checks if a attribute has a string value.
+ */
+ public static boolean StringValueExists(LDAPAttribute attr, String sval) {
+ if (attr == null) {
+ return false;
+ }
+ Enumeration vals = attr.getStringValues();
+ String val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (String) vals.nextElement();
+ if (val.equalsIgnoreCase(sval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
new file mode 100644
index 000000000..846ea7c48
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
@@ -0,0 +1,351 @@
+// --- 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.publish.publishers;
+
+
+import java.net.*;
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.cmsutil.http.*;
+
+
+/**
+ * This publisher writes certificate and CRL into
+ * a directory.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSPPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ private static final String PROP_HOST = "host";
+ private static final String PROP_PORT = "port";
+ private static final String PROP_PATH = "path";
+ private static final String PROP_NICK = "nickName";
+ private static final String PROP_CLIENT_AUTH_ENABLE = "enableClientAuth";
+
+ private IConfigStore mConfig = null;
+ private String mHost = null;
+ private String mPort = null;
+ private String mPath = null;
+ private String mNickname = null;
+ private boolean mClientAuthEnabled = true;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName() {
+ return "OCSPPublisher";
+ }
+
+ /**
+ * Returns the description of the ldap publisher.
+ */
+ public String getDescription() {
+ return "This publisher writes the CRL to CMS's OCSP server.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_HOST + ";string;Host of CMS's OCSP Secure agent service",
+ PROP_PORT + ";string;Port of CMS's OCSP Secure agent service",
+ PROP_PATH + ";string;URI of CMS's OCSP Secure agent service",
+ PROP_NICK + ";string;Nickname of cert used for client authentication",
+ PROP_CLIENT_AUTH_ENABLE + ";boolean;Client Authentication enabled",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-ocsppublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Publishes CRLs to a Online Certificate Status Manager, an OCSP responder provided by CMS."
+ };
+
+ return params;
+ }
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ String host = "";
+ String port = "";
+ String path = "";
+ String nickname = "";
+ String clientAuthEnabled = "";
+
+ try {
+ host = mConfig.getString(PROP_HOST);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_HOST + "=" + host);
+ try {
+ port = mConfig.getString(PROP_PORT);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_PORT + "=" + port);
+ try {
+ path = mConfig.getString(PROP_PATH);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_PATH + "=" + path);
+ try {
+ nickname = mConfig.getString(PROP_NICK);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_NICK + "=" + nickname);
+ try {
+ clientAuthEnabled = mConfig.getString(PROP_CLIENT_AUTH_ENABLE);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_CLIENT_AUTH_ENABLE + "=" + clientAuthEnabled);
+ return v;
+ }
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ IConfigStore config = CMS.getConfigStore();
+ String nickname = "";
+ // get subsystem cert nickname as default for client auth
+ try {
+ nickname = config.getString("ca.subsystem.nickname", "");
+ String tokenname = config.getString("ca.subsystem.tokenname", "");
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ } catch (Exception e) {
+ }
+
+
+ v.addElement(PROP_HOST + "=");
+ v.addElement(PROP_PORT + "=");
+ v.addElement(PROP_PATH + "=/ocsp/agent/ocsp/addCRL");
+ v.addElement(PROP_CLIENT_AUTH_ENABLE + "=true");
+ v.addElement(PROP_NICK + "=" + nickname);
+ return v;
+ }
+
+ /**
+ * Initializes this plugin.
+ */
+ public void init(IConfigStore config) {
+ mConfig = config;
+ try {
+ mHost = mConfig.getString(PROP_HOST, "");
+ mPort = mConfig.getString(PROP_PORT, "");
+ mPath = mConfig.getString(PROP_PATH, "");
+ mNickname = mConfig.getString(PROP_NICK, "");
+ mClientAuthEnabled = mConfig.getBoolean(PROP_CLIENT_AUTH_ENABLE, true);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ protected Socket Connect(String host, boolean secure, JssSSLSocketFactory factory)
+ {
+ Socket socket = null;
+ StringTokenizer st = new StringTokenizer(host, " ");
+ while (st.hasMoreTokens()) {
+ String hp = st.nextToken(); // host:port
+ StringTokenizer st1 = new StringTokenizer(hp, ":");
+ String h = st1.nextToken();
+ int p = Integer.parseInt(st1.nextToken());
+ try {
+ if (secure) {
+ socket = factory.makeSocket(h, p);
+ } else {
+ socket = new Socket(h, p);
+ }
+ return socket;
+ } catch (Exception e) {
+ }
+ try {
+ Thread.sleep(5000); // 5 seconds delay
+ } catch (Exception e) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Publishs a object to the ldap directory.
+ *
+ * @param conn a Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to publish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to publish
+ * (java.security.cert.X509Certificate or,
+ * java.security.cert.X509CRL)
+ */
+ public synchronized void publish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ try {
+ if (!(object instanceof X509CRL))
+ return;
+ X509CRL crl = (X509CRL) object;
+
+ // talk to agent port of CMS
+
+ // open the connection and prepare it to POST
+ boolean secure = true;
+
+ String host = mHost;
+ int port = Integer.parseInt(mPort);
+ String path = mPath;
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: " +
+ "Host='" + host + "' Port='" + port +
+ "' URL='" + path + "'");
+ CMS.debug("OCSPPublisher: " +
+ "Host='" + host + "' Port='" + port +
+ "' URL='" + path + "'");
+
+ StringBuffer query = new StringBuffer();
+ query.append("crl=");
+ query.append(URLEncoder.encode("-----BEGIN CERTIFICATE REVOCATION LIST-----\n"));
+ query.append(URLEncoder.encode(CMS.BtoA(crl.getEncoded())));
+ query.append(URLEncoder.encode("\n-----END CERTIFICATE REVOCATION LIST-----"));
+ query.append("&noui=true");
+
+ Socket socket = null;
+ JssSSLSocketFactory factory;
+
+ if (mClientAuthEnabled) {
+ factory = new JssSSLSocketFactory(mNickname);
+ } else {
+ factory = new JssSSLSocketFactory();
+ }
+
+ if (mHost != null && mHost.indexOf(' ') != -1) {
+ // support failover hosts configuration
+ // host parameter can be
+ // "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
+ do {
+ socket = Connect(mHost, secure, factory);
+ } while (socket == null);
+ } else {
+ if (secure) {
+ socket = factory.makeSocket(host, port);
+ } else {
+ socket = new Socket(host, port);
+ }
+ }
+
+ if( socket == null ) {
+ CMS.debug( "OCSPPublisher::publish() - socket is null!" );
+ throw new ELdapException( "socket is null" );
+ }
+
+ // use HttpRequest and POST
+ HttpRequest httpReq = new HttpRequest();
+
+ httpReq.setMethod("POST");
+ httpReq.setURI(path);
+ httpReq.setHeader("Connection", "Keep-Alive");
+
+ httpReq.setHeader("Content-Type",
+ "application/x-www-form-urlencoded");
+ httpReq.setHeader("Content-Transfer-Encoding", "7bit");
+
+ httpReq.setHeader("Content-Length",
+ Integer.toString(query.length()));
+ httpReq.setContent(query.toString());
+ OutputStream os = socket.getOutputStream();
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, "UTF8");
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: start sending CRL");
+ long startTime = CMS.getCurrentDate().getTime();
+ CMS.debug("OCSPPublisher: start CRL sending startTime=" + startTime);
+ httpReq.write(outputStreamWriter);
+ long endTime = CMS.getCurrentDate().getTime();
+ CMS.debug("OCSPPublisher: done CRL sending endTime=" + endTime + " diff=" + (endTime - startTime));
+
+ // Read the response
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: start getting response");
+ DataInputStream dis = new DataInputStream(socket.getInputStream());
+ String nextline;
+ String line = "";
+ String error = "";
+ boolean status = false;
+
+ while ((nextline = dis.readLine()) != null) {
+ if (nextline.startsWith("status=")) {
+ if (nextline.substring(7, nextline.length()).equals("0")) {
+ status = true;
+ }
+ }
+ if (nextline.startsWith("error=")) {
+ error = nextline.substring(6, nextline.length());
+ }
+ }
+ dis.close();
+ if (status) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: successful");
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: failed - " + error);
+ }
+
+ } catch (IOException e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ } catch (CRLException e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ } catch (Exception e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Unpublishs a object to the ldap directory.
+ *
+ * @param conn the Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to unpublish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to unpublish
+ * (java.security.cert.X509Certificate)
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ // NOT USED
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/Utils.java b/pki/base/common/src/com/netscape/cms/publish/publishers/Utils.java
new file mode 100644
index 000000000..358a762b3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/Utils.java
@@ -0,0 +1,131 @@
+// --- 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.publish.publishers;
+
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+
+/**
+ * Publisher utility class.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Utils {
+ public static void checkHost(String hostname) throws UnknownHostException {
+ InetAddress addr = InetAddress.getByName(hostname);
+ }
+
+ public static void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buf = new byte[4096];
+ int len;
+
+ while ((len = in.read(buf)) != -1) {
+ out.write(buf, 0, len);
+ }
+ }
+
+ public static void copyStream(BufferedReader in, OutputStreamWriter out) throws IOException {
+ char[] buf = new char[4096];
+ int len;
+
+ while ((len = in.read(buf)) != -1) {
+ out.write(buf, 0, len);
+ }
+ }
+
+ /// Sorts an array of Strings.
+ // Java currently has no general sort function. Sorting Strings is
+ // common enough that it's worth making a special case.
+ public static void sortStrings(String[] strings) {
+ // Just does a bubblesort.
+ for (int i = 0; i < strings.length - 1; ++i) {
+ for (int j = i + 1; j < strings.length; ++j) {
+ if (strings[i].compareTo(strings[j]) > 0) {
+ String t = strings[i];
+
+ strings[i] = strings[j];
+ strings[j] = t;
+ }
+ }
+ }
+ }
+
+ /// Returns a date string formatted in Unix ls style - if it's within
+ // six months of now, Mmm dd hh:ss, else Mmm dd yyyy.
+ public static String lsDateStr(Date date) {
+ long dateTime = date.getTime();
+
+ if (dateTime == -1L)
+ return "------------";
+ long nowTime = System.currentTimeMillis();
+ SimpleDateFormat formatter = new SimpleDateFormat();
+
+ if (Math.abs(nowTime - dateTime) < 183L * 24L * 60L * 60L * 1000L)
+ formatter.applyPattern("MMM dd hh:ss");
+ else
+ formatter.applyPattern("MMM dd yyyy");
+ return formatter.format(date);
+ }
+
+ /**
+ * compares contents two byte arrays returning true if exactly same.
+ */
+ static public boolean byteArraysAreEqual(byte[] a, byte[] b) {
+ if (a.length != b.length)
+ return false;
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * strips out double quotes around String parameter
+ * @param s the string potentially bracketed with double quotes
+ * @return string stripped of surrounding double quotes
+ */
+ public static String stripQuotes(String s) {
+ if (s == null) {
+ return s;
+ }
+
+ if ((s.startsWith("\"")) && (s.endsWith("\""))) {
+ return (s.substring(1, (s.length() - 1)));
+ }
+
+ return s;
+ }
+
+ /**
+ * returns an array of strings from a vector of Strings
+ * there'll be trouble if the Vector contains something other
+ * than just Strings
+ */
+ public static String[] getStringArrayFromVector(Vector v) {
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ return s;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/request/RequestScheduler.java b/pki/base/common/src/com/netscape/cms/request/RequestScheduler.java
new file mode 100644
index 000000000..36bb5cd2a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/request/RequestScheduler.java
@@ -0,0 +1,88 @@
+// --- 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.request;
+
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.math.BigInteger;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.EBaseException;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestScheduler;
+
+
+/**
+ * This class represents a request scheduler that prioritizes
+ * the threads based on the request processing order.
+ * The request that enters the request queue first should
+ * be processed first.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RequestScheduler implements IRequestScheduler {
+ private Vector mRequestThreads = new Vector();
+
+ /**
+ * Request entered the request queue processing.
+ *
+ * @param r request
+ */
+ public synchronized void requestIn(IRequest r) {
+ Thread current = Thread.currentThread();
+
+ if (mRequestThreads.size() == 0) {
+ current.setPriority(Thread.MAX_PRIORITY);
+ }
+ mRequestThreads.addElement(current);
+ }
+
+ /**
+ * Request exited the request queue processing.
+ *
+ * @param r request
+ */
+ public synchronized void requestOut(IRequest r) {
+ Thread current = Thread.currentThread();
+ Thread first = (Thread) mRequestThreads.elementAt(0);
+
+ if (current.equals(first)) {
+ // reprioritize
+ try {
+ Thread second = (Thread) mRequestThreads.elementAt(1);
+
+ second.setPriority(Thread.MAX_PRIORITY);
+ } catch (Exception e) {
+ // no second element; nothing to do
+ }
+ }
+ mRequestThreads.removeElement(current);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ASelfTest.java b/pki/base/common/src/com/netscape/cms/selftests/ASelfTest.java
new file mode 100644
index 000000000..d2b54c3b8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ASelfTest.java
@@ -0,0 +1,194 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import java.util.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements an individual self test.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public abstract class ASelfTest
+ implements ISelfTest {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ //////////////////////////
+ // ISelfTest parameters //
+ //////////////////////////
+
+ // parameter information
+ private static final String SELF_TEST_NAME = "ASelfTest";
+
+ // variables associated with this specific object
+ protected ISelfTestSubsystem mSelfTestSubsystem = null;
+ protected String mInstanceName = null;
+ protected IConfigStore mConfig = null;
+ protected String mPrefix = null;
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ///////////////////////
+ // ISelfTest methods //
+ ///////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest(ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters)
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException {
+ // store individual self test class values for this instance
+ mSelfTestSubsystem = (ISelfTestSubsystem) subsystem;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_PARAMETER_WAS_NULL",
+ SELF_TEST_NAME));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // store additional individual self test class values for this instance
+ mInstanceName = instanceName;
+
+ // compose self test plugin parameter property prefix
+ String pluginPath = PROP_PLUGIN + "." + instanceName;
+
+ mConfig = parameters.getSubStore(pluginPath);
+
+ if ((mConfig != null) &&
+ (mConfig.getName() != null) &&
+ (mConfig.getName() != "")) {
+ mPrefix = mConfig.getName().trim();
+ } else {
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_PARAMETER_WAS_NULL",
+ SELF_TEST_NAME));
+
+ throw new EMissingSelfTestException();
+ }
+
+ return;
+ }
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public abstract void startupSelfTest()
+ throws ESelfTestException;
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public abstract void shutdownSelfTest();
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public abstract String getSelfTestDescription(Locale locale);
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public abstract void runSelfTest(ILogEventListener logger)
+ throws ESelfTestException;
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java b/pki/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java
new file mode 100644
index 000000000..19fb71cff
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java
@@ -0,0 +1,279 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.ca;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.security.x509.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check for CA presence.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CAPresence
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////
+ // CAPresence parameters //
+ ///////////////////////////
+
+ // parameter information
+ public static final String PROP_CA_SUB_ID = "CaSubId";
+ private String mCaSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////
+ // CAPresence methods //
+ ////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mCaSubId = mConfig.getString( PROP_CA_SUB_ID );
+ if( mCaSubId != null ) {
+ mCaSubId = mCaSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_CA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_CA_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_CA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_CA_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_CA_PRESENCE_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ ICertificateAuthority ca = null;
+ X509CertImpl caCert = null;
+ X509Key caPubKey = null;
+
+ ca = ( ICertificateAuthority ) CMS.getSubsystem( mCaSubId );
+
+ if( ca == null ) {
+ // log that the CA is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the CA certificate
+ caCert = ca.getCACert();
+
+ if( caCert == null ) {
+ // log that the CA is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_CA_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the CA certificate public key
+ try {
+ caPubKey = ( X509Key ) caCert.get( X509CertImpl.PUBLIC_KEY );
+
+ if( caPubKey == null ) {
+ // log that something is seriously wrong with the CA
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_CORRUPT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+ } catch( CertificateParsingException e ) {
+ // log that something is seriously wrong with the CA
+ mSelfTestSubsystem.log( logger,
+ e.toString() );
+
+ throw new ESelfTestException( e.toString() );
+ }
+
+ // log that the CA is present
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java b/pki/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java
new file mode 100644
index 000000000..ec8651059
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java
@@ -0,0 +1,279 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.ca;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.security.x509.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check the validity of the CA.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CAValidity
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////
+ // CAValidity parameters //
+ ///////////////////////////
+
+ // parameter information
+ public static final String PROP_CA_SUB_ID = "CaSubId";
+ private String mCaSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////
+ // CAValidity methods //
+ ////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mCaSubId = mConfig.getString( PROP_CA_SUB_ID );
+ if( mCaSubId != null ) {
+ mCaSubId = mCaSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_CA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_CA_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_CA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_CA_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_CA_VALIDITY_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ ICertificateAuthority ca = null;
+ X509CertImpl caCert = null;
+
+ ca = ( ICertificateAuthority ) CMS.getSubsystem( mCaSubId );
+
+ if( ca == null ) {
+ // log that the CA is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the CA certificate
+ caCert = ca.getCACert();
+
+ if( caCert == null ) {
+ // log that the CA is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_CA_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the CA validity period
+ try {
+ caCert.checkValidity();
+ } catch( CertificateNotYetValidException e ) {
+ // log that the CA is not yet valid
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_NOT_YET_VALID",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } catch( CertificateExpiredException e ) {
+ // log that the CA is expired
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_EXPIRED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // log that the CA is valid
+ logMessage = CMS.getLogMessage( "SELFTESTS_CA_IS_VALID",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java b/pki/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
new file mode 100644
index 000000000..5338cfff8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
@@ -0,0 +1,235 @@
+// --- 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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+// package statement //
+///////////////////////
+
+package com.netscape.cms.selftests.common;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.security.x509.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check the system certs
+ * of the subsystem
+ * <P>
+ *
+ * @version $Revision: $, $Date: $
+ */
+public class SystemCertsVerification
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////
+ // SystemCertsVerification parameters //
+ ///////////////////////////
+
+ // parameter information
+ public static final String PROP_SUB_ID = "SubId";
+ private String mSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////
+ // SystemCertsVerification methods //
+ ////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mSubId = mConfig.getString( PROP_SUB_ID );
+ if( mSubId != null ) {
+ mSubId = mSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_SYSTEM_CERTS_VERIFICATION_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ boolean rc = false;
+
+ rc = CMS.verifySystemCerts();
+ if (rc == true) {
+ logMessage = CMS.getLogMessage( "SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_SUCCESS",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ } else {
+ logMessage = CMS.getLogMessage( "SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_FAILURE",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ throw new ESelfTestException( logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java b/pki/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java
new file mode 100644
index 000000000..2cf481dde
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java
@@ -0,0 +1,270 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.kra;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.*;
+import java.util.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check for KRA presence.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KRAPresence
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////
+ // KRAPresence parameters //
+ ///////////////////////////
+
+ // parameter information
+ public static final String PROP_KRA_SUB_ID = "SubId";
+ private String mSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////
+ // KRAPresence methods //
+ ////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mSubId = mConfig.getString( PROP_KRA_SUB_ID );
+ if( mSubId != null ) {
+ mSubId = mSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_KRA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_KRA_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_KRA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_KRA_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_KRA_PRESENCE_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ IKeyRecoveryAuthority kra = null;
+ org.mozilla.jss.crypto.X509Certificate kraCert = null;
+ PublicKey kraPubKey = null;
+
+ kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( mSubId );
+
+ if( kra == null ) {
+ // log that the KRA is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_KRA_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the KRA certificate
+ kraCert = kra.getTransportCert();
+
+ if( kraCert == null ) {
+ // log that the RA is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_KRA_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the KRA certificate public key
+ kraPubKey = ( PublicKey ) kraCert.getPublicKey();
+
+ if( kraPubKey == null ) {
+ // log that something is seriously wrong with the KRA
+ logMessage = CMS.getLogMessage( "SELFTESTS_KRA_IS_CORRUPT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // log that the KRA is present
+ logMessage = CMS.getLogMessage( "SELFTESTS_KRA_IS_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java b/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
new file mode 100644
index 000000000..a05294a8e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
@@ -0,0 +1,297 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.ocsp;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.security.x509.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check for OCSP presence.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class OCSPPresence
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ /////////////////////////////
+ // OCSPPresence parameters //
+ /////////////////////////////
+
+ // parameter information
+ public static final String PROP_OCSP_SUB_ID = "OcspSubId";
+ private String mOcspSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ //////////////////////////
+ // OCSPPresence methods //
+ //////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mOcspSubId = mConfig.getString( PROP_OCSP_SUB_ID );
+ if( mOcspSubId != null ) {
+ mOcspSubId = mOcspSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_OCSP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_OCSP_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_OCSP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_OCSP_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_OCSP_PRESENCE_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ IOCSPAuthority ocsp = null;
+ ISigningUnit ocspSigningUnit = null;
+ X509CertImpl ocspCert = null;
+ X509Key ocspPubKey = null;
+
+ ocsp = ( IOCSPAuthority ) CMS.getSubsystem( mOcspSubId );
+
+ if( ocsp == null ) {
+ // log that the OCSP is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the OCSP signing unit
+ ocspSigningUnit = ocsp.getSigningUnit();
+
+ if( ocspSigningUnit == null ) {
+ // log that the OCSP is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the OCSP certificate
+ ocspCert = ocspSigningUnit.getCertImpl();
+
+ if( ocspCert == null ) {
+ // log that the OCSP is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the OCSP certificate public key
+ try {
+ ocspPubKey = ( X509Key )
+ ocspCert.get( X509CertImpl.PUBLIC_KEY );
+
+ if( ocspPubKey == null ) {
+ // log that something is seriously wrong with the OCSP
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_CORRUPT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+ } catch( CertificateParsingException e ) {
+ // log that something is seriously wrong with the OCSP
+ mSelfTestSubsystem.log( logger,
+ e.toString() );
+
+ throw new ESelfTestException( e.toString() );
+ }
+
+ // log that the OCSP is present
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java b/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
new file mode 100644
index 000000000..2bfe9ffd9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
@@ -0,0 +1,297 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.ocsp;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.security.x509.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check the validity of the OCSP.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class OCSPValidity
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ /////////////////////////////
+ // OCSPValidity parameters //
+ /////////////////////////////
+
+ // parameter information
+ public static final String PROP_OCSP_SUB_ID = "OcspSubId";
+ private String mOcspSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ //////////////////////////
+ // OCSPValidity methods //
+ //////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mOcspSubId = mConfig.getString( PROP_OCSP_SUB_ID );
+ if( mOcspSubId != null ) {
+ mOcspSubId = mOcspSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_OCSP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_OCSP_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_OCSP_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_OCSP_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_OCSP_VALIDITY_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ IOCSPAuthority ocsp = null;
+ ISigningUnit ocspSigningUnit = null;
+ X509CertImpl ocspCert = null;
+
+ ocsp = ( IOCSPAuthority ) CMS.getSubsystem( mOcspSubId );
+
+ if( ocsp == null ) {
+ // log that the OCSP is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the OCSP signing unit
+ ocspSigningUnit = ocsp.getSigningUnit();
+
+ if( ocspSigningUnit == null ) {
+ // log that the OCSP is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the OCSP certificate
+ ocspCert = ocspSigningUnit.getCertImpl();
+
+ if( ocspCert == null ) {
+ // log that the OCSP is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the OCSP validity period
+ try {
+ ocspCert.checkValidity();
+ } catch( CertificateNotYetValidException e ) {
+ // log that the OCSP is not yet valid
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_OCSP_IS_NOT_YET_VALID",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } catch( CertificateExpiredException e ) {
+ // log that the OCSP is expired
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_EXPIRED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // log that the OCSP is valid
+ logMessage = CMS.getLogMessage( "SELFTESTS_OCSP_IS_VALID",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java b/pki/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java
new file mode 100644
index 000000000..f87c07128
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java
@@ -0,0 +1,279 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.ra;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.security.*;
+import java.util.*;
+
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check for RA presence.
+ * <P>
+ * <PRE>
+ * NOTE: This self-test is for Registration Authorities prior to
+ * Netscape Certificate Management System 7.0. It does NOT
+ * apply to the Registration Authority found in
+ * Red Hat Certificate System 7.3 or later (including
+ * ALL versions of Dogtag Certificate System).
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RAPresence
+extends ASelfTest
+{
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////////
+ // RAPresence parameters //
+ ///////////////////////////
+
+ // parameter information
+ public static final String PROP_RA_SUB_ID = "RaSubId";
+ private String mRaSubId = null;
+
+
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////////
+ // RAPresence methods //
+ ////////////////////////
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest( ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters )
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ // retrieve mandatory parameter(s)
+ try {
+ mRaSubId = mConfig.getString( PROP_RA_SUB_ID );
+ if( mRaSubId != null ) {
+ mRaSubId = mRaSubId.trim();
+ } else {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_VALUES",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_RA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( PROP_RA_SUB_ID );
+ }
+ } catch( EBaseException e ) {
+ mSelfTestSubsystem.log( mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage(
+ "SELFTESTS_MISSING_NAME",
+ getSelfTestName(),
+ mPrefix
+ + "."
+ + PROP_RA_SUB_ID ) );
+
+ throw new EMissingSelfTestException( mPrefix,
+ PROP_RA_SUB_ID,
+ null );
+ }
+
+ // retrieve optional parameter(s)
+
+ return;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage( locale,
+ "CMS_SELFTESTS_RA_PRESENCE_DESCRIPTION" );
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest( ILogEventListener logger )
+ throws ESelfTestException
+ {
+ String logMessage = null;
+ IRegistrationAuthority ra = null;
+ org.mozilla.jss.crypto.X509Certificate raCert = null;
+ PublicKey raPubKey = null;
+
+ ra = ( IRegistrationAuthority ) CMS.getSubsystem( mRaSubId );
+
+ if( ra == null ) {
+ // log that the RA is not installed
+ logMessage = CMS.getLogMessage( "SELFTESTS_RA_IS_NOT_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ } else {
+ // Retrieve the RA certificate
+ raCert = ra.getRACert();
+
+ if( raCert == null ) {
+ // log that the RA is not yet initialized
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_RA_IS_NOT_INITIALIZED",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // Retrieve the RA certificate public key
+ raPubKey = ( PublicKey ) raCert.getPublicKey();
+
+ if( raPubKey == null ) {
+ // log that something is seriously wrong with the RA
+ logMessage = CMS.getLogMessage( "SELFTESTS_RA_IS_CORRUPT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+
+ throw new ESelfTestException( logMessage );
+ }
+
+ // log that the RA is present
+ logMessage = CMS.getLogMessage( "SELFTESTS_RA_IS_PRESENT",
+ getSelfTestName() );
+
+ mSelfTestSubsystem.log( logger,
+ logMessage );
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
new file mode 100644
index 000000000..05337bd96
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
@@ -0,0 +1,323 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.tks;
+
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.tks.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.cms.selftests.*;
+import java.util.*;
+import com.netscape.symkey.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a self test to check for TKS known session key.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @author awnuk
+ * @version $Revision$, $Date$
+ */
+public class TKSKnownSessionKey
+extends ASelfTest
+{
+ // parameter information
+ public static final String PROP_TKS_SUB_ID = "TksSubId";
+ private String mTksSubId = null;
+ private String mToken = null;
+ private String mUseSoftToken = null;
+ private String mKeyName = null;
+ private byte[] mKeyInfo = null;
+ private byte[] mCardChallenge = null;
+ private byte[] mHostChallenge = null;
+ private byte[] mCUID = null;
+ private byte[] mMacKey = null;
+ private byte[] mSessionKey = null;
+
+
+ /**
+ * Initializes this subsystem with the configuration store
+ * associated with this instance name.
+ * <P>
+ *
+ * @param subsystem the associated subsystem
+ * @param instanceName the name of this self test instance
+ * @param parameters configuration store (self test parameters)
+ * @exception EDuplicateSelfTestException subsystem has duplicate name/value
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void initSelfTest (ISelfTestSubsystem subsystem,
+ String instanceName,
+ IConfigStore parameters)
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException
+ {
+ ISubsystem tks = null;
+ IConfigStore tksConfig = null;
+ String logMessage = null;
+
+ super.initSelfTest( subsystem, instanceName, parameters );
+
+ mTksSubId = getConfigString(PROP_TKS_SUB_ID);
+ mToken = getConfigString("token");
+ mKeyName = getConfigString("keyName");
+ mCardChallenge = getConfigByteArray("cardChallenge", 8);
+ mHostChallenge = getConfigByteArray("hostChallenge", 8);
+ mKeyInfo = getConfigByteArray("keyName", 2);
+ mCUID = getConfigByteArray("CUID", 10);
+ mMacKey = getConfigByteArray("macKey", 16);
+ mUseSoftToken = getConfigString("useSoftToken");
+
+ String defKeySetMacKey = null;
+ tks = (ISubsystem) CMS.getSubsystem(mTksSubId);
+ if (tks != null) {
+ tksConfig = tks.getConfigStore();
+ if (tksConfig != null) {
+ try {
+ defKeySetMacKey = tksConfig.getString("defKeySet.mac_key");
+ byte defMacKey[] = com.netscape.cmsutil.util.Utils.SpecialDecode(defKeySetMacKey);
+ if (!Arrays.equals(mMacKey, defMacKey)) {
+ defKeySetMacKey = null;
+ }
+ } catch (EBaseException e) {
+ defKeySetMacKey = null;
+ }
+ }
+ }
+ if (defKeySetMacKey == null) {
+ CMS.debug("TKSKnownSessionKey: invalid mac key");
+ CMS.debug("TKSKnownSessionKey self test FAILED");
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_INVALID_VALUES",
+ getSelfTestName(), mPrefix + "." + "macKey"));
+ throw new EInvalidSelfTestException (mPrefix, "macKey", null);
+ }
+
+ try {
+ mSessionKey = getConfigByteArray("sessionKey", 16);
+ } catch (EMissingSelfTestException e) {
+ if (mSessionKey == null) {
+ mSessionKey = SessionKey.ComputeSessionKey (mToken, mKeyName,
+ mCardChallenge, mHostChallenge,
+ mKeyInfo, mCUID, mMacKey, mUseSoftToken);
+ if (mSessionKey == null || mSessionKey.length != 16) {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
+ getSelfTestName(), mPrefix + ".sessionKey"));
+ throw new EMissingSelfTestException ("sessionKey");
+ }
+ String sessionKey = SpecialEncode(mSessionKey);
+ mConfig.putString("sessionKey", sessionKey);
+ try {
+ CMS.getConfigStore().commit(true);
+ } catch (EBaseException be) {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
+ getSelfTestName(), mPrefix + ".sessionKey"));
+ throw new EMissingSelfTestException ("sessionKey");
+ }
+ }
+ }
+
+ return;
+ }
+
+
+ private String SpecialEncode (byte data[])
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < data.length; i++) {
+ sb.append("#");
+ if ((data[i] & 0xff) < 16) {
+ sb.append("0");
+ }
+ sb.append(Integer.toHexString((data[i] & 0xff)));
+ }
+
+ return sb.toString();
+ }
+
+
+ private String getConfigString (String name) throws EMissingSelfTestException
+ {
+ String value = null;
+
+ try {
+ value = mConfig.getString(name);
+ if (value != null) {
+ value = value.trim();
+ } else {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
+ getSelfTestName(), mPrefix + "." + name));
+ throw new EMissingSelfTestException (name);
+ }
+ } catch (EBaseException e) {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_NAME",
+ getSelfTestName(), mPrefix + "." + name));
+ throw new EMissingSelfTestException (mPrefix, name, null);
+ }
+
+ return value;
+ }
+
+
+ private byte[] getConfigByteArray (String name, int size) throws EMissingSelfTestException,
+ EInvalidSelfTestException
+ {
+ String stringValue = getConfigString(name);
+
+ byte byteValue[] = com.netscape.cmsutil.util.Utils.SpecialDecode(stringValue);
+ if (byteValue == null) {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_NAME",
+ getSelfTestName(), mPrefix + "." + name));
+ throw new EMissingSelfTestException (name);
+ }
+ if (byteValue.length != size) {
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_INVALID_VALUES",
+ getSelfTestName(), mPrefix + "." + name));
+ throw new EInvalidSelfTestException (mPrefix, name, stringValue);
+ }
+
+ return byteValue;
+ }
+
+
+ /**
+ * Notifies this subsystem if it is in execution mode.
+ * <P>
+ *
+ * @exception ESelfTestException failed to start
+ */
+ public void startupSelfTest()
+ throws ESelfTestException
+ {
+ return;
+ }
+
+
+ /**
+ * Stops this subsystem. The subsystem may call shutdownSelfTest
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdownSelfTest()
+ {
+ return;
+ }
+
+
+ /**
+ * Returns the name associated with this self test. This method may
+ * return null if the self test has not been intialized.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName()
+ {
+ return super.getSelfTestName();
+ }
+
+
+ /**
+ * Returns the root configuration storage (self test parameters)
+ * associated with this subsystem.
+ * <P>
+ *
+ * @return configuration store (self test parameters) of this subsystem
+ */
+ public IConfigStore getSelfTestConfigStore()
+ {
+ return super.getSelfTestConfigStore();
+ }
+
+
+ /**
+ * Retrieves description associated with an individual self test.
+ * This method may return null.
+ * <P>
+ *
+ * @param locale locale of the client that requests the description
+ * @return description of self test
+ */
+ public String getSelfTestDescription( Locale locale )
+ {
+ return CMS.getUserMessage (locale, "CMS_SELFTESTS_TKS_PRESENCE_DESCRIPTION");
+ }
+
+
+ /**
+ * Execute an individual self test.
+ * <P>
+ *
+ * @param logger specifies logging subsystem
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTest (ILogEventListener logger)
+ throws ESelfTestException
+ {
+ String logMessage = null;
+
+ byte[] sessionKey = SessionKey.ComputeSessionKey (mToken, mKeyName,
+ mCardChallenge, mHostChallenge,
+ mKeyInfo, mCUID, mMacKey, mUseSoftToken);
+ if (sessionKey == null) {
+ CMS.debug("TKSKnownSessionKey: generated no session key");
+ CMS.debug("TKSKnownSessionKey self test FAILED");
+ logMessage = CMS.getLogMessage ("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
+ mSelfTestSubsystem.log (logger, logMessage);
+ throw new ESelfTestException( logMessage );
+ } else if (!Arrays.equals(mSessionKey, sessionKey)) {
+ CMS.debug("TKSKnownSessionKey: generated invalid session key");
+ CMS.debug("TKSKnownSessionKey self test FAILED");
+ logMessage = CMS.getLogMessage ("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
+ mSelfTestSubsystem.log (logger, logMessage);
+ throw new ESelfTestException( logMessage );
+ } else {
+ logMessage = CMS.getLogMessage ("SELFTESTS_TKS_SUCCEEDED", getSelfTestName(), getSelfTestName());
+ mSelfTestSubsystem.log (logger, logMessage);
+ CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java
new file mode 100644
index 000000000..7bac528e9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java
@@ -0,0 +1,915 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.text.*;
+import java.net.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+//import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.evaluators.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * Manage Access Control List configuration
+ *
+ * @version $Revision$, $Date$
+ */
+public class ACLAdminServlet extends AdminServlet {
+
+ private IUGSubsystem mUG = null;
+ private static final String PROP_ACLS = "acls";
+ private static final String PROP_EVAL = "accessEvaluator";
+ private final static String INFO = "ACLAdminServlet";
+ private IAuthzManager mAuthzMgr = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ACL =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ACL_3";
+
+ /**
+ * Constructs servlet.
+ */
+ public ACLAdminServlet() {
+ super();
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ }
+
+ /**
+ * initialize the servlet.
+ * <ul>
+ * <li>http.param OP_TYPE = OP_SEARCH,
+ * <li>http.param OP_SCOPE - the scope of the request operation:
+ * <ul><LI>"impl" ACL implementations
+ * <LI>"acls" ACL rules
+ * <LI>"evaluatorTypes" ACL evaluators.
+ * </ul>
+ * </ul>
+ *
+ * @param config servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mAuthzMgr = mAuthz.get(mAclMethod);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param req the object holding the request information
+ * @param resp the object holding the response information
+ */
+
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String scope = super.getParameter(req, Constants.OP_SCOPE);
+ String op = super.getParameter(req, Constants.OP_TYPE);
+
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_INVALID_PROTOCOL"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ Locale clientLocale = super.getLocale(req);
+
+ try {
+ super.authenticate(req);
+ } catch (IOException e) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("ADMIN_SRVLT_FAIL_AUTHS"));
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req),"CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+
+ IUser user = null;
+
+ try {
+ SessionContext mSC = SessionContext.getContext();
+
+ user = (IUser)
+ mSC.get(SessionContext.USER);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+
+ try {
+ AUTHZ_RES_NAME = "certServer.acl.configuration";
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ACL)) {
+ listResources(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_ACL_IMPLS)) {
+ listACLsEvaluators(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_EVALUATOR_TYPES)) {
+ listACLsEvaluatorTypes(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ACL)) {
+ getResourceACL(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ACL)) {
+ updateResources(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ACL_IMPLS)) {
+ addACLsEvaluator(req, resp, scope);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ACL_IMPLS)) {
+ deleteACLsEvaluator(req, resp, scope);
+ return;
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_INVALID_OP_SCOPE"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ sendResponse(ERROR, e.toString(getLocale(req)),
+ null, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ log(ILogger.LL_DEBUG, "SRVLT_FAIL_PERFORM 2");
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+
+ log(ILogger.LL_DEBUG, "SRVLT_FAIL_PERFORM 3");
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+
+ /**
+ * list acls resources by name
+ */
+ private void listResources(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ Enumeration res = mAuthzMgr.getACLs();
+
+ while (res.hasMoreElements()) {
+ ACL acl = (ACL) res.nextElement();
+ String desc = acl.getDescription();
+
+ if (desc == null)
+ params.add(acl.getName(), "");
+ else
+ params.add(acl.getName(), desc);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * get acls information for a resource
+ */
+ private void getResourceACL(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ //get resource id first
+ String resourceId = super.getParameter(req, Constants.RS_ID);
+
+ if (resourceId == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IACL acl = mAuthzMgr.getACL(resourceId);
+
+ if (acl != null) {
+ Enumeration en = acl.rights();
+
+ StringBuffer rights = new StringBuffer();
+
+ if (en.hasMoreElements()) {
+ while (en.hasMoreElements()) {
+ if (rights.length() != 0) {
+ rights.append(",");
+ }
+ String right = (String) en.nextElement();
+
+ rights.append(right);
+ }
+ }
+
+ params.add(Constants.PR_ACL_OPS, rights.toString());
+
+ en = acl.entries();
+ String acis = "";
+
+ if (en.hasMoreElements()) {
+ while (en.hasMoreElements()) {
+ if (acis != "") {
+ acis += ";";
+ }
+ ACLEntry aclEntry = (ACLEntry) en.nextElement();
+ String aci = aclEntry.getACLEntryString();
+
+ acis += aci;
+ }
+ }
+
+ params.add(Constants.PR_ACI, acis);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ACLS_SRVLT_RESOURCE_NOT_FOUND"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_RESOURCE_NOT_FOUND"),
+ null, resp);
+ return;
+ }
+ }
+
+ /**
+ * modify acls information for a resource
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ACL used when configuring
+ * Access Control List (ACL) information
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void updateResources(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // get resource id first
+ String resourceId = super.getParameter(req, Constants.RS_ID);
+
+ if (resourceId == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // get resource acls
+ String resourceACLs = super.getParameter(req, Constants.PR_ACI);
+ String rights = super.getParameter(req, Constants.PR_ACL_RIGHTS);
+ String desc = super.getParameter(req, Constants.PR_ACL_DESC);
+
+ try {
+ mAuthzMgr.updateACLs(resourceId, rights, resourceACLs, desc);
+
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_UPDATE_FAIL"),
+ null, resp);
+ return;
+ }
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * list access evaluators by types and class paths
+ */
+ private void listACLsEvaluators(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration res = mAuthzMgr.aclEvaluatorElements();
+
+ while (res.hasMoreElements()) {
+ IAccessEvaluator evaluator = (IAccessEvaluator) res.nextElement();
+
+ // params.add(evaluator.getType(), evaluator.getDescription());
+ params.add(evaluator.getType(), evaluator.getClass().getName());
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void listACLsEvaluatorTypes(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration res = mAuthzMgr.aclEvaluatorElements();
+
+ while (res.hasMoreElements()) {
+ IAccessEvaluator evaluator = (IAccessEvaluator) res.nextElement();
+ String[] operators = evaluator.getSupportedOperators();
+ StringBuffer str = new StringBuffer();
+
+ for (int i = 0; i < operators.length; i++) {
+ if (str.length() > 0)
+ str.append(",");
+ str.append(operators[i]);
+ }
+
+ params.add(evaluator.getType(), str.toString());
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * add access evaluators
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ACL used when configuring
+ * Access Control List (ACL) information
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this ACL evaluator's
+ * substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addACLsEvaluator(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // get evaluator type first
+ String type = super.getParameter(req, Constants.RS_ID);
+
+ if (type == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the evaluator type unique?
+ /*
+ if (!mACLs.isTypeUnique(type)) {
+ String infoMsg = "replacing existing type: "+ type;
+ log(ILogger.LL_WARN, infoMsg);
+ }
+ */
+
+ // get class
+ String classPath = super.getParameter(req, Constants.PR_ACL_CLASS);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(PROP_EVAL);
+ IConfigStore mStore =
+ destStore.getSubStore(ScopeDef.SC_ACL_IMPLS);
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ String errMsg = "class " + classPath + " not found";
+
+ log(ILogger.LL_FAILURE, errMsg);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_CLASS_LOAD_FAIL"),
+ null, resp);
+ return;
+ }
+
+ // is the class an IAccessEvaluator?
+ try {
+ if
+ (Class.forName("com.netscape.certsrv.evaluators.IAccessEvaluator").isAssignableFrom(newImpl) == false) {
+ String errMsg = "class not com.netscape.certsrv.evaluators.IAccessEvaluator" +
+ classPath;
+
+ log(ILogger.LL_FAILURE, errMsg);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+ } catch (Exception e) {
+ String errMsg = "class not com.netscape.certsrv.evaluators.IAccessEvaluator" +
+ classPath;
+
+ log(ILogger.LL_FAILURE, errMsg);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore substore = mStore.makeSubStore(type);
+
+ substore.put(Constants.PR_ACL_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ACLS_SRVLT_FAIL_COMMIT"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_COMMIT_FAIL"),
+ null, resp);
+ return;
+ }
+
+ // Instantiate an object for this implementation
+ IAccessEvaluator evaluator = null;
+
+ try {
+ evaluator = (IAccessEvaluator) Class.forName(classPath).newInstance();
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_INST_CLASS_FAIL"),
+ null, resp);
+ return;
+ }
+
+ // initialize the access evaluator
+ if (evaluator != null) {
+ evaluator.init();
+ // add evaluator to list
+ mAuthzMgr.registerEvaluator(type, evaluator);
+ }
+
+ //...
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * remove access evaluators
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ACL used when configuring
+ * Access Control List (ACL) information
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this ACL evaluator's
+ * substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void deleteACLsEvaluator(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does the evaluator exist?
+ Hashtable mEvaluators = mAuthzMgr.getAccessEvaluators();
+
+ if (mEvaluators.containsKey(id) == false) {
+ log(ILogger.LL_FAILURE, "evaluator attempted to be removed not found");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_EVAL_NOT_FOUND"),
+ null, resp);
+ return;
+ }
+
+ // it's possibl that it's being used...we have to assume that
+ // the administrator knows what she is doing, for now
+ mEvaluators.remove((Object) id);
+
+ try {
+ IConfigStore destStore =
+ mConfig.getSubStore(PROP_EVAL);
+ IConfigStore mStore =
+ destStore.getSubStore(ScopeDef.SC_ACL_IMPLS);
+
+ mStore.removeSubStore(id);
+ } catch (Exception eeee) {
+ //CMS.debugStackTrace(eeee);
+ }
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ACLS_SRVLT_FAIL_COMMIT"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_ACL_COMMIT_FAIL"),
+ null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ACL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Searchs for certificate requests.
+ */
+
+ /*
+ private void getACLs(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException,
+ EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ String names = getParameter(req, Constants.PT_NAMES);
+ StringTokenizer st = new StringTokenizer(names, ",");
+ while (st.hasMoreTokens()) {
+ String target = st.nextToken();
+ ACL acl = AccessManager.getInstance().getACL(target);
+ oos.writeObject(acl);
+ }
+ // BASE64Encoder encoder = new BASE64Encoder();
+ // params.add(Constants.PT_ACLS, encoder.encodeBuffer(bos.toByteArray()));
+ params.add(Constants.PT_ACLS, CMS.BtoA(bos.toByteArray()));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+ */
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ACLS,
+ level, "ACLAdminServlet: " + msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java b/pki/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java
new file mode 100644
index 000000000..4e97c2d52
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java
@@ -0,0 +1,44 @@
+// --- 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.servlet.admin;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for the remote admin.
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class AdminResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java
new file mode 100644
index 000000000..f7f9ce16a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java
@@ -0,0 +1,1304 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.security.cert.X509Certificate;
+import netscape.security.x509.X509CertImpl;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.base.*;
+
+
+/**
+ * A class represents an administration servlet that
+ * is responsible to serve administrative
+ * operation such as configuration parameter updates.
+ *
+ * Since each administration servlet needs to perform
+ * authentication information parsing and response
+ * formulation, it makes sense to encapsulate the
+ * commonalities into this class.
+ *
+ * By extending this serlvet, the subclass does not
+ * need to re-implement the request parsing code
+ * (i.e. authentication information parsing).
+ *
+ * If a subsystem needs to expose configuration
+ * parameters management, it should create an
+ * administration servlet (i.e. CAAdminServlet)
+ * and register it to RemoteAdmin subsystem.
+ *
+ * <code>
+ * public class CAAdminServlet extends AdminServlet {
+ * ...
+ * }
+ * </code>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AdminServlet extends HttpServlet {
+
+ private final static String HDR_AUTHORIZATION = "Authorization";
+ private final static String HDR_LANG = "accept-language";
+ private final static String HDR_CONTENT_LEN = "Content-Length";
+
+ protected ILogger mLogger = CMS.getLogger();
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private IUGSubsystem mUG = null;
+ protected IConfigStore mConfig = null;
+ protected IAuthzSubsystem mAuthz = null;
+
+ // we don't allow to switch authz db mid-way, for now
+ protected String mAclMethod = null;
+ protected String mOp = "";
+ protected static String AUTHZ_RES_NAME = "certServer";
+ protected AuthzToken mToken;
+
+ private String mServletID = null;
+ public final static String PROP_AUTHZ_MGR = "AuthzMgr";
+ public final static String PROP_ACL = "ACLinfo";
+
+ public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz";
+ public final static String AUTHZ_MGR_LDAP = "DirAclAuthz";
+ public final static String PROP_ID = "ID";
+ public final static String AUTHZ_CONFIG_STORE = "authz";
+ public final static String AUTHZ_SRC_TYPE = "sourceType";
+ public final static String AUTHZ_SRC_LDAP = "ldap";
+ public final static String AUTHZ_SRC_XML = "web.xml";
+ public static final String CERT_ATTR =
+ "javax.servlet.request.X509Certificate";
+
+ public final static String SIGNED_AUDIT_SCOPE = "Scope";
+ public final static String SIGNED_AUDIT_OPERATION = "Operation";
+ public final static String SIGNED_AUDIT_RESOURCE = "Resource";
+ public final static String SIGNED_AUDIT_RULENAME = "RULENAME";
+ public final static String SIGNED_AUDIT_PASSWORD_VALUE = "********";
+ public final static String SIGNED_AUDIT_EMPTY_NAME_VALUE_PAIR = "Unknown";
+ public final static String SIGNED_AUDIT_NAME_VALUE_DELIMITER = ";;";
+ public final static String SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER = "+";
+
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTH_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTH_SUCCESS_3";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4";
+ private final static String LOGGING_SIGNED_AUDIT_ROLE_ASSUME =
+ "LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3";
+ private final static String CERTUSERDB =
+ IAuthSubsystem.CERTUSERDB_AUTHMGR_ID;
+ private final static String PASSWDUSERDB =
+ IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID;
+
+ /**
+ * Constructs generic administration servlet.
+ */
+ public AdminServlet() {
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ mConfig = CMS.getConfigStore();
+
+ String srcType = AUTHZ_SRC_LDAP;
+
+ try {
+ IConfigStore authzConfig = mConfig.getSubStore(AUTHZ_CONFIG_STORE);
+
+ srcType = authzConfig.getString(AUTHZ_SRC_TYPE, AUTHZ_SRC_LDAP);
+ } catch (EBaseException e) {
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_FAIL_SRC_TYPE"));
+ }
+ mAuthz =
+ (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+
+ mServletID = getSCparam(sc, PROP_ID, "servlet id unknown");
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_INITED", mServletID));
+
+ if (srcType.equalsIgnoreCase(AUTHZ_SRC_XML)) {
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_INITED", ""));
+ // get authz mgr from xml file; if not specified, use
+ // ldap by default
+ mAclMethod = getSCparam(sc, PROP_AUTHZ_MGR, AUTHZ_MGR_LDAP);
+
+ if (mAclMethod.equalsIgnoreCase(AUTHZ_MGR_BASIC)) {
+ String aclInfo = sc.getInitParameter(PROP_ACL);
+
+ if (aclInfo != null) {
+ try {
+ addACLInfo(aclInfo);
+ //mAuthz.authzMgrAccessInit(mAclMethod, aclInfo);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_FAIL"));
+ throw new ServletException("failed to init authz info from xml config file");
+ }
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE", mServletID));
+ } else { // PROP_AUTHZ_MGR not specified, use default authzmgr
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_PROP_ACL_NOT_SPEC", PROP_ACL, mServletID, AUTHZ_MGR_LDAP));
+ }
+ } else { // PROP_AUTHZ_MGR not specified, use default authzmgr
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_PROP_ACL_NOT_SPEC", PROP_AUTHZ_MGR, mServletID, AUTHZ_MGR_LDAP));
+ }
+
+ } else {
+ mAclMethod = AUTHZ_MGR_LDAP;
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_AUTH_LDAP_NOT_XML", mServletID));
+ }
+ }
+
+ public void outputHttpParameters(HttpServletRequest httpReq)
+ {
+ CMS.debug("AdminServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = (String)paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("AdminServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("AdminServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CMS server is not ready to serve.");
+
+ if (CMS.debugOn()) {
+ outputHttpParameters(req);
+ }
+ }
+
+ private void addACLInfo(String info) throws EBaseException {
+ StringTokenizer tokenizer = new StringTokenizer(info, "#");
+
+ while (tokenizer.hasMoreTokens()) {
+ String acl = (String) tokenizer.nextToken();
+
+ mAuthz.authzMgrAccessInit(mAclMethod, acl);
+ }
+ }
+
+ private String getSCparam(ServletConfig sc, String param, String defVal) {
+ String val = sc.getInitParameter(param);
+
+ if (val == null)
+ return defVal;
+ else
+ return val;
+ }
+
+ /**
+ * Authenticates to the identity scope with the given
+ * userid and password via identity manager.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_FAIL used when authentication
+ * fails (in case of SSL-client auth, only webserver env can pick up the
+ * SSL violation; CMS authMgr can pick up cert mis-match, so this event
+ * is used)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_SUCCESS used when authentication
+ * succeeded
+ * </ul>
+ * @exception IOException an input/output error has occurred
+ */
+ protected void authenticate(HttpServletRequest req) throws
+ IOException {
+
+ String auditMessage = null;
+ String auditSubjectID = ILogger.UNIDENTIFIED;
+ String auditUID = ILogger.UNIDENTIFIED;
+ String authType = "";
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ try {
+ IConfigStore configStore = CMS.getConfigStore();
+
+ authType = configStore.getString("authType");
+ } catch (EBaseException e) {
+ // do nothing for now.
+ }
+ IAuthSubsystem auth = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ X509Certificate cert = null;
+
+ if (authType.equals("sslclientauth")) {
+ X509Certificate[] allCerts =
+ (X509Certificate[]) req.getAttribute(CERT_ATTR);
+
+ if (allCerts == null || allCerts.length == 0) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+
+ throw new IOException("No certificate");
+ }
+
+ cert = allCerts[0];
+ try {
+ byte[] certEncoded = cert.getEncoded();
+
+ cert = new X509CertImpl(certEncoded);
+
+ // save the "Subject DN" of this certificate in case it
+ // must be audited as an authentication failure
+ String certUID = cert.getSubjectDN().getName();
+
+ if (certUID != null) {
+ certUID = certUID.trim();
+
+ if (!(certUID.equals(""))) {
+ auditUID = certUID;
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ // create session (if we don't, identity will reject
+ // the authentication).
+ SessionContext sc = SessionContext.getContext();
+ IAuthToken token = null;
+
+ // a kludge for the desperately pinging console
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ log(ILogger.LL_DEBUG, CMS.getLogMessage("ADMIN_SRVLT_ABOUT_AUTH",
+ mServletID));
+ try {
+ if (authType.equals("sslclientauth")) {
+ IAuthManager
+ authMgr = auth.get(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID);
+ IAuthCredentials authCreds =
+ getAuthCreds(authMgr, cert);
+
+ token = (AuthToken) authMgr.authenticate(authCreds);
+ } else {
+ String authToken = req.getHeader(HDR_AUTHORIZATION);
+ String b64s = authToken.substring(
+ authToken.lastIndexOf(' ') + 1);
+ String authCode = new String(com.netscape.osutil.OSUtil.AtoB(b64s));
+ String userid = authCode.substring(0,
+ authCode.lastIndexOf(':'));
+ String password = authCode.substring(
+ authCode.lastIndexOf(':') + 1);
+ AuthCredentials cred = new AuthCredentials();
+
+ // save the "userid" of this certificate in case it
+ // must be audited as an authentication failure
+ String pwdUID = userid;
+
+ if (pwdUID != null) {
+ pwdUID = pwdUID.trim();
+
+ if (!(pwdUID.equals(""))) {
+ auditUID = pwdUID;
+ }
+ }
+
+ cred.set("uid", userid);
+ cred.set("pwd", password);
+
+ token = auth.authenticate(cred,
+ IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID);
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_AUTH_FOR_SRVLT",
+ mServletID));
+ }
+ } catch (EBaseException e) {
+ //will fix it later for authorization
+ /*
+ String errMsg = "authenticate(): " +
+ AdminResources.SRVLT_FAIL_AUTHS +": "+userid +":"+
+ e.getMessage();
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAIL",
+ CMS.getLogMessage("ADMIN_SRVLT_FAIL_AUTHS"),
+ userid,e.getMessage()));
+ */
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ throw new IOException("authentication failed");
+ }
+
+ try {
+ String tuserid = token.getInString("userid");
+
+ if (tuserid == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_NO_AUTH_TOKEN",
+ tuserid));
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ throw new IOException("authentication failed");
+ }
+
+ // get user.
+ // this either returns null or
+ // throws exception when user not found
+ IUser user = mUG.getUser(tuserid);
+
+ if (user == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USER_NOT_FOUND",
+ tuserid));
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ throw new IOException("authentication failed");
+ }
+
+ // set session context to work with some agent servlets.
+ // XXX should see if this can be used for more things.
+ SessionContext sessionContext = SessionContext.getContext();
+
+ sessionContext.put(SessionContext.AUTH_TOKEN, token);
+ sessionContext.put(SessionContext.USER_ID, tuserid);
+ sessionContext.put(SessionContext.USER, user);
+ } catch (EUsrGrpException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USR_GRP_ERR", e.toString()));
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ throw new IOException("authentication failed");
+ } catch (EBaseException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERROR",
+ e.toString()));
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ throw new IOException("authentication failed");
+ }
+
+ // build locale based on the client language
+ Locale locale = getLocale(req);
+
+ sc.put(SessionContext.LOCALE, locale);
+
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ auditSubjectID(),
+ ILogger.SUCCESS,
+ CERTUSERDB);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ auditSubjectID(),
+ ILogger.SUCCESS,
+ PASSWDUSERDB);
+
+ audit(auditMessage);
+ }
+ } catch (IOException eAudit1) {
+ if (authType.equals("sslclientauth")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ CERTUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ ILogger.UNIDENTIFIED,
+ ILogger.FAILURE,
+ PASSWDUSERDB,
+ auditUID);
+
+ audit(auditMessage);
+ }
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ public static AuthCredentials getAuthCreds(
+ IAuthManager authMgr, X509Certificate clientCert)
+ throws EBaseException {
+ // get credentials from http parameters.
+ String[] reqCreds = authMgr.getRequiredCreds();
+ AuthCredentials creds = new AuthCredentials();
+
+ for (int i = 0; i < reqCreds.length; i++) {
+ String reqCred = reqCreds[i];
+
+ if (reqCred.equals(IAuthManager.CRED_SSL_CLIENT_CERT)) {
+ // cert could be null;
+ creds.set(reqCred, new X509Certificate[] { clientCert}
+ );
+ }
+ }
+ return creds;
+ }
+
+ /**
+ * Authorize must occur after Authenticate
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_FAIL used when authorization
+ * has failed
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS used when authorization
+ * is successful
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_ROLE_ASSUME used when user assumes a
+ * role (in current CMS that's when one accesses a role port)
+ * </ul>
+ * @param req HTTP servlet request
+ * @return the authorization token
+ */
+ protected AuthzToken authorize(HttpServletRequest req) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditACLResource = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditOperation = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String resource = null;
+ String operation = null;
+
+ // use session context to get auth token for now
+ SessionContext sc = SessionContext.getContext();
+ IAuthToken authToken = (IAuthToken) sc.get(SessionContext.AUTH_TOKEN);
+
+ AuthzToken authzTok = null;
+
+ CMS.debug("AdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CHECK_AUTHZ_AUTH", mServletID));
+ // hardcoded for now .. just testing
+ try {
+ // we check both "read" and "write" for now. later within
+ // each servlet, they can break it down
+ authzTok = mAuthz.authorize(mAclMethod, authToken, AUTHZ_RES_NAME, mOp);
+ // initialize the ACL resource, overwriting "auditACLResource"
+ // if it is not null
+ resource = (String)
+ authzTok.get(AuthzToken.TOKEN_AUTHZ_RESOURCE);
+ if (resource != null) {
+ auditACLResource = resource.trim();
+ }
+
+ // initialize the operation, overwriting "auditOperation"
+ // if it is not null
+ operation = (String)
+ authzTok.get(AuthzToken.TOKEN_AUTHZ_OPERATION);
+ if (operation != null) {
+ auditOperation = operation.trim();
+ }
+
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTH_SUCCEED", mServletID));
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return authzTok;
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader(HDR_LANG);
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ public static int SUCCESS = 0;
+ public static int ERROR = 1;
+ public static int RESTART = -1;
+
+ /**
+ * Sends response.
+ *
+ * @param returnCode return code
+ * @param errorMsg localized error message
+ * @param params result parameters
+ * @param resp HTTP servlet response
+ */
+ protected void sendResponse(int returnCode, String errorMsg,
+ NameValuePairs params, HttpServletResponse resp)
+ throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+
+ dos.writeInt(returnCode);
+ if (errorMsg != null) {
+ dos.writeUTF(errorMsg);
+ }
+ StringBuffer buf = new StringBuffer();
+
+ if (params != null) {
+ Enumeration e = params.getNames();
+
+ if (e.hasMoreElements()) {
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String value = java.net.URLEncoder.encode((String)
+ params.getValue(name));
+
+ buf.append(java.net.URLEncoder.encode(name) +
+ "=" + value);
+ if (e.hasMoreElements())
+ buf.append("&");
+ }
+ byte content[] = buf.toString().getBytes();
+
+ dos.write(content, 0, content.length);
+ }
+ }
+ byte msg[] = bos.toByteArray();
+
+ resp.setContentLength(msg.length);
+ resp.getOutputStream().write(msg);
+ resp.getOutputStream().flush();
+ }
+
+ /**
+ * URL decodes the given string.
+ */
+ protected String URLdecode(String s) {
+ if (s == null)
+ return null;
+ ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = (int) s.charAt(i);
+
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '%') {
+ int c1 = Character.digit(s.charAt(++i), 16);
+ int c2 = Character.digit(s.charAt(++i), 16);
+
+ out.write((char) (c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ } // end for
+ return out.toString();
+ }
+
+ protected String getParameter(HttpServletRequest req, String name) {
+ // Servlet framework already apply URLdecode
+ // return URLdecode(req.getParameter(name));
+ return req.getParameter(name);
+ }
+
+ /**
+ * Generic configuration store get operation.
+ */
+ protected synchronized void getConfig(
+ IConfigStore config, HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ //if (name.equals(Constants.PT_OP))
+ // continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+
+ //System.out.println(name);
+ //System.out.println(name+","+config.getString(name));
+ params.add(name, config.getString(name));
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Generic configuration store set operation.
+ * The caller is responsible to do validiation before
+ * calling this, and commit changes after this call.
+ */
+ protected synchronized void setConfig(
+ IConfigStore config, HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ //if (name.equals(Constants.PT_OP))
+ // continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ // XXX Need validation...
+ // XXX what if update failed
+ config.putString(name, req.getParameter(name));
+ }
+ commit(true);
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Lists configuration store.
+ */
+ protected synchronized void listConfig(
+ IConfigStore config, HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration e = config.getPropertyNames();
+ NameValuePairs params = new NameValuePairs();
+
+ while (e.hasMoreElements()) {
+ String s = (String) e.nextElement();
+
+ params.add(s, config.getString(s));
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * authorize a user based on its authentication credentials.
+ */
+ public boolean authorize(IAuthToken token) throws EBaseException {
+ String mGroupNames[] = { "Administrators" };
+ boolean mAnd = true;
+
+ try {
+ String userid = token.getInString("userid");
+
+ if (userid == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_GRP_AUTHZ_FAIL", userid));
+ return false;
+ }
+
+ // get user.
+ // this either returns null or throws exception when user not found
+ IUser user = mUG.getUser(userid);
+
+ if (user == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USER_NOT_IN_DB", userid));
+ return false;
+ }
+
+ // set session context to work with some agent servlets.
+ // XXX should see if this can be used for more things.
+ SessionContext sessionContext = SessionContext.getContext();
+
+ sessionContext.put(SessionContext.AUTH_TOKEN, token);
+ sessionContext.put(SessionContext.USER_ID, userid);
+ sessionContext.put(SessionContext.USER, user);
+
+ // check group membership of user.
+ if (mAnd) {
+ for (int i = 0; i < mGroupNames.length; i++) {
+ if (!mUG.isMemberOf(user, mGroupNames[i])) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USER_NOT_IN_GRP", userid,
+ mGroupNames[i]));
+ return false;
+ }
+ }
+ return true;
+ } else {
+ for (int i = 0; i < mGroupNames.length; i++) {
+ if (mUG.isMemberOf(user, mGroupNames[i])) {
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_OTHER, ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_GRP_AUTH_SUCC_USER", userid,
+ mGroupNames[i]));
+ return true;
+ }
+ }
+ StringBuffer groups = new StringBuffer();
+ groups.append(mGroupNames[0]);
+
+ for (int j = 1; j < mGroupNames.length; j++) {
+ groups.append(",");
+ groups.append(mGroupNames[j]);
+ }
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USER_NOT_ANY_GRP", userid, groups.toString()));
+ return false;
+ }
+ } catch (EUsrGrpException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_USR_GRP_ERR", e.toString()));
+ return false;
+ }
+ }
+
+ /**
+ * FileConfigStore functionality
+ *
+ * The original config file is moved to <filename>.<date>.
+ * Commits the current properties to the configuration file.
+ * <P>
+ *
+ * @param createBackup true if a backup file should be created
+ */
+ protected void commit(boolean createBackup) throws EBaseException {
+ mConfig.commit(createBackup);
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ADMIN,
+ level, "AdminServlet: " + msg);
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended admin servlets
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+
+ /**
+ * Signed Audit Parameters
+ *
+ * This method is inherited by all extended admin servlets and
+ * is called to extract parameters from the HttpServletRequest
+ * and return a string of name;;value pairs separated by a '+'
+ * if more than one name;;value pair exists.
+ * <P>
+ *
+ * @param req HTTP servlet request
+ * @return a delimited string of one or more delimited name/value pairs
+ */
+ protected String auditParams(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String parameters = SIGNED_AUDIT_EMPTY_NAME_VALUE_PAIR;
+ String value = null;
+
+ // always identify the scope of the request
+ if (req.getParameter(Constants.OP_SCOPE) != null) {
+ parameters = SIGNED_AUDIT_SCOPE
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + req.getParameter(Constants.OP_SCOPE);
+ }
+
+ // identify the operation type of the request
+ if (req.getParameter(Constants.OP_TYPE) != null) {
+ parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER;
+
+ parameters += SIGNED_AUDIT_OPERATION
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + req.getParameter(Constants.OP_TYPE);
+ }
+
+ // identify the resource type of the request
+ if (req.getParameter(Constants.RS_ID) != null) {
+ parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER;
+
+ parameters += SIGNED_AUDIT_RESOURCE
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + req.getParameter(Constants.RS_ID);
+ }
+
+ // identify any remaining request parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ // skip previously extracted parameters
+ if (name.equals(Constants.OP_SCOPE)) {
+ continue;
+ }
+ if (name.equals(Constants.OP_TYPE)) {
+ continue;
+ }
+ if (name.equals(Constants.RS_ID)) {
+ continue;
+ }
+
+ // skip "RULENAME" parameter
+ if (name.equals(SIGNED_AUDIT_RULENAME)) {
+ continue;
+ }
+
+ parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER;
+
+ value = req.getParameter(name);
+ if (value != null) {
+ value = value.trim();
+
+ if (value.equals("")) {
+ parameters += name
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ //
+ // To fix Blackflag Bug # 613800:
+ //
+ // Check "com.netscape.certsrv.common.Constants" for
+ // case-insensitive "password", "pwd", and "passwd"
+ // name fields, and hide any password values:
+ //
+ /* "password" */ if( name.equals( Constants.PASSWORDTYPE ) ||
+ name.equals( Constants.TYPE_PASSWORD ) ||
+ name.equals( Constants.PR_USER_PASSWORD ) ||
+ name.equals( Constants.PT_OLD_PASSWORD ) ||
+ name.equals( Constants.PT_NEW_PASSWORD ) ||
+ name.equals( Constants.PT_DIST_STORE ) ||
+ name.equals( Constants.PT_DIST_EMAIL ) ||
+ /* "pwd" */ name.equals( Constants.PR_AUTH_ADMIN_PWD ) ||
+ // ignore this one name.equals( Constants.PR_BINDPWD_PROMPT ) ||
+ name.equals( Constants.PR_DIRECTORY_MANAGER_PWD ) ||
+ name.equals( Constants.PR_OLD_AGENT_PWD ) ||
+ name.equals( Constants.PR_AGENT_PWD ) ||
+ name.equals( Constants.PT_PUBLISH_PWD ) ||
+ /* "passwd" */ name.equals( Constants.PR_BIND_PASSWD ) ||
+ name.equals( Constants.PR_BIND_PASSWD_AGAIN ) ||
+ name.equals( Constants.PR_TOKEN_PASSWD ) ) {
+
+ // hide password value
+ parameters += name
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + SIGNED_AUDIT_PASSWORD_VALUE;
+ } else {
+ // process normally
+ parameters += name
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + value;
+ }
+ }
+ } else {
+ parameters += name
+ + SIGNED_AUDIT_NAME_VALUE_DELIMITER
+ + ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+
+ return parameters;
+ }
+
+ /**
+ * Signed Audit Groups
+ *
+ * This method is called to extract all "groups" associated
+ * with the "auditSubjectID()".
+ * <P>
+ *
+ * @param SubjectID string containing the signed audit log message SubjectID
+ * @return a delimited string of groups associated
+ * with the "auditSubjectID()"
+ */
+ private String auditGroups(String SubjectID) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if ((SubjectID == null) ||
+ (SubjectID.equals(ILogger.UNIDENTIFIED))) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ Enumeration groups = null;
+
+ try {
+ groups = mUG.findGroups("*");
+ } catch (Exception e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ StringBuffer membersString = new StringBuffer();
+
+ while (groups.hasMoreElements()) {
+ IGroup group = (IGroup) groups.nextElement();
+
+ if (group.isMember(SubjectID) == true) {
+ if (membersString.length()!=0) {
+ membersString.append(", ");
+ }
+
+ membersString.append(group.getGroupID());
+ }
+ }
+
+ if (membersString.length()!= 0) {
+ return membersString.toString();
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+
+ protected NameValuePairs convertStringArrayToNVPairs(String[] s) {
+ if (s == null) return null;
+ NameValuePairs nvps = new NameValuePairs();
+ int i;
+
+ for (i = 0; i < s.length; i++) {
+ int j = s[i].indexOf(";");
+ String paramName = s[i].substring(0, j);
+ String args = s[i].substring(j + 1);
+
+ nvps.add(paramName, args);
+ }
+ return nvps;
+
+ }
+
+ protected static IExtendedPluginInfo getClassByNameAsExtendedPluginInfo(String className) {
+
+ IExtendedPluginInfo epi = null;
+
+ try {
+ // here is the new dummy obj created
+ Object o = Class.forName(className).newInstance();
+
+ epi = (IExtendedPluginInfo) o;
+ } catch (Exception e) {
+ }
+
+ return epi;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java
new file mode 100644
index 000000000..fd7edfabd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java
@@ -0,0 +1,1690 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.usrgrp.*;
+
+
+/**
+ * A class representing an administration servlet for the
+ * Authentication Management subsystem. This servlet is responsible
+ * to serve configuration requests for the Auths Management subsystem.
+ *
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthAdminServlet extends AdminServlet {
+
+ private final static String INFO = "AuthAdminServlet";
+ private IAuthSubsystem mAuths = null;
+
+ private final static String PW_PASSWORD_CACHE_ADD =
+ "PASSWORD_CACHE_ADD";
+ private final static String VIEW = ";" + Constants.VIEW;
+ private final static String EDIT = ";" + Constants.EDIT;
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_AUTH =
+ "LOGGING_SIGNED_AUDIT_CONFIG_AUTH_3";
+
+ public AuthAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mAuths = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ AUTHZ_RES_NAME = "certServer.auth.configuration";
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description, type info
+ * from policy, authentication,
+ * need to add: listener, mapper and publishing plugins
+ * --- same as policy, should we move this into extendedpluginhelper?
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+
+ NameValuePairs params =
+ getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+
+ impl = mAuths.getAuthManagerPlugin(implName);
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op == null) {
+ //System.out.println("SRVLT_INVALID_PROTOCOL");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ // if it is not authentication, that means it is for CSC admin ping.
+ // the best way to do is to define another protocol for ping and move
+ // it to the generic servlet which is admin servlet.
+ if (!op.equals(OpDef.OP_AUTH)) {
+ if (scope.equals(ScopeDef.SC_AUTH)) {
+ String id = req.getParameter(Constants.RS_ID);
+
+ // for CSC admin ping only
+ if (op.equals(OpDef.OP_READ) &&
+ id.equals(Constants.RS_ID_CONFIG)) {
+
+ // no need to authenticate this. if we're alive, return true.
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_PING, Constants.TRUE);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } else {
+ //System.out.println("SRVLT_INVALID_OP_TYPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_TYPE", op),
+ null, resp);
+ return;
+ }
+ }
+ }
+
+ try {
+ if (op.equals(OpDef.OP_AUTH)) {
+ if (scope.equals(ScopeDef.SC_AUTHTYPE)) {
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("authType", "pwd");
+ NameValuePairs params = new NameValuePairs();
+
+ params.add("authType", val);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ }
+ } catch (Exception e) {
+ sendResponse(ERROR,CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+ // for the rest
+ try {
+ super.authenticate(req);
+ if (op.equals(OpDef.OP_AUTH)) { // for admin authentication only
+ sendResponse(SUCCESS, null, null, resp);
+ return;
+ }
+ } catch (IOException e) {
+ //System.out.println("SRVLT_FAIL_AUTHS");
+ sendResponse(ERROR,CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+
+ try {
+ // perform operation based on scope
+ if (scope != null) {
+ AUTHZ_RES_NAME = "certServer.auth.configuration";
+ if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ try {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ getExtendedPluginInfo(req, resp);
+ return;
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ }
+ if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_AUTH_IMPLS)) {
+ listAuthMgrPlugins(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_AUTH_MGR_INSTANCE)) {
+ listAuthMgrInsts(req, resp);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_AUTH_IMPLS)) {
+ getConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_AUTH_MGR_INSTANCE)) {
+ getInstConfig(req, resp);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_AUTH_IMPLS)) {
+ addAuthMgrPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_AUTH_MGR_INSTANCE)) {
+ addAuthMgrInst(req, resp, scope);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_AUTH_IMPLS)) {
+ delAuthMgrPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_AUTH_MGR_INSTANCE)) {
+ delAuthMgrInst(req, resp, scope);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_AUTH_MGR_INSTANCE)) {
+ modAuthMgrInst(req, resp, scope);
+ return;
+ }
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ }
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+
+ private void putUserPWPair(String combo) {
+ int semicolon;
+
+ semicolon = combo.indexOf(";");
+ String user = combo.substring(0, semicolon);
+ String pw = combo.substring(semicolon + 1);
+
+ CMS.putPasswordCache(user, pw);
+ }
+
+ /**
+ * Add authentication manager plug-in
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_AUTH used when configuring
+ * authentication
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this authentication
+ * manager's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addAuthMgrPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+ // is the manager id unique?
+ if (mAuths.getPlugins().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_DUP_MGR_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_AUTH_CLASS);
+
+ if (classPath == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_NULL_AUTHMGR_CLASSNAME"),
+ null, resp);
+ return;
+ }
+
+ if (classPath.equals("com.netscape.cmscore.authentication.PasswdUserDBAuthentication") ||
+ classPath.equals("com.netscape.cmscore.authentication.CertUserDBAuthentication")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_PERMISSION_DENIED"), null, resp);
+ return;
+ }
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_AUTH_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_PLUGIN_NOT_FOUND"),
+ null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_PLUGIN_NOT_FOUND"),
+ null, resp);
+ return;
+ }
+
+ // is the class an IAuthManager?
+ try {
+ if (IAuthManager.class.isAssignableFrom(newImpl) == false) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_AUTH_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add manager to registry.
+ AuthMgrPlugin plugin = new AuthMgrPlugin(id, classPath);
+
+ mAuths.getPlugins().put(id, plugin);
+ mAuths.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_PLUGIN_ADD", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Add authentication manager instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_AUTH used when configuring
+ * authentication
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this authentication
+ * manager's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addAuthMgrInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the manager instance id unique?
+ if (mAuths.getInstances().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_ILL_MGR_INST_ID"),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ // SC_AUTH_IMPL_NAME is absolutely required, the rest depend on
+ // on each authenticaton manager
+ String implname = req.getParameter(Constants.PR_AUTH_IMPL_NAME);
+
+ if (implname == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_MISSING_PARAMS"),
+ null, resp);
+ return;
+ }
+
+ // prevent agent & admin creation.
+ if (implname.equals(IAuthSubsystem.PASSWDUSERDB_PLUGIN_ID) ||
+ implname.equals(IAuthSubsystem.CERTUSERDB_PLUGIN_ID)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_PERMISSION_DENIED"), null, resp);
+ }
+
+ // check if implementation exists.
+ AuthMgrPlugin plugin =
+ (AuthMgrPlugin) mAuths.getPlugins().get(implname);
+
+ if (plugin == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ new EAuthMgrPluginNotFound(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ // now the rest of config parameters
+ // note that we only check to see if the required parameters
+ // are there, but not checking the values are valid
+ String[] configParams = mAuths.getConfigParams(implname);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_AUTH_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+ String val = req.getParameter(key);
+
+ if (val != null) {
+ substore.put(key, val);
+ }
+ }
+ }
+ substore.put(IAuthSubsystem.PROP_PLUGIN, implname);
+
+ String pwadd = req.getParameter(PW_PASSWORD_CACHE_ADD);
+
+ if (pwadd != null) {
+ putUserPWPair(pwadd);
+ }
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ IAuthManager authMgrInst = null;
+
+ try {
+ authMgrInst = (IAuthManager) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // cleanup
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the authentication manager
+ try {
+ authMgrInst.init(id, implname, substore);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // clean up.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // inited and commited ok. now add manager instance to list.
+ mAuths.add(id, authMgrInst);
+
+ mAuths.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_MGR_ADD", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_AUTH_IMPL_NAME, implname);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private synchronized void listAuthMgrPlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mAuths.getPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ AuthMgrPlugin value = (AuthMgrPlugin)
+ mAuths.getPlugins().get(name);
+
+ if (value.isVisible()) {
+ params.add(name, value.getClassPath() + EDIT);
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listAuthMgrInsts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ for (Enumeration e = mAuths.getInstances().keys();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ AuthManagerProxy proxy = (AuthManagerProxy) mAuths.getInstances().get(name);
+ IAuthManager value = proxy.getAuthManager();
+ String enableStr = "enabled";
+
+ if (!proxy.isEnable()) {
+ enableStr = "disabled";
+ }
+
+ AuthMgrPlugin amgrplugin = (AuthMgrPlugin)
+ mAuths.getPlugins().get(value.getImplName());
+
+ if (!amgrplugin.isVisible()) {
+ params.add(name, value.getImplName() + ";invisible;" + enableStr);
+ } else {
+ params.add(name, value.getImplName() + ";visible;" + enableStr);
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Delete authentication manager plug-in
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_AUTH used when configuring
+ * authentication
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this authentication
+ * manager's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void delAuthMgrPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // prevent deletion of admin and agent.
+ if (id.equals(IAuthSubsystem.PASSWDUSERDB_PLUGIN_ID) ||
+ id.equals(IAuthSubsystem.CERTUSERDB_PLUGIN_ID)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_PERMISSION_DENIED"), null, resp);
+ }
+
+ // does auth manager exist?
+ if (mAuths.getPlugins().containsKey(id) == false) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ new EAuthMgrPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_AUTHENTICATION_DUP_MGR_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this auth manager
+ // DON'T remove auth manager if any instance
+ for (Enumeration e = mAuths.getInstances().keys();
+ e.hasMoreElements();) {
+ IAuthManager authMgr = (IAuthManager) mAuths.get((String) e.nextElement());
+
+ if (authMgr.getImplName() == id) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_MGR_IN_USE"),
+ null, resp);
+ return;
+ }
+ }
+
+ // then delete this auth manager
+ mAuths.getPlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_AUTH_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ }
+ }
+
+ /**
+ * Delete authentication manager instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_AUTH used when configuring
+ * authentication
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this authentication
+ * manager's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void delAuthMgrInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // prevent deletion of admin and agent.
+ if (id.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID) ||
+ id.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_PERMISSION_DENIED"), null, resp);
+ }
+
+ // does auth manager instance exist?
+ if (mAuths.getInstances().containsKey(id) == false) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ new EAuthMgrNotFound(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ IAuthManager mgrInst = (IAuthManager) mAuths.get(id);
+
+ mAuths.getInstances().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_AUTH_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ //This only works in the fact that we only support one instance per
+ //auth plugin.
+ ILdapAuthInfo authInfo = CMS.getLdapAuthInfo();
+
+ authInfo.removePassword("Rule " + id);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * used for getting the required configuration parameters (with
+ * possible default values) for a particular auth manager plugin
+ * implementation name specified in the RS_ID. Actually, there is
+ * no logic in here to set any default value here...there's no
+ * default value for any parameter in this authentication subsystem
+ * at this point. Later, if we do have one (or some), it can be
+ * added. The interface remains the same.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ String[] configParams = mAuths.getConfigParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_AUTH_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ params.add(configParams[i], "");
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does auth manager instance exist?
+ if (mAuths.getInstances().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EAuthMgrNotFound(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ IAuthManager mgrInst = (IAuthManager) mAuths.get(id);
+ IConfigStore config = mgrInst.getConfigStore();
+ String[] configParams = mgrInst.getConfigParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_AUTH_IMPL_NAME, mgrInst.getImplName());
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+ String val = (String) config.get(key);
+
+ if (val != null) {
+ params.add(key, val);
+ } else {
+ params.add(key, "");
+ }
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Modify authentication manager instance
+ * This will actually create a new instance with new configuration
+ * parameters and replace the old instance if the new instance is
+ * created and initialized successfully.
+ * The old instance is left running, so this is very expensive.
+ * Restart of server recommended.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_AUTH used when configuring
+ * authentication
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of this authentication
+ * manager's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modAuthMgrInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ // expensive operation.
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // prevent modification of admin and agent.
+ if (id.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID) ||
+ id.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_PERMISSION_DENIED"), null, resp);
+ }
+
+ // Does the manager instance exist?
+ if (!mAuths.getInstances().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage("CMS_AUTHENTICATION_MGR_IMPL_NOT_FOUND"),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_AUTH_IMPL_NAME);
+
+ if (implname == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage("CMS_AUTHENTICATION_MISSING_PARAMS"),
+ null, resp);
+ return;
+ }
+
+ // get plugin for implementation
+ AuthMgrPlugin plugin =
+ (AuthMgrPlugin) mAuths.getPlugins().get(implname);
+
+ if (plugin == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ new EAuthMgrPluginNotFound(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ IAuthManager oldinst =
+ (IAuthManager) mAuths.get(id);
+ IConfigStore oldConfig = oldinst.getConfigStore();
+
+ String[] oldConfigParms = oldinst.getConfigParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.add(IAuthSubsystem.PROP_PLUGIN,
+ (String) oldConfig.get(IAuthSubsystem.PROP_PLUGIN));
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.length; i++) {
+ String key = oldConfigParms[i];
+ Object val = oldConfig.get(key);
+
+ if (val != null) {
+ saveParams.add(key, (String) val);
+ }
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_AUTH_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+
+ // create new substore.
+
+ String[] configParams = mAuths.getConfigParams(implname);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(IAuthSubsystem.PROP_PLUGIN, implname);
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+ String val = req.getParameter(key);
+
+ if (val != null) {
+ substore.put(key, val);
+ }
+ }
+ }
+
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ IAuthManager newMgrInst = null;
+
+ try {
+ newMgrInst = (IAuthManager) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EAuthException(CMS.getUserMessage(getLocale(req),"CMS_AUTHENTICATION_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the authentication manager
+
+ try {
+ newMgrInst.init(id, implname, substore);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ mAuths.add(id, newMgrInst);
+
+ mAuths.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_MGR_REPL", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_AUTH,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ // convenience routine.
+ private static void restore(IConfigStore store,
+ String id, NameValuePairs saveParams) {
+ store.removeSubStore(id);
+ IConfigStore rstore = store.makeSubStore(id);
+
+ Enumeration keys = saveParams.getNames();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String value = saveParams.getValue(key);
+
+ if (value != null)
+ rstore.put(key, value);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java b/pki/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java
new file mode 100644
index 000000000..354015e13
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java
@@ -0,0 +1,100 @@
+// --- 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.servlet.admin;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * Authentication Credentials as input to the authMgr
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthCredentials implements IAuthCredentials {
+ private Hashtable authCreds = null;
+ // Inserted by bskim
+ private IArgBlock argblk = null;
+ // Insert end
+
+ public AuthCredentials() {
+ authCreds = new Hashtable();
+ }
+
+ /**
+ * sets a credential with credential name and the credential
+ * @param name credential name
+ * @param cred credential
+ * @exception com.netscape.certsrv.base.EBaseException NullPointerException
+ */
+ public void set(String name, Object cred)throws EBaseException {
+ if (cred == null) {
+ throw new EBaseException("AuthCredentials.set()");
+ }
+
+ authCreds.put(name, cred);
+ }
+
+ /**
+ * returns the credential to which the specified name is mapped in this
+ * credential set
+ * @param name credential name
+ * @return the named authentication credential
+ */
+ public Object get(String name) {
+ return ((Object) authCreds.get(name));
+ }
+
+ /**
+ * removes the name and its corresponding credential from this
+ * credential set. This method does nothing if the named
+ * credential is not in the credential set.
+ * @param name credential name
+ */
+ public void delete(String name) {
+ authCreds.remove(name);
+ }
+
+ /**
+ * returns an enumeration of the credentials in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ * @return an enumeration of the values in this credential set
+ * @see java.util.Enumeration
+ */
+ public Enumeration getElements() {
+ return (authCreds.elements());
+ }
+
+ // Inserted by bskim
+ public void setArgBlock(IArgBlock blk) {
+ argblk = blk;
+ return;
+ }
+
+ // Insert end
+
+ public IArgBlock getArgBlock() {
+ return argblk;
+ }
+ // Insert end
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java
new file mode 100644
index 000000000..5f2bf07c9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java
@@ -0,0 +1,1642 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.request.IRequestListener;
+
+
+/**
+ * A class representings an administration servlet for Certificate
+ * Authority. This servlet is responsible to serve CA
+ * administrative operations such as configuration parameter
+ * updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CAAdminServlet extends AdminServlet {
+
+ public final static String PROP_EMAIL_TEMPLATE = "emailTemplate";
+
+ private final static String INFO = "CAAdminServlet";
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE_3";
+
+ private ICertificateAuthority mCA = null;
+ protected static final String PROP_ENABLED = "enabled";
+
+ /**
+ * Constructs CA servlet.
+ */
+ public CAAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mCA = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. Each request is authenticated to
+ * the authenticate manager.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ //get all operational flags
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ //check operational flags
+ if ((op == null) || (scope == null)) {
+ sendResponse(1, "Invalid Protocol", null, resp);
+ return;
+ }
+
+ super.authenticate(req);
+
+ try {
+ AUTHZ_RES_NAME = "certServer.ca.configuration";
+ if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ try {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ getExtendedPluginInfo(req, resp);
+ return;
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ }
+ }
+
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL))
+ getGeneralConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CONNECTOR))
+ getConnectorConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRLIPS))
+ getCRLIPsConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRL))
+ getCRLConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_REQ_COMP))
+ getNotificationReqCompConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_REV_COMP))
+ getNotificationRevCompConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ))
+ getNotificationRIQConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRLEXTS_RULES))
+ getCRLExtsConfig(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL))
+ setGeneralConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CONNECTOR))
+ setConnectorConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRLIPS))
+ setCRLIPsConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRL))
+ setCRLConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_REQ_COMP))
+ setNotificationReqCompConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_REV_COMP))
+ setNotificationRevCompConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ))
+ setNotificationRIQConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRLEXTS_RULES))
+ setCRLExtsConfig(req, resp);
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_CRLEXTS_RULES))
+ listCRLExtsConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_CRLIPS))
+ listCRLIPsConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_CRLIPS))
+ addCRLIPsConfig(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_CRLIPS))
+ deleteCRLIPsConfig(req, resp);
+ } else {
+ sendResponse(1, "Unknown operation", null, resp);
+ }
+ } catch (Exception e) {
+ sendResponse(1, e.toString(), null, resp);
+ return;
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /*
+ * handle request completion (cert issued) notification config requests
+ */
+ private void getNotificationCompConfig(HttpServletRequest req,
+ HttpServletResponse resp, IConfigStore rc) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, rc.getString(name, ""));
+ }
+
+ params.add(Constants.PR_ENABLE,
+ rc.getString(PROP_ENABLED, Constants.FALSE));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getNotificationRevCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(mCA.PROP_CERT_REVOKED_SUBSTORE);
+
+ getNotificationCompConfig(req, resp, rc);
+ }
+
+ private void getNotificationReqCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(mCA.PROP_CERT_ISSUED_SUBSTORE);
+
+ getNotificationCompConfig(req, resp, rc);
+ }
+
+ /*
+ * handle getting request in queue notification config info
+ */
+ private void getNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mCA.PROP_REQ_IN_Q_SUBSTORE);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, riq.getString(name, ""));
+ }
+
+ params.add(Constants.PR_ENABLE,
+ riq.getString(PROP_ENABLED, Constants.FALSE));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /*
+ * handle setting request in queue notification config info
+ */
+ private void setNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mCA.PROP_REQ_IN_Q_SUBSTORE);
+
+ //set rest of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String val = req.getParameter(name);
+
+ // if it's emailTemplate, check to see if the path exists
+ if (name.equalsIgnoreCase(PROP_EMAIL_TEMPLATE)) {
+ File template = new File(val);
+
+ if ((!template.exists()) || (!template.canRead())
+ || (template.isDirectory())) {
+ String error =
+ "Template: " + val + " does not exist or invalid";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_INVALID_PATH"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PATH"),
+ null, resp);
+ return;
+ }
+ }
+ riq.putString(name, val);
+ mCA.getRequestInQListener().set(name, val);
+ }
+
+ // set enable flag
+ String enabledString = req.getParameter(Constants.PR_ENABLE);
+
+ riq.putString(PROP_ENABLED, enabledString);
+ mCA.getRequestInQListener().set(PROP_ENABLED, enabledString);
+
+ commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /*
+ * handle setting request complete notification config info
+ */
+ private void setNotificationCompConfig(HttpServletRequest req,
+ HttpServletResponse resp, IConfigStore rc, IRequestListener thisListener) throws ServletException,
+ IOException, EBaseException {
+
+ //set rest of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String val = req.getParameter(name);
+
+ // if it's emailTemplate, check to see if the path exists
+ if (name.equalsIgnoreCase(PROP_EMAIL_TEMPLATE)) {
+ File template = new File(val);
+
+ if ((!template.exists()) || (!template.canRead())
+ || (template.isDirectory())) {
+ String error =
+ "Template: " + val + " does not exist or invalid";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_INVALID_PATH"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PATH"),
+ null, resp);
+ return;
+ }
+ }
+ rc.putString(name, val);
+ thisListener.set(name, val);
+ }
+
+ // set enable flag
+ String enabledString = req.getParameter(Constants.PR_ENABLE);
+
+ rc.putString(PROP_ENABLED, enabledString);
+ thisListener.set(PROP_ENABLED, enabledString);
+
+ commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void setNotificationRevCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mCA.PROP_CERT_REVOKED_SUBSTORE);
+
+ setNotificationCompConfig(req, resp, rc, mCA.getCertRevokedListener());
+ }
+
+ private void setNotificationReqCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mCA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mCA.PROP_CERT_ISSUED_SUBSTORE);
+
+ setNotificationCompConfig(req, resp, rc, mCA.getCertIssuedListener());
+
+ }
+
+ private void listCRLIPsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (ip != null) {
+ String ipId = ip.getId();
+
+ if (ipId != null && ipId.length() > 0)
+ params.add(ipId, ip.getDescription());
+ params.add(ipId + "." + Constants.PR_ENABLED,
+ (Boolean.valueOf(ip.isCRLIssuingPointEnabled())).toString());
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getCRLIPsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id != null && id.length() > 0) {
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(id);
+
+ if (ip != null) {
+
+ Enumeration e = req.getParameterNames();
+ String value = "";
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.PR_ENABLED)) {
+ if (ip.isCRLIssuingPointEnabled()) {
+ value = Constants.TRUE;
+ } else {
+ value = Constants.FALSE;
+ }
+ }
+ if (name.equals(Constants.PR_ID))
+ value = id;
+ if (name.equals(Constants.PR_DESCRIPTION))
+ value = ip.getDescription();
+ if (name.equals(Constants.PR_CLASS))
+ value = ip.getClass().getName();
+
+ params.add(name, value);
+ }
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Add CRL issuing points configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE used when
+ * configuring CRL profile (extensions, frequency, CRL format)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void addCRLIPsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String ipId = req.getParameter(Constants.PR_ID);
+
+ if (ipId == null || ipId.length() == 0) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP name", null, resp);
+ return;
+ }
+ params.add(Constants.PR_ID, ipId);
+
+ String desc = req.getParameter(Constants.PR_DESCRIPTION);
+
+ if (desc == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP description", null, resp);
+ return;
+ }
+ params.add(Constants.PR_DESCRIPTION, desc);
+
+ String sEnable = req.getParameter(Constants.PR_ENABLED);
+ boolean enable = true;
+
+ if (sEnable != null && sEnable.length() > 0 &&
+ sEnable.equalsIgnoreCase(Constants.FALSE)) {
+ enable = false;
+ params.add(Constants.PR_ENABLED, Constants.FALSE);
+ } else {
+ params.add(Constants.PR_ENABLED, Constants.TRUE);
+ }
+
+ IConfigStore crlSubStore =
+ mCA.getConfigStore().getSubStore(mCA.PROP_CRL_SUBSTORE);
+ Enumeration crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = (String) crlNames.nextElement();
+
+ if (ipId.equals(name)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, ipId + " CRL IP already exists", null, resp);
+ return;
+ }
+ }
+ if (!mCA.addCRLIssuingPoint(crlSubStore, ipId, enable, desc)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Cannot add or edit CRL IP", null, resp);
+ return;
+ }
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Set CRL issuing points configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE used when
+ * configuring CRL profile (extensions, frequency, CRL format)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setCRLIPsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String ipId = req.getParameter(Constants.PR_ID);
+
+ if (ipId == null || ipId.length() == 0) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP name", null, resp);
+ return;
+ }
+ params.add(Constants.PR_ID, ipId);
+
+ String desc = req.getParameter(Constants.PR_DESCRIPTION);
+
+ if (desc == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP description", null, resp);
+ return;
+ }
+ params.add(Constants.PR_DESCRIPTION, desc);
+
+ String sEnable = req.getParameter(Constants.PR_ENABLED);
+ boolean enable = true;
+
+ if (sEnable != null && sEnable.length() > 0 &&
+ sEnable.equalsIgnoreCase(Constants.FALSE)) {
+ enable = false;
+ params.add(Constants.PR_ENABLED, Constants.FALSE);
+ } else {
+ params.add(Constants.PR_ENABLED, Constants.TRUE);
+ }
+
+ IConfigStore crlSubStore =
+ mCA.getConfigStore().getSubStore(mCA.PROP_CRL_SUBSTORE);
+ boolean done = false;
+ Enumeration crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = (String) crlNames.nextElement();
+
+ if (ipId.equals(name)) {
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(ipId);
+
+ if (ip != null) {
+ ip.setDescription(desc);
+ ip.enableCRLIssuingPoint(enable);
+ }
+ IConfigStore c = crlSubStore.getSubStore(ipId);
+
+ if (c != null) {
+ c.putString(Constants.PR_DESCRIPTION, desc);
+ c.putString(Constants.PR_ENABLED,
+ (enable) ? Constants.TRUE : Constants.FALSE);
+ }
+ done = true;
+ break;
+ }
+ }
+ if (!done) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP " + ipId, null, resp);
+ return;
+ }
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Delete CRL issuing points configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE used when
+ * configuring CRL profile (extensions, frequency, CRL format)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void deleteCRLIPsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id != null && id.length() > 0) {
+ IConfigStore crlSubStore =
+ mCA.getConfigStore().getSubStore(mCA.PROP_CRL_SUBSTORE);
+ boolean done = false;
+ Enumeration crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = (String) crlNames.nextElement();
+
+ if (id.equals(name)) {
+ mCA.deleteCRLIssuingPoint(crlSubStore, id);
+ done = true;
+ break;
+ }
+ }
+ if (!done) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, "Missing CRL IP " + id, null, resp);
+ return;
+ }
+ commit(true);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void getCRLExtsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ String ipId = null;
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ ipId = name;
+ }
+ if (ipId == null || ipId.length() <= 0) {
+ ipId = ICertificateAuthority.PROP_MASTER_CRL;
+ }
+
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(ipId);
+ ICMSCRLExtensions crlExts = ip.getCRLExtensions();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id != null) {
+ params = crlExts.getConfigParams(id);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Delete CRL extensions configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE used when
+ * configuring CRL profile (extensions, frequency, CRL format)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setCRLExtsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String ipId = req.getParameter(Constants.PR_ID);
+
+ if (ipId == null || ipId.length() <= 0) {
+ ipId = ICertificateAuthority.PROP_MASTER_CRL;
+ }
+
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(ipId);
+ ICMSCRLExtensions crlExts = ip.getCRLExtensions();
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore =
+ config.getSubStore(mCA.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(ipId);
+ IConfigStore crlExtsSubStore =
+ crlSubStore.getSubStore(mCA.PROP_CRLEXT_SUBSTORE);
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id != null) {
+ IConfigStore crlExtSubStore = crlExtsSubStore.getSubStore(id);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_CRLEXT_IMPL_NAME))
+ continue;
+ if (name.equals("RULENAME"))
+ continue;
+ String value = req.getParameter(name);
+
+ params.add(name, value);
+ }
+ crlExts.setConfigParams(id, params, crlExtSubStore);
+ commit(true);
+ ip.clearCRLCache();
+ ip.updateCRLCacheRepository();
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void listCRLExtsConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.PR_ID);
+
+ if (id == null || id.length() <= 0) {
+ id = mCA.PROP_MASTER_CRL;
+ }
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore = config.getSubStore(mCA.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+ IConfigStore crlExtsSubStore = crlSubStore.getSubStore(mCA.PROP_CRLEXT_SUBSTORE);
+
+ if (crlExtsSubStore != null) {
+ Enumeration enumExts = crlExtsSubStore.getSubStoreNames();
+
+ while (enumExts.hasMoreElements()) {
+ String extName = (String) enumExts.nextElement();
+ boolean crlExtEnabled = false;
+ IConfigStore crlExtSubStore = crlExtsSubStore.getSubStore(extName);
+ Enumeration properties = crlExtSubStore.getPropertyNames();
+
+ while (properties.hasMoreElements()) {
+ String name = (String) properties.nextElement();
+
+ if (name.equals(Constants.PR_ENABLE)) {
+ crlExtEnabled = crlExtSubStore.getBoolean(name, false);
+ }
+ }
+ params.add(extName, extName + ";visible;" + ((crlExtEnabled) ? "enabled" : "disabled"));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description,
+ * type info from CRL extensions
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+
+ NameValuePairs params =
+ getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+
+ String ipId = null;
+ String name = null;
+
+ Enumeration ips = mCA.getCRLIssuingPoints();
+ if (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+ if (ip != null) {
+ ipId = ip.getId();
+ }
+ }
+ if (ipId != null) {
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(ipId);
+ ICMSCRLExtensions crlExts = ip.getCRLExtensions();
+ name = crlExts.getClassPath(implName);
+ }
+ if (name != null) {
+ impl = getClassByNameAsExtendedPluginInfo(name);
+ }
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+ }
+
+ /**
+ * Set CRL configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE used when
+ * configuring CRL profile (extensions, frequency, CRL format)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setCRLConfig(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null || id.length() <= 0 ||
+ id.equals(Constants.RS_ID_CONFIG)) {
+ id = mCA.PROP_MASTER_CRL;
+ }
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(id);
+
+ //Save New Settings to the config file
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore = config.getSubStore(mCA.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+
+ //set reset of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String value = req.getParameter(name);
+
+ params.add(name, value);
+ crlSubStore.putString(name, value);
+ }
+ boolean noRestart = ip.updateConfig(params);
+
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ if (noRestart)
+ sendResponse(SUCCESS, null, null, resp);
+ else
+ sendResponse(RESTART, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CRL_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void getCRLConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null || id.length() <= 0 ||
+ id.equals(Constants.RS_ID_CONFIG)) {
+ id = mCA.PROP_MASTER_CRL;
+ }
+ IConfigStore crlsSubStore =
+ mCA.getConfigStore().getSubStore(mCA.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, crlSubStore.getString(name, ""));
+ }
+
+ getSigningAlgConfig(params);
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getConnectorConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore caConfig = mCA.getConfigStore();
+ IConfigStore connectorConfig = caConfig.getSubStore("connector");
+ IConfigStore caConnectorConfig = null;
+
+ if (isKRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("KRA");
+ } else if (isCLAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("CLA");
+ }
+
+ Enumeration enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+
+ params.add(name, caConnectorConfig.getString(name, ""));
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setConnectorConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore caConfig = mCA.getConfigStore();
+ IConfigStore connectorConfig = caConfig.getSubStore("connector");
+ IConfigStore caConnectorConfig = null;
+
+// String nickname = CMS.getServerCertNickname();
+
+ if (isKRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("KRA");
+ } else if (isCLAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("CLA");
+ }
+
+ Enumeration enum1 = req.getParameterNames();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+/*
+ if (name.equals("nickName")) {
+ caConnectorConfig.putString(name, nickname);
+ continue;
+ }
+*/
+ if (name.equals("host")) {
+ try {
+ Utils.checkHost(req.getParameter("host"));
+ } catch (UnknownHostException e) {
+ sendResponse(ERROR, "Unknown Host " + req.getParameter("host"), null, resp);
+ return;
+ }
+ }
+ caConnectorConfig.putString(name, req.getParameter(name));
+ }
+ }
+
+ commit(true);
+ sendResponse(RESTART, null, null, resp);
+ }
+
+ private boolean isKRAConnector(HttpServletRequest req) {
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+
+ if (val.equals("Data Recovery Manager Connector"))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private boolean isCLAConnector(HttpServletRequest req) {
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+
+ if (val.equals("Clone Master Manager Connector"))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private void getGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String value = "false";
+
+ /*
+ ISubsystem eeGateway =
+ SubsystemRegistry.getInstance().get("eeGateway");
+ if (eeGateway != null) {
+ IConfigStore eeConfig = eeGateway.getConfigStore();
+ if (eeConfig != null)
+ value = eeConfig.getString("enabled", "true");
+ String ocspValue = "true";
+ ocspValue = eeConfig.getString("enableOCSP", "true");
+ params.add(Constants.PR_OCSP_ENABLED, ocspValue);
+ }
+ params.add(Constants.PR_EE_ENABLED, value);
+ */
+
+
+ IConfigStore caConfig = mCA.getConfigStore();
+
+ value = caConfig.getString(mCA.PROP_ENABLE_PAST_CATIME, "false");
+ params.add(Constants.PR_VALIDITY, value);
+
+ getSigningAlgConfig(params);
+ getSerialConfig(params);
+ getMaxSerialConfig(params);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getSigningAlgConfig(NameValuePairs params) {
+ params.add(Constants.PR_DEFAULT_ALGORITHM,
+ mCA.getDefaultAlgorithm());
+ String[] algorithms = mCA.getCASigningAlgorithms();
+ StringBuffer algorStr = new StringBuffer();
+
+ for (int i = 0; i < algorithms.length; i++) {
+ if (i == 0)
+ algorStr.append(algorithms[i]);
+ else {
+ algorStr.append(":");
+ algorStr.append(algorithms[i]);
+ }
+ }
+ params.add(Constants.PR_ALL_ALGORITHMS, algorStr.toString());
+ }
+
+ private void getSerialConfig(NameValuePairs params) {
+ params.add(Constants.PR_SERIAL,
+ mCA.getStartSerial());
+ }
+
+ private void getMaxSerialConfig(NameValuePairs params) {
+ params.add(Constants.PR_MAXSERIAL,
+ mCA.getMaxSerial());
+ }
+
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ ISubsystem eeGateway = null;
+
+ /*
+ ISubsystem eeGateway =
+ SubsystemRegistry.getInstance().get("eeGateway");
+ */
+ IConfigStore eeConfig = null;
+
+ if (eeGateway != null)
+ eeConfig = eeGateway.getConfigStore();
+ IConfigStore caConfig = mCA.getConfigStore();
+
+ Enumeration enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ //mCA.setMaxSerial("");
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_EE_ENABLED)) {
+
+ /*
+ if (eeConfig != null) {
+ if (((EEGateway)eeGateway).isEnabled() &&
+ value.equals("false") ||
+ !((EEGateway)eeGateway).isEnabled() &&
+ value.equals("true")) {
+ restart=true;;
+ }
+ eeConfig.putString("enabled", value);
+ }
+ */
+ } else if (key.equals(Constants.PR_VALIDITY)) {
+ mCA.setValidity(value);
+ } else if (key.equals(Constants.PR_DEFAULT_ALGORITHM)) {
+ mCA.setDefaultAlgorithm(value);
+ } else if (key.equals(Constants.PR_SERIAL)) {
+ mCA.setStartSerial(value);
+ } else if (key.equals(Constants.PR_MAXSERIAL)) {
+ mCA.setMaxSerial(value);
+ }
+ }
+
+ commit(true);
+ if (restart)
+ sendResponse(RESTART, null, null, resp);
+ else
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /**
+ * Retrieves configuration parameters of certificate
+ * authority.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ // validate
+ super.getConfig(mCA.getConfigStore(), req, resp);
+ }
+
+ /**
+ * Sets configuration parameters of certificate
+ * authority.
+ */
+ private synchronized void setConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ super.setConfig(mCA.getConfigStore(), req, resp);
+ // XXX - commit changes
+ }
+
+ /**
+ * Lists configuration store parameters.
+ */
+ private synchronized void listConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ super.listConfig(mCA.getConfigStore(), req, resp);
+ }
+
+ /**
+ * Locks a request so that no one can modify it except
+ * owner.
+ */
+ private synchronized void lockRequest(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ // XXX
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Locks certificate record so that no one can
+ * modify it except owner.
+ */
+ private synchronized void lockCertRecord(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Modifies a cert record.
+ */
+ private synchronized void modifyCertRecord(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ // XXX
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "CAAdminServlet: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
new file mode 100644
index 000000000..b735f0f10
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
@@ -0,0 +1,3677 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.selftests.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.tks.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.cert.ICrossCertPairSubsystem;
+import com.netscape.cmsutil.util.*;
+import com.netscape.cms.servlet.common.CMSGateway;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import com.netscape.symkey.*;
+
+/**
+ * A class representings an administration servlet. This
+ * servlet is responsible to serve Certificate Server
+ * level administrative operations such as configuration
+ * parameter updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public final class CMSAdminServlet extends AdminServlet {
+
+ private final static String INFO = "CMSAdminServlet";
+ private final static String BEGIN_HEADER = "-----BEGIN CERTIFICATE-----";
+ private final static String END_HEADER = "-----END CERTIFICATE-----";
+
+ private final static String PROP_DB = "dbs";
+ private final static String PROP_SMTP = "smtp";
+ private final static String PROP_RADM = "radm";
+ private final static String PROP_GATEWAY = "cmsgateway";
+ private final static String PROP_INTERNAL_DB = "internaldb";
+
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION_3";
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY =
+ "LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY_3";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC =
+ "LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC_3";
+ private final static String LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION =
+ "LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION_2";
+ private final static String LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION =
+ "LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION_3";
+
+ // CMS must be instantiated before this admin servlet.
+
+ /**
+ * Constructs CA servlet.
+ */
+ public CMSAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+ try {
+ super.authenticate(req);
+ } catch (IOException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ try {
+ AUTHZ_RES_NAME = "certServer.general.configuration";
+ if (scope.equals(ScopeDef.SC_PLATFORM)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ getEnv(req, resp);
+ return;
+ }
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LDAP))
+ getDBConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_SMTP))
+ readSMTPConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_STAT))
+ readStat(req, resp);
+ else if (scope.equals(ScopeDef.SC_ENCRYPTION))
+ readEncryption(req, resp);
+ else if (scope.equals(ScopeDef.SC_TOKEN))
+ getAllTokenNames(req, resp);
+ else if (scope.equals(ScopeDef.SC_SUBJECT_NAME))
+ getSubjectName(req, resp);
+ else if (scope.equals(ScopeDef.SC_GET_NICKNAMES))
+ getAllNicknames(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LDAP))
+ setDBConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_SMTP))
+ modifySMTPConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_TASKS))
+ performTasks(req, resp);
+ else if (scope.equals(ScopeDef.SC_ENCRYPTION))
+ modifyEncryption(req, resp);
+ else if (scope.equals(ScopeDef.SC_ISSUE_IMPORT_CERT))
+ issueImportCert(req, resp);
+ else if (scope.equals(ScopeDef.SC_INSTALL_CERT))
+ installCert(req, resp);
+ else if (scope.equals(ScopeDef.SC_IMPORT_CROSS_CERT))
+ importXCert(req, resp);
+ else if (scope.equals(ScopeDef.SC_DELETE_CERTS))
+ deleteCerts(req, resp);
+ else if (scope.equals(ScopeDef.SC_TRUST))
+ trustCACert(req, resp);
+ else if (scope.equals(ScopeDef.SC_TOKEN_LOGON))
+ loggedInToken(req, resp);
+ else if (scope.equals(ScopeDef.SC_ROOTCERT_TRUSTBIT))
+ setRootCertTrust(req, resp);
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_SUBSYSTEM))
+ readSubsystem(req, resp);
+ else if (scope.equals(ScopeDef.SC_CA_CERTLIST))
+ getCACerts(req, resp);
+ else if (scope.equals(ScopeDef.SC_ALL_CERTLIST))
+ getAllCertsManage(req, resp);
+ else if (scope.equals(ScopeDef.SC_USERCERTSLIST))
+ getUserCerts(req, resp);
+ else if (scope.equals(ScopeDef.SC_TKSKEYSLIST))
+ getTKSKeys(req, resp);
+ else if (scope.equals(ScopeDef.SC_TOKEN))
+ getAllTokenNames(req, resp);
+ else if (scope.equals(ScopeDef.SC_ROOTCERTSLIST))
+ getRootCerts(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "delete";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_ROOTCERTSLIST)) {
+ deleteRootCert(req, resp);
+ } else if (scope.equals(ScopeDef.SC_USERCERTSLIST)) {
+ deleteUserCert(req,resp);
+ }
+ } else if (op.equals(OpDef.OP_PROCESS)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_CERT_REQUEST))
+ getCertRequest(req, resp);
+ else if (scope.equals(ScopeDef.SC_SUBJECT_NAME))
+ processSubjectName(req, resp);
+ else if (scope.equals(ScopeDef.SC_CERTINFO))
+ getCertInfo(req, resp);
+ else if (scope.equals(ScopeDef.SC_CERT_PRETTY_PRINT))
+ getCertPrettyPrint(req, resp);
+ else if (scope.equals(ScopeDef.SC_ROOTCERT_TRUSTBIT))
+ getRootCertTrustBit(req, resp);
+ else if (scope.equals(ScopeDef.SC_TOKEN_STATUS))
+ checkTokenStatus(req, resp);
+ else if (scope.equals(ScopeDef.SC_SELFTESTS))
+ runSelfTestsOnDemand(req, resp);
+ else if (scope.equals(ScopeDef.SC_TKSKEYSLIST))
+ createMasterKey(req, resp);
+ } else if (op.equals(OpDef.OP_VALIDATE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_SUBJECT_NAME))
+ validateSubjectName(req, resp);
+ else if (scope.equals(ScopeDef.SC_KEY_LENGTH))
+ validateKeyLength(req, resp);
+ else if (scope.equals(ScopeDef.SC_CERTIFICATE_EXTENSION))
+ validateCertExtension(req, resp);
+ else if (scope.equals(ScopeDef.SC_KEY_CURVENAME))
+ validateCurveName(req, resp);
+ }
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)),
+ null, resp);
+ return;
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+
+ e.printStackTrace(new PrintWriter(sw));
+
+ sendResponse(1, "operation failure", null, resp);
+ return;
+ }
+ }
+
+ private void getEnv(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ if (File.separator.equals("\\"))
+ params.add(Constants.PR_NT, Constants.TRUE);
+ else
+ params.add(Constants.PR_NT, Constants.FALSE);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getAllTokenNames(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_TOKEN_LIST, jssSubSystem.getTokenList());
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getAllNicknames(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ params.add(Constants.PR_ALL_NICKNAMES, jssSubSystem.getAllCerts());
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private boolean isSubsystemInstalled(String subsystem) {
+ Enumeration e = CMS.getSubsystems();
+
+ while (e.hasMoreElements()) {
+ String type = "";
+ ISubsystem sys = (ISubsystem) e.nextElement();
+
+ //get subsystem type
+ if ((sys instanceof IKeyRecoveryAuthority) &&
+ subsystem.equals("kra"))
+ return true;
+ else if ((sys instanceof IRegistrationAuthority) &&
+ subsystem.equals("ra"))
+ return true;
+ else if ((sys instanceof ICertificateAuthority) &&
+ subsystem.equals("ca"))
+ return true;
+ else if ((sys instanceof IOCSPAuthority) &&
+ subsystem.equals("ocsp"))
+ return true;
+ }
+
+ return false;
+ }
+
+ private void readEncryption(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ Enumeration e = CMS.getSubsystems();
+ boolean isCAInstalled = false;
+ boolean isRAInstalled = false;
+ boolean isKRAInstalled = false;
+ boolean isOCSPInstalled = false;
+ boolean isTKSInstalled = false;
+
+ while (e.hasMoreElements()) {
+ String type = "";
+ ISubsystem sys = (ISubsystem) e.nextElement();
+
+ //get subsystem type
+ if (sys instanceof IKeyRecoveryAuthority)
+ isKRAInstalled = true;
+ else if (sys instanceof IRegistrationAuthority)
+ isRAInstalled = true;
+ else if (sys instanceof ICertificateAuthority)
+ isCAInstalled = true;
+ else if (sys instanceof IOCSPAuthority)
+ isOCSPInstalled = true;
+ else if (sys instanceof ITKSAuthority)
+ isTKSInstalled = true;
+
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String caTokenName = "";
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_CIPHER_VERSION,
+ jssSubSystem.getCipherVersion());
+ params.add(Constants.PR_CIPHER_FORTEZZA, jssSubSystem.isCipherFortezza());
+ params.add(Constants.PR_CIPHER_PREF, jssSubSystem.getCipherPreferences());
+
+ String tokenList = jssSubSystem.getTokenList();
+
+ String tokenNewList = "";
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ",");
+
+ while (tokenizer.hasMoreElements()) {
+ String tokenName = (String) tokenizer.nextElement();
+ String certs = jssSubSystem.getCertListWithoutTokenName(tokenName);
+
+ if (certs.equals(""))
+ continue;
+ if (tokenNewList.equals(""))
+ tokenNewList = tokenNewList + tokenName;
+ else
+ tokenNewList = tokenNewList + "," + tokenName;
+ tokenName = escapeString(tokenName);
+ params.add(Constants.PR_TOKEN_PREFIX + tokenName, certs);
+ }
+
+ params.add(Constants.PR_TOKEN_LIST, tokenNewList);
+
+ if (isCAInstalled) {
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getSigningUnit();
+
+ caTokenName = signingUnit.getTokenName();
+
+ if (caTokenName.equals(jssSubSystem.getInternalTokenName()))
+ caTokenName = Constants.PR_INTERNAL_TOKEN;
+
+ String caNickName = signingUnit.getNickname();
+
+ //params.add(Constants.PR_CERT_CA, caTokenName+","+caNickName);
+ params.add(Constants.PR_CERT_CA, getCertNickname(caNickName));
+ }
+
+ if (isRAInstalled) {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+ String raNickname = ra.getNickname();
+
+ params.add(Constants.PR_CERT_RA, getCertNickname(raNickname));
+ }
+
+ if (isKRAInstalled) {
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+ String kraNickname = kra.getNickname();
+
+ params.add(Constants.PR_CERT_TRANS, getCertNickname(kraNickname));
+ }
+ if (isTKSInstalled) {
+ ITKSAuthority tks = (ITKSAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_TKS);
+ }
+ String nickName = CMS.getServerCertNickname();
+
+ params.add(Constants.PR_CERT_SERVER, getCertNickname(nickName));
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private String escapeString(String name) {
+ StringTokenizer tokenizer = new StringTokenizer(name, " ");
+ StringBuffer tokenname = new StringBuffer();
+
+ if (tokenizer.countTokens() == 1)
+ return name;
+ while (tokenizer.hasMoreElements()) {
+ if (tokenizer.countTokens() == 1)
+ tokenname.append((String) tokenizer.nextElement());
+ else {
+ tokenname.append((String) tokenizer.nextElement());
+ tokenname.append("%20");
+ }
+ }
+
+ return tokenname.toString();
+ }
+
+ private String getCertNickname(String nickName) {
+ if (!nickName.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(nickName, ":");
+ String tokenName = "";
+
+ if (tokenizer.countTokens() > 1) {
+ tokenName = (String) tokenizer.nextElement();
+ } else {
+ tokenName = Constants.PR_INTERNAL_TOKEN;
+ }
+ return tokenName + "," + ((String) tokenizer.nextElement());
+ }
+ return "";
+ }
+
+ /**
+ * Modify encryption configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION used when
+ * configuring encryption (cert settings and SSL cipher preferences)
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to modify encryption configuration
+ */
+ private void modifyEncryption(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ Enumeration enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ jssSubSystem.getInternalTokenName();
+ Enumeration e = CMS.getSubsystems();
+ boolean isCAInstalled = false;
+ boolean isRAInstalled = false;
+ boolean isKRAInstalled = false;
+ boolean isOCSPInstalled = false;
+ boolean isTKSInstalled = false;
+
+ while (e.hasMoreElements()) {
+ String type = "";
+ ISubsystem sys = (ISubsystem) e.nextElement();
+
+ //get subsystem type
+ if (sys instanceof IKeyRecoveryAuthority)
+ isKRAInstalled = true;
+ else if (sys instanceof IRegistrationAuthority)
+ isRAInstalled = true;
+ else if (sys instanceof ICertificateAuthority)
+ isCAInstalled = true;
+ else if (sys instanceof IOCSPAuthority)
+ isOCSPInstalled = true;
+ else if (sys instanceof ITKSAuthority)
+ isTKSInstalled = true;
+ }
+
+ ICertificateAuthority ca = null;
+ IRegistrationAuthority ra = null;
+ IKeyRecoveryAuthority kra = null;
+ ITKSAuthority tks = null;
+
+ if (isCAInstalled)
+ ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ if (isRAInstalled)
+ ra = (IRegistrationAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+ if (isKRAInstalled)
+ kra = (IKeyRecoveryAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+ if (isTKSInstalled)
+ tks = (ITKSAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_TKS);
+
+ boolean isCACert = true;
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+ String val = req.getParameter(name);
+
+ if (name.equals(Constants.PR_CIPHER_PREF)) {
+ jssSubSystem.setCipherPreferences(val);
+ } else if (name.equals(Constants.PR_CERT_CA)) {
+ ISigningUnit signingUnit = ca.getSigningUnit();
+
+ if ((val != null) && (!val.equals(""))) {
+ StringTokenizer tokenizer = new StringTokenizer(val, ",");
+
+ if (tokenizer.countTokens() != 2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getLogMessage("BASE_INVALID_UI_INFO"));
+ }
+
+ String tokenName = (String) tokenizer.nextElement();
+ String nickName = (String) tokenizer.nextElement();
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN)) {
+ tokenName = jssSubSystem.getInternalTokenName();
+ } else {
+ nickName = tokenName + ":" + nickName;
+ }
+
+ isCACert = jssSubSystem.isCACert(nickName);
+ if (isCACert) {
+ signingUnit.updateConfig(nickName, tokenName);
+ } else
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getLogMessage("BASE_NOT_CA_CERT"));
+ }
+ } else if (name.equals(Constants.PR_CERT_RA)) {
+ if ((val != null) && (!val.equals(""))) {
+ String nickName = getCertConfigNickname(val);
+
+ ra.setNickname(nickName);
+ }
+ } else if (name.equals(Constants.PR_CERT_TRANS)) {
+ if ((val != null) && (!val.equals(""))) {
+ String nickName = getCertConfigNickname(val);
+
+ kra.setNickname(nickName);
+ }
+ } else if (name.equals(Constants.PR_CERT_SERVER)) {
+ if ((val != null) && (!val.equals(""))) {
+ String nickName = getCertConfigNickname(val);
+
+ modifyRADMCert(nickName);
+ modifyAgentGatewayCert(nickName);
+ if (isRAInstalled)
+ modifyEEGatewayCert(ra, nickName);
+ if (isCAInstalled)
+ modifyCAGatewayCert(ca, nickName);
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(RESTART, null, params, resp);
+ mConfig.commit(true);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private String getCertConfigNickname(String val) throws EBaseException {
+ StringTokenizer tokenizer = new StringTokenizer(val, ",");
+
+ if (tokenizer.countTokens() != 2) {
+ throw new EBaseException(CMS.getLogMessage("BASE_INVALID_UI_INFO"));
+ }
+ String tokenName = (String) tokenizer.nextElement();
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN))
+ tokenName = "";
+ else
+ tokenName = tokenName + ":";
+ return (tokenName + (String) tokenizer.nextElement());
+ }
+
+ private void modifyRADMCert(String nickName) {
+ CMS.setServerCertNickname(nickName);
+
+ /*
+ RemoteAdmin raAdmin = (RemoteAdmin)RemoteAdmin.getInstance();
+ HTTPService httpsService = raAdmin.getHttpsService();
+ httpsService.setNickName(nickName);
+ */
+ }
+
+ private void modifyAgentGatewayCert(String nickName) {
+ CMS.setServerCertNickname(nickName);
+
+ /*
+ AgentGateway gateway = (AgentGateway)mReg.get(AgentGateway.ID);
+ HTTPService httpsService = gateway.getHttpsService();
+ httpsService.setNickName(nickName);
+ */
+ }
+
+ private void modifyEEGatewayCert(IRegistrationAuthority ra, String nickName) {
+ CMS.setServerCertNickname(nickName);
+
+ /*
+ HTTPSubsystem eeGateway = ra.getHTTPSubsystem();
+ HTTPService httpsService = eeGateway.getHttpsService();
+ httpsService.setNickName(nickName);
+ */
+ }
+
+ private void modifyCAGatewayCert(ICertificateAuthority ca, String nickName) {
+ CMS.setServerCertNickname(nickName);
+
+ /*
+ HTTPSubsystem caGateway = ca.getHTTPSubsystem();
+ HTTPService httpsService = caGateway.getHttpsService();
+ httpsService.setNickName(nickName);
+ */
+ }
+
+ /**
+ * Performs Server Tasks: RESTART/STOP operation
+ */
+ private void performTasks(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String restart = req.getParameter(Constants.PR_SERVER_RESTART);
+ String stop = req.getParameter(Constants.PR_SERVER_STOP);
+ NameValuePairs params = new NameValuePairs();
+
+ if (restart != null) {
+ //XXX Uncommented afetr watchdog is implemented
+ sendResponse(SUCCESS, null, params, resp);
+ //mServer.restart();
+ return;
+ }
+
+ if (stop != null) {
+ //XXX Send response first then shutdown
+ sendResponse(SUCCESS, null, params, resp);
+ CMS.shutdown();
+ return;
+ }
+
+ sendResponse(ERROR, "Unknown operation", null, resp);
+
+ }
+
+ /**
+ * Reads subsystems that server has loaded with.
+ */
+ private void readSubsystem(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = CMS.getSubsystems();
+ StringBuffer buff = new StringBuffer();
+
+ while (e.hasMoreElements()) {
+ String type = "";
+ ISubsystem sys = (ISubsystem) e.nextElement();
+
+ //get subsystem type
+ if (sys instanceof IKeyRecoveryAuthority)
+ type = Constants.PR_KRA_INSTANCE;
+ if (sys instanceof IRegistrationAuthority)
+ type = Constants.PR_RA_INSTANCE;
+ if (sys instanceof ICertificateAuthority)
+ type = Constants.PR_CA_INSTANCE;
+ if (sys instanceof IOCSPAuthority)
+ type = Constants.PR_OCSP_INSTANCE;
+ if (sys instanceof ITKSAuthority)
+ type = Constants.PR_TKS_INSTANCE;
+ if (!type.trim().equals(""))
+ params.add(sys.getId(), type);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Reads server statistics.
+ */
+ private void readStat(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String installdate = cs.getString(Constants.PR_STAT_INSTALLDATE, "");
+ params.add(Constants.PR_STAT_INSTALLDATE, installdate);
+ } catch (Exception e) {
+ }
+
+ try {
+ String version = cs.getString(Constants.PR_STAT_VERSION, "");
+ params.add(Constants.PR_STAT_VERSION, version);
+ } catch (Exception e) {
+ }
+
+ try {
+ String instanceId = cs.getString(Constants.PR_STAT_INSTANCEID, "");
+ params.add(Constants.PR_STAT_INSTANCEID, instanceId);
+ } catch (Exception e) {
+ }
+
+ params.add(Constants.PR_STAT_STARTUP,
+ (new Date(CMS.getStartupTime())).toString());
+ params.add(Constants.PR_STAT_TIME,
+ (new Date(System.currentTimeMillis())).toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Modifies network information.
+ */
+ private void modifyNetworkConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ /*
+ HTTPSubsystem eeGateway = (HTTPSubsystem)
+ SubsystemRegistry.getInstance().get("eeGateway");
+ RemoteAdmin raAdmin = (RemoteAdmin)RemoteAdmin.getInstance();
+ AgentGateway agent = (AgentGateway)mReg.get(AgentGateway.ID);
+
+ Enumeration enum1 = req.getParameterNames();
+
+ String eeHTTPportString = null;
+ String eeHTTPSportString = null;
+ String agentHTTPSportString = null;
+ String radminHTTPSportString = null;
+
+ String gatewayBacklog = "15";
+
+ // eeHTTPEnabled corresponds to the checkbox which enables the
+ // HTTP EE port
+ String eeHTTPEnabled = Constants.FALSE;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String)enum1.nextElement();
+ String value = (String)req.getParameter(key);
+
+ if (key.equals(Constants.PR_AGENT_S_BACKLOG)) {
+ agent.setHTTPSBacklog(value);
+ } else if (key.equals(Constants.PR_GATEWAY_S_BACKLOG)) {
+ eeGateway.setHTTPSBacklog(value);
+ } else if (key.equals(Constants.PR_ADMIN_S_BACKLOG)) {
+ raAdmin.setHTTPSBacklog(value);
+ } else if (key.equals(Constants.PR_GATEWAY_BACKLOG)) {
+ gatewayBacklog = value;
+ } else if (key.equals(Constants.PR_GATEWAY_PORT_ENABLED)) {
+ eeHTTPEnabled = value;
+ }
+ }
+
+
+ eeHTTPportString = req.getParameter(Constants.PR_GATEWAY_PORT);
+ eeHTTPSportString = req.getParameter(Constants.PR_GATEWAY_S_PORT);
+ agentHTTPSportString= req.getParameter(Constants.PR_AGENT_S_PORT);
+ radminHTTPSportString= req.getParameter(Constants.PR_ADMIN_S_PORT);
+
+
+ int eeHTTPport=0;
+ int eeHTTPSport=0;
+ int agentHTTPSport=0;
+ int radminHTTPSport=0;
+ if (eeHTTPportString != null) eeHTTPport = Integer.parseInt(eeHTTPportString);
+ if (eeHTTPSportString != null) eeHTTPSport = Integer.parseInt(eeHTTPSportString);
+ if (agentHTTPSportString != null) agentHTTPSport = Integer.parseInt(agentHTTPSportString);
+ if (radminHTTPSportString != null) radminHTTPSport = Integer.parseInt(radminHTTPSportString);
+
+
+ String portName="";
+ int portnum;
+ try {
+
+ // EE HTTP is special, since it has it's own checkbox for enabling/disabling
+ if (eeHTTPEnabled.equals(Constants.TRUE) &&
+ eeHTTPport != 0 &&
+ eeHTTPport != eeGateway.getHTTPPort())
+ {
+ portName = "End-entity";
+ checkPortAvailable(eeHTTPport);
+ }
+
+ if (eeHTTPSport != 0 && eeHTTPSport != eeGateway.getHTTPSPort()) {
+ portName = "SSL End-entity";
+ checkPortAvailable(eeHTTPSport);
+ }
+ if (agentHTTPSport != 0 && agentHTTPSport != agent.getHTTPSPort()) {
+ portName = "Agent";
+ checkPortAvailable(agentHTTPSport);
+ }
+ if (radminHTTPSport != 0 && radminHTTPSport != raAdmin.getHTTPSPort()) {
+ portName = "Remote Admin";
+ checkPortAvailable(radminHTTPSport);
+ }
+
+ // If any of the above ports are not available, an exception
+ // will be thrown and these methods below will not be called
+
+ if (eeHTTPEnabled.equals(Constants.TRUE)) {
+ eeGateway.setHTTPPort(eeHTTPport);
+ }
+ eeGateway.setHTTPSPort(eeHTTPSport);
+ agent.setHTTPSPort(agentHTTPSport);
+ raAdmin.setHTTPSPort(radminHTTPSport);
+
+ } catch (IOException e) {
+ // send 'port in use' error
+ sendResponse(ERROR, portName+" "+e.getMessage(), null, resp);
+ // we do not want to save the config in this case
+ return;
+ }
+
+ eeGateway.setHTTPBacklog(gatewayBacklog);
+ eeGateway.setHTTPPortEnable(eeHTTPEnabled);
+
+ mConfig.commit(true);
+ sendResponse(RESTART, null, null, resp);
+ */
+ }
+
+ /**
+ * Check if the port is available for binding.
+ * @throws IOException if not available
+ */
+
+ private void checkPortAvailable(int port)
+ throws IOException {
+ try {
+ // see if the port is being used by somebody else
+ ServerSocket ss = new ServerSocket(port);
+
+ ss.close();
+ } catch (Exception e) {
+ throw new IOException("port " + port + " is in use. Please select another port");
+ }
+ }
+
+ /**
+ * Reads network information.
+ */
+ private void readNetworkConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ getEENetworkConfig(params);
+ getAdminConfig(params);
+ getAgentConfig(params);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getEENetworkConfig(NameValuePairs params)
+ throws EBaseException {
+
+ /*
+ HTTPSubsystem eeGateway =
+ (HTTPSubsystem)mReg.get("eeGateway");
+ if (eeGateway == null) {
+ // i.e. standalone DRM
+ params.add(Constants.PR_GATEWAY_S_PORT, "-1");
+ params.add(Constants.PR_GATEWAY_PORT, "-1");
+ params.add(Constants.PR_GATEWAY_S_BACKLOG, "-1");
+ params.add(Constants.PR_GATEWAY_BACKLOG,"-1");
+ params.add(Constants.PR_GATEWAY_PORT_ENABLED,"false");
+ } else {
+ params.add(Constants.PR_GATEWAY_S_PORT,
+ ""+eeGateway.getHTTPSPort());
+ params.add(Constants.PR_GATEWAY_PORT,
+ ""+eeGateway.getHTTPPort());
+ params.add(Constants.PR_GATEWAY_S_BACKLOG,
+ ""+eeGateway.getHTTPBacklog());
+ params.add(Constants.PR_GATEWAY_BACKLOG,
+ ""+eeGateway.getHTTPSBacklog());
+ params.add(Constants.PR_GATEWAY_PORT_ENABLED,
+ eeGateway.getHTTPPortEnable());
+ }
+ */
+ }
+
+ private void getAdminConfig(NameValuePairs params) throws EBaseException {
+
+ /*
+ RemoteAdmin raAdmin = (RemoteAdmin)RemoteAdmin.getInstance();
+ params.add(Constants.PR_ADMIN_S_PORT, ""+raAdmin.getHTTPSPort());
+ params.add(Constants.PR_ADMIN_S_BACKLOG,""+raAdmin.getHTTPSBacklog());
+ */
+ }
+
+ private void getAgentConfig(NameValuePairs params) throws EBaseException {
+
+ /*
+ AgentGateway agent = (AgentGateway)mReg.get(AgentGateway.ID);
+ params.add(Constants.PR_AGENT_S_PORT, ""+agent.getHTTPSPort());
+ params.add(Constants.PR_AGENT_S_BACKLOG,""+agent.getHTTPSBacklog());
+ */
+ }
+
+ /**
+ * Modifies database information.
+ */
+ private void setDBConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore dbConfig = mConfig.getSubStore(PROP_INTERNAL_DB);
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals(Constants.OP_TYPE))
+ continue;
+ if (key.equals(Constants.RS_ID))
+ continue;
+ if (key.equals(Constants.OP_SCOPE))
+ continue;
+
+ dbConfig.putString(key, req.getParameter(key));
+ }
+
+ sendResponse(RESTART, null, null, resp);
+ mConfig.commit(true);
+ }
+ /**
+ * Create Master Key
+ */
+private void createMasterKey(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+ String newKeyName = null, selectedToken = null;
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.PR_KEY_LIST))
+ {
+ newKeyName = req.getParameter(name);
+ }
+ if (name.equals(Constants.PR_TOKEN_LIST))
+ {
+ selectedToken = req.getParameter(name);
+ }
+
+
+ }
+ if(selectedToken!=null && newKeyName!=null)
+ {
+ String symKeys = SessionKey.GenMasterKey(selectedToken,newKeyName);
+ CMS.getConfigStore().putString("tks.defaultSlot", selectedToken);
+ String masterKeyPrefix = CMS.getConfigStore().getString("tks.master_key_prefix", null);
+
+ SessionKey.SetDefaultPrefix(masterKeyPrefix);
+ params.add(Constants.PR_KEY_LIST, newKeyName);
+ params.add(Constants.PR_TOKEN_LIST, selectedToken);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+}
+
+ /**
+ * Reads secmod.db
+ */
+ private void getTKSKeys(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.PR_TOKEN_LIST))
+ {
+ String selectedToken = req.getParameter(name);
+
+ int count = 0;
+ int keys_found = 0;
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ CryptoToken token = null;
+ CryptoManager mCryptoManager = null;
+ try {
+ mCryptoManager = CryptoManager.getInstance();
+ } catch (Exception e2) {
+ }
+
+ if(!jssSubSystem.isTokenLoggedIn(selectedToken))
+ {
+ PasswordCallback cpcb = new ConsolePasswordCallback();
+ while (true) {
+ try {
+ token = mCryptoManager.getTokenByName(selectedToken);
+ token.login(cpcb);
+ break;
+ } catch (Exception e3) {
+ //log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_INCORRECT_PWD"));
+ continue;
+ }
+ }
+ }
+ // String symKeys = new String("key1,key2");
+ String symKeys = SessionKey.ListSymmetricKeys(selectedToken);
+ params.add(Constants.PR_TOKEN_LIST, symKeys);
+
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+
+ /**
+ * Reads database information.
+ */
+ private void getDBConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore dbConfig = mConfig.getSubStore(PROP_DB);
+ IConfigStore ldapConfig = dbConfig.getSubStore("ldap");
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_SECURE_PORT_ENABLED))
+ params.add(name, ldapConfig.getString(name, "Constants.FALSE"));
+ else
+ params.add(name, ldapConfig.getString(name, ""));
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Modifies SMTP configuration.
+ */
+ private void modifySMTPConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ // XXX
+ IConfigStore sConfig = mConfig.getSubStore(PROP_SMTP);
+
+ String host = req.getParameter(Constants.PR_SERVER_NAME);
+
+ if (host != null)
+ sConfig.putString("host", host);
+
+ String port = req.getParameter(Constants.PR_PORT);
+
+ if (port != null)
+ sConfig.putString("port", port);
+
+ commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /**
+ * Reads SMTP configuration.
+ */
+ private void readSMTPConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore dbConfig = mConfig.getSubStore(PROP_SMTP);
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_SERVER_NAME,
+ dbConfig.getString("host"));
+ params.add(Constants.PR_PORT,
+ dbConfig.getString("port"));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void loggedInToken(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ String tokenName = "";
+ String pwd = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_TOKEN_NAME)) {
+ tokenName = value;
+ } else if (key.equals(Constants.PR_TOKEN_PASSWD)) {
+ pwd = value;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ jssSubSystem.loggedInToken(tokenName, pwd);
+
+ /* Do a "PUT" of the new pw to the watchdog" */
+ CMS.putPasswordCache(tokenName, pwd);
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void checkTokenStatus(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ String key = "";
+ String value = "";
+
+ while (enum1.hasMoreElements()) {
+ key = (String) enum1.nextElement();
+ value = req.getParameter(key);
+ if (key.equals(Constants.PR_TOKEN_NAME)) {
+ break;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ boolean status = jssSubSystem.isTokenLoggedIn(value);
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_LOGGED_IN, "" + status);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Retrieve a certificate request
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC used when
+ * asymmetric keys are generated
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to retrieve certificate request
+ */
+ private void getCertRequest(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditPublicKey = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration enum1 = req.getParameterNames();
+ String tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ String keyType = "";
+ int keyLength = 512;
+ String subjectName = "";
+ String certType = Constants.PR_CA_SIGNING_CERT;
+ String dir = "";
+ String pathname = "";
+ String serverID = "";
+ String otherNickname = "";
+ String certSubType = "";
+ String keyCurveName = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_TOKEN_NAME)) {
+ if (!value.equals(Constants.PR_INTERNAL_TOKEN))
+ tokenName = value;
+ } else if (key.equals(Constants.PR_KEY_LENGTH)) {
+ keyLength = Integer.parseInt(value);
+ } else if (key.equals(Constants.PR_KEY_TYPE)) {
+ keyType = value;
+ } else if (key.equals(Constants.RS_ID)) {
+ certType = value;
+ } else if (key.equals(Constants.PR_SUBJECT_NAME)) {
+ subjectName = value;
+ } else if (key.equals(Constants.PR_SERVER_ID)) {
+ serverID = value;
+ } else if (key.equals(Constants.PR_NICKNAME)) {
+ otherNickname = value;
+ } else if (key.equals(Constants.PR_CERTIFICATE_SUBTYPE)) {
+ certSubType = value;
+ } else if (key.equals(Constants.PR_KEY_CURVENAME)) {
+ keyCurveName = value;
+ }
+ }
+
+ pathname = mConfig.getString("instanceRoot", "")
+ + File.separator + "conf" + File.separator;
+ dir = pathname;
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ KeyPair keypair = null;
+ PQGParams pqgParams = null;
+ String nickname = "";
+
+ // other cert and has the existing key
+ if (certType.equals(Constants.PR_OTHER_CERT) && keyType.equals(""))
+ nickname = otherNickname;
+ else if (!certType.equals(Constants.PR_OTHER_CERT))
+ nickname = getNickname(certType);
+
+ String nicknameWithoutTokenName = "";
+
+ if (nickname != null && !nickname.equals("")) {
+ int index = nickname.indexOf(":");
+
+ nicknameWithoutTokenName = nickname;
+ if (index >= 0)
+ nicknameWithoutTokenName = nickname.substring(index + 1);
+ }
+
+ if (keyType.equals("")) {
+ if (nickname.equals("")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
+ }
+ keypair = jssSubSystem.getKeyPair(nickname);
+ } else {
+ if (keyType.equals("ECC")) {
+ // get ECC keypair
+ keypair = jssSubSystem.getECCKeyPair(tokenName, keyCurveName, certType);
+ } else { //DSA or RSA
+ if (keyType.equals("DSA"))
+ pqgParams = jssSubSystem.getPQG(keyLength);
+ keypair = jssSubSystem.getKeyPair(tokenName, keyType, keyLength, pqgParams);
+ }
+ }
+
+ // reset the "auditPublicKey"
+ auditPublicKey = auditPublicKey(keypair);
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ pathname = pathname + File.separator + "cacsr.txt";
+ if (!keyType.equals(""))
+ setCANewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ pathname = pathname + File.separator + "racsr.txt";
+ if (!keyType.equals(""))
+ setRANewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ pathname = pathname + File.separator + "ocspcsr.txt";
+ if (!keyType.equals(""))
+ setOCSPNewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ pathname = pathname + File.separator + "kracsr.txt";
+ if (!keyType.equals(""))
+ setKRANewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ pathname = pathname + File.separator + "sslcsr.txt";
+ if (!keyType.equals(""))
+ setAgentNewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ pathname = pathname + File.separator + "sslcsrradm.txt";
+ if (!keyType.equals(""))
+ setRADMNewnickname(tokenName, nicknameWithoutTokenName);
+ } else if (certType.equals(Constants.PR_OTHER_CERT)) {
+ pathname = pathname + File.separator + "othercsr.txt";
+ }
+ String certReq = jssSubSystem.getCertRequest(subjectName, keypair);
+
+ params.add(Constants.PR_CSR, certReq);
+ params.add(Constants.PR_CERT_REQUEST_DIR, dir);
+ PrintStream ps = new PrintStream(new FileOutputStream(pathname));
+
+ ps.println(certReq);
+ ps.close();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ mConfig.commit(true);
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_KEY_GEN_ASYMMETRIC,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditPublicKey );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void setCANewnickname(String tokenName, String nickname)
+ throws EBaseException {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getSigningUnit();
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ signingUnit.setNewNickName(nickname);
+ else {
+ if (tokenName.equals("") && nickname.equals(""))
+ signingUnit.setNewNickName("");
+ else
+ signingUnit.setNewNickName(tokenName + ":" + nickname);
+ }
+ }
+
+ private String getCANewnickname() throws EBaseException {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getSigningUnit();
+
+ return signingUnit.getNewNickName();
+ }
+
+ private void setRANewnickname(String tokenName, String nickname)
+ throws EBaseException {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ ra.setNewNickName(nickname);
+ else {
+ if (tokenName.equals("") && nickname.equals(""))
+ ra.setNewNickName("");
+ else
+ ra.setNewNickName(tokenName + ":" + nickname);
+ }
+ }
+
+ private String getRANewnickname() throws EBaseException {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ return ra.getNewNickName();
+ }
+
+ private void setOCSPNewnickname(String tokenName, String nickname)
+ throws EBaseException {
+ IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_OCSP);
+
+ if (ocsp != null) {
+ ISigningUnit signingUnit = ocsp.getSigningUnit();
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ signingUnit.setNewNickName(nickname);
+ else {
+ if (tokenName.equals("") && nickname.equals(""))
+ signingUnit.setNewNickName("");
+ else
+ signingUnit.setNewNickName(tokenName + ":" + nickname);
+ }
+ } else {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getOCSPSigningUnit();
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ signingUnit.setNewNickName(nickname);
+ else {
+ if (tokenName.equals("") && nickname.equals(""))
+ signingUnit.setNewNickName("");
+ else
+ signingUnit.setNewNickName(tokenName + ":" + nickname);
+ }
+ }
+ }
+
+ private String getOCSPNewnickname() throws EBaseException {
+ IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_OCSP);
+
+ if (ocsp != null) {
+ ISigningUnit signingUnit = ocsp.getSigningUnit();
+
+ return signingUnit.getNewNickName();
+ } else {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getOCSPSigningUnit();
+
+ return signingUnit.getNewNickName();
+ }
+ }
+
+ private void setKRANewnickname(String tokenName, String nickname)
+ throws EBaseException {
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ kra.setNewNickName(nickname);
+ else {
+ if (tokenName.equals("") && nickname.equals(""))
+ kra.setNewNickName("");
+ else
+ kra.setNewNickName(tokenName + ":" + nickname);
+ }
+ }
+
+ private String getKRANewnickname() throws EBaseException {
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+
+ return kra.getNewNickName();
+ }
+
+ private void setRADMNewnickname(String tokenName, String nickName)
+ throws EBaseException {
+ CMS.setServerCertNickname(tokenName, nickName);
+
+ /*
+ RemoteAdmin raAdmin = (RemoteAdmin)RemoteAdmin.getInstance();
+ HTTPService httpsService = raAdmin.getHttpsService();
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ httpsService.setNewNickName(nickName);
+ else {
+ if (tokenName.equals("") && nickName.equals(""))
+ httpsService.setNewNickName("");
+ else
+ httpsService.setNewNickName(tokenName+":"+nickName);
+ }
+ */
+ }
+
+ private String getRADMNewnickname()
+ throws EBaseException {
+ // assuming the nickname does not change.
+ return CMS.getServerCertNickname();
+
+ /*
+ RemoteAdmin raAdmin = (RemoteAdmin)RemoteAdmin.getInstance();
+ HTTPService httpsService = raAdmin.getHttpsService();
+ return httpsService.getNewNickName();
+ */
+ }
+
+ private void setAgentNewnickname(String tokenName, String nickName)
+ throws EBaseException {
+ CMS.setServerCertNickname(tokenName, nickName);
+
+ /*
+ AgentGateway gateway = (AgentGateway)mReg.get(AgentGateway.ID);
+ HTTPService httpsService = gateway.getHttpsService();
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ httpsService.setNewNickName(nickName);
+ else {
+ if (tokenName.equals("") && nickName.equals(""))
+ httpsService.setNewNickName("");
+ else
+ httpsService.setNewNickName(tokenName+":"+nickName);
+ }
+ */
+ }
+
+ private String getAgentNewnickname()
+ throws EBaseException {
+ // assuming the nickname does not change.
+ return CMS.getServerCertNickname();
+
+ /*
+ AgentGateway gateway = (AgentGateway)mReg.get(AgentGateway.ID);
+ HTTPService httpsService = gateway.getHttpsService();
+ return httpsService.getNewNickName();
+ */
+ }
+
+ /**
+ * Issue import certificate
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY used when
+ * "Certificate Setup Wizard" is used to import CA certs into the
+ * certificate database
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to issue an import certificate
+ */
+ private void issueImportCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ Enumeration enum1 = req.getParameterNames();
+ String pkcs = "";
+ String type = "";
+ String tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ String keyType = "RSA";
+ int keyLength = 512;
+ String subjectName = "";
+ KeyCertData properties = new KeyCertData();
+ String pathname = "";
+
+ String configPath = "";
+ String newtokenname = null;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals("pathname")) {
+ configPath = mConfig.getString("instanceRoot", "")
+ + File.separator + "conf" + File.separator;
+ pathname = configPath + value;
+ } else {
+ if (key.equals(Constants.PR_TOKEN_NAME))
+ newtokenname = value;
+ properties.put(key, value);
+ }
+ }
+
+ String certType = (String) properties.get(Constants.RS_ID);
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ IDBSubsystem dbs = (IDBSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_DBS);
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ICertificateRepository repository =
+ (ICertificateRepository) ca.getCertificateRepository();
+ ISigningUnit signingUnit = ca.getSigningUnit();
+ String oldtokenname = null;
+ //this is the old nick name
+ String nickname = getNickname(certType);
+ String nicknameWithoutTokenName = "";
+ String oldcatokenname = signingUnit.getTokenName();
+ String canickname = getNickname(Constants.PR_CA_SIGNING_CERT);
+ String canicknameWithoutTokenName = "";
+
+ int index = nickname.indexOf(":");
+
+ if (index == -1) {
+ nicknameWithoutTokenName = nickname;
+ oldtokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ } else if (index > 0 && (index < (nickname.length() - 1))) {
+ nicknameWithoutTokenName = nickname.substring(index + 1);
+ oldtokenname = nickname.substring(0, index);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new
+ EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
+ }
+
+ if (newtokenname == null)
+ newtokenname = oldtokenname;
+ index = canickname.indexOf(":");
+ if (index == -1) {
+ canicknameWithoutTokenName = canickname;
+ } else if (index > 0 && (index < (canickname.length() - 1))) {
+ canicknameWithoutTokenName = canickname.substring(index + 1);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new
+ EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
+ }
+
+ //xxx renew ca ,use old issuer?
+ properties.setIssuerName(
+ jssSubSystem.getCertSubjectName(oldcatokenname,
+ canicknameWithoutTokenName));
+
+ KeyPair pair = null;
+
+ if (nickname.equals("")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new
+ EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
+ }
+
+ //xxx set to old nickname?
+ properties.setCertNickname(nickname);
+ if (!certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ CertificateExtensions exts = jssSubSystem.getExtensions(
+ oldcatokenname, canicknameWithoutTokenName);
+
+ properties.setCAExtensions(exts);
+ }
+
+ KeyPair caKeyPair = null;
+ String defaultSigningAlg = null;
+ String defaultOCSPSigningAlg = null;
+
+ if (properties.getHashType() != null) {
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ defaultSigningAlg = properties.getHashType();
+ }
+ if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ defaultOCSPSigningAlg = properties.getHashType();
+ }
+ }
+
+ // create a new CA certificate or ssl server cert
+ if (properties.getKeyCurveName() != null) { //new ECC
+ CMS.debug("CMSAdminServlet: issueImportCert: generating ECC keys");
+ pair = jssSubSystem.getECCKeyPair(properties);
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ caKeyPair = pair;
+ } else if (properties.getKeyLength() != null) { //new RSA or DSA
+ keyType = properties.getKeyType();
+ String keyLen = properties.getKeyLength();
+ PQGParams pqgParams = null;
+
+ if (keyType.equals("DSA")) {
+ pqgParams = jssSubSystem.getCAPQG(Integer.parseInt(keyLen),
+ mConfig);
+ //properties.put(Constants.PR_PQGPARAMS, pqgParams);
+ }
+ pair = jssSubSystem.getKeyPair(properties);
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ caKeyPair = pair;
+ // renew the CA certificate or ssl server cert
+ } else {
+ pair = jssSubSystem.getKeyPair(nickname);
+ // should get it from the CA signing certificate
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ updateCASignature(nickname, properties, jssSubSystem);
+ caKeyPair = pair;
+ defaultSigningAlg = signingUnit.getDefaultAlgorithm();
+ }
+
+ /*
+ String alg = jssSubSystem.getSignatureAlgorithm(nickname);
+ SignatureAlgorithm sigAlg = SigningUnit.mapAlgorithmToJss(alg);
+ properties.setSignatureAlgorithm(sigAlg);
+ properties.setAlgorithmId(
+ jssSubSystem.getAlgorithmId(alg, mConfig));
+ */
+ }
+
+ String alg = properties.getSignedBy();
+ if (!certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ caKeyPair = jssSubSystem.getKeyPair(canickname);
+ updateCASignature(canickname, properties, jssSubSystem);
+ } else if (alg != null) {
+ // self signed CA signing cert, new keys
+ // value provided for signedBy
+ SignatureAlgorithm sigAlg = Cert.mapAlgorithmToJss(alg);
+ properties.setSignatureAlgorithm(sigAlg);
+ properties.setAlgorithmId(jssSubSystem.getAlgorithmId(alg, mConfig));
+ }
+
+ if (pair == null)
+ CMS.debug("CMSAdminServlet: issueImportCert: key pair is null");
+
+ BigInteger nextSerialNo = repository.getNextSerialNumber();
+
+ properties.setSerialNumber(nextSerialNo);
+ properties.setKeyPair(pair);
+ properties.setConfigFile(mConfig);
+ // properties.put(Constants.PR_CA_KEYPAIR, pair);
+ properties.put(Constants.PR_CA_KEYPAIR, caKeyPair);
+
+ X509CertImpl signedCert =
+ jssSubSystem.getSignedCert(properties, certType,
+ caKeyPair.getPrivate());
+
+ if (signedCert == null)
+ CMS.debug("CMSAdminServlet: issueImportCert: signedCert is null");
+
+ /* bug 600124
+ try {
+ jssSubSystem.deleteTokenCertificate(nickname, pathname);
+ } catch (Throwable e) {
+ //skip it
+ }
+ */
+
+ boolean nicknameChanged = false;
+
+ //xxx import cert with nickname without token name?
+ //jss adds the token prefix!!!
+ //log(ILogger.LL_DEBUG,"import as alias"+ nicknameWithoutTokenName);
+ try {
+ CMS.debug("CMSAdminServlet: issueImportCert: Importing cert: " + nicknameWithoutTokenName);
+ jssSubSystem.importCert(signedCert, nicknameWithoutTokenName,
+ certType);
+ } catch (EBaseException e) {
+ // if it fails, let use a different nickname to try
+ Date now = new Date();
+ String newNickname = nicknameWithoutTokenName
+ + "-" + now.getTime();
+
+ CMS.debug("CMSAdminServlet: issueImportCert: Importing cert with nickname: " + newNickname);
+ jssSubSystem.importCert(signedCert, newNickname,
+ certType);
+ nicknameWithoutTokenName = newNickname;
+ nicknameChanged = true;
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = newNickname;
+ } else {
+ nickname = tokenName + ":" + newNickname;
+ }
+ }
+
+ ICertRecord certRecord = repository.createCertRecord(
+ signedCert.getSerialNumber(),
+ signedCert, null);
+
+ repository.addCertificateRecord(certRecord);
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ try {
+ X509CertInfo certInfo = (X509CertInfo) signedCert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ BasicConstraintsExtension basic =
+ (BasicConstraintsExtension)
+ extensions.get(BasicConstraintsExtension.NAME);
+
+ if (basic == null)
+ log(CMS.getLogMessage("ADMIN_SRVLT_BASIC_CONSTRAIN_NULL"));
+ else {
+ Integer pathlen = (Integer)
+ basic.get(BasicConstraintsExtension.PATH_LEN);
+ int num = pathlen.intValue();
+
+ if (num == 0)
+ ca.setBasicConstraintMaxLen(num);
+ else if (num > 0) {
+ num = num - 1;
+ ca.setBasicConstraintMaxLen(num);
+ }
+ }
+ } else
+ log(CMS.getLogMessage("ADMIN_SRVLT_CERT_NO_EXT"));
+ } catch (Exception eee) {
+ log("CMSAdminServlet: Exception caught: " + eee.toString());
+ }
+ }
+
+ CMS.debug("CMSAdminServlet: oldtoken:" + oldtokenname
+ + " newtoken:" + newtokenname + " nickname:" + nickname);
+ if ((newtokenname != null &&
+ !newtokenname.equals(oldtokenname)) || nicknameChanged) {
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ if (newtokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ signingUnit.updateConfig(nicknameWithoutTokenName,
+ newtokenname);
+ } else {
+ signingUnit.updateConfig(newtokenname + ":" +
+ nicknameWithoutTokenName,
+ newtokenname);
+ }
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ if (newtokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nicknameWithoutTokenName;
+ } else {
+ nickname = newtokenname + ":"
+ + nicknameWithoutTokenName;
+ }
+
+ //setRADMNewnickname("","");
+ //modifyRADMCert(nickname);
+ modifyAgentGatewayCert(nickname);
+ if (isSubsystemInstalled("ra")) {
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ modifyEEGatewayCert(ra, nickname);
+ }
+ if (isSubsystemInstalled("ca")) {
+ modifyCAGatewayCert(ca, nickname);
+ }
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ if (newtokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nicknameWithoutTokenName;
+ } else {
+ nickname = newtokenname + ":"
+ + nicknameWithoutTokenName;
+ }
+
+ modifyRADMCert(nickname);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ if (ca != null) {
+ ISigningUnit ocspSigningUnit = ca.getOCSPSigningUnit();
+
+ if (newtokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ ocspSigningUnit.updateConfig(
+ nicknameWithoutTokenName, newtokenname);
+ } else {
+ ocspSigningUnit.updateConfig(newtokenname + ":" +
+ nicknameWithoutTokenName,
+ newtokenname);
+ }
+ }
+ }
+ }
+
+ // set signing algorithms if needed
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ signingUnit.setDefaultAlgorithm(defaultSigningAlg);
+
+ if (defaultOCSPSigningAlg != null) {
+ ISigningUnit ocspSigningUnit = ca.getOCSPSigningUnit();
+ ocspSigningUnit.setDefaultAlgorithm(defaultOCSPSigningAlg);
+ }
+
+ properties.clear();
+ properties = null;
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ mConfig.commit(true);
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ CMS.debug("CMSAdminServlet: issueImportCert: EBaseException thrown: " + eAudit1.toString());
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ CMS.debug("CMSAdminServlet: issueImportCert: IOException thrown: " + eAudit2.toString());
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private String getDefaultSigningAlg(String keyType, String messageDigest) {
+ if (keyType.equals("RSA")) {
+ if (messageDigest.equals("MD2")) {
+ return "MD2withRSA";
+ } else if (messageDigest.equals("MD5")) {
+ return "MD5withRSA";
+ } else if (messageDigest.equals("SHA1")) {
+ return "SHA1withRSA";
+ } else if (messageDigest.equals("SHA256")) {
+ return "SHA256withRSA";
+ } else if (messageDigest.equals("SHA512")) {
+ return "SHA512withRSA";
+ }
+ } else if (keyType.equals("DSA")) {
+ if (messageDigest.equals("SHA1")) {
+ return "SHA1withDSA";
+ }
+ } else /* EC */ {
+ if (messageDigest.equals("SHA1")) {
+ return "SHA1withEC";
+ } else if (messageDigest.equals("SHA256")) {
+ return "SHA256withEC";
+ } else if (messageDigest.equals("SHA384")) {
+ return "SHA384withEC";
+ } else if (messageDigest.equals("SHA512")) {
+ return "SHA512withEC";
+ }
+ }
+ return null;
+ }
+
+ private void updateCASignature(String nickname, KeyCertData properties,
+ ICryptoSubsystem jssSubSystem) throws EBaseException {
+ String alg = jssSubSystem.getSignatureAlgorithm(nickname);
+ SignatureAlgorithm sigAlg = Cert.mapAlgorithmToJss(alg);
+
+ properties.setSignatureAlgorithm(sigAlg);
+ properties.setAlgorithmId(
+ jssSubSystem.getAlgorithmId(alg, mConfig));
+ }
+
+ /**
+ * Install certificates
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY used when
+ * "Certificate Setup Wizard" is used to import CA certs into the
+ * certificate database
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to install a certificate
+ */
+ private void installCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ String pkcs = "";
+ String certType = "";
+ String nickname = "";
+ String pathname = "";
+ String serverRoot = "";
+ String serverID = "";
+ String certpath = "";
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_PKCS10))
+ pkcs = value;
+ else if (key.equals(Constants.RS_ID))
+ certType = value;
+ else if (key.equals(Constants.PR_NICKNAME))
+ nickname = value;
+ else if (key.equals("pathname"))
+ pathname = value;
+ else if (key.equals(Constants.PR_SERVER_ROOT))
+ serverRoot = value;
+ else if (key.equals(Constants.PR_SERVER_ID))
+ serverID = value;
+ else if (key.equals(Constants.PR_CERT_FILEPATH))
+ certpath = value;
+ }
+
+ try {
+ if (pkcs == null || pkcs.equals("")) {
+ if (certpath == null || certpath.equals("")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ EBaseException ex = new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_FILE_PATH"));
+
+ throw ex;
+ } else {
+ FileInputStream in = new FileInputStream(certpath);
+ BufferedReader d =
+ new BufferedReader(new InputStreamReader(in));
+ String content = "";
+
+ pkcs = "";
+ StringBuffer sb = new StringBuffer();
+ while ((content = d.readLine()) != null) {
+ sb.append(content);
+ sb.append("\n");
+ }
+
+ pkcs = sb.toString();
+ if (d != null) {
+ d.close();
+ }
+ pkcs = pkcs.substring(0, pkcs.length() - 1);
+ }
+ }
+ } catch (IOException ee) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_OPEN_FILE_FAILED"));
+ }
+
+ pkcs = pkcs.trim();
+ pathname = serverRoot + File.separator + serverID
+ + File.separator + "config" + File.separator + pathname;
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ //String nickname = getNickname(certType);
+ String nicknameWithoutTokenName = "";
+
+ int index = nickname.indexOf(":");
+
+ if (index == -1)
+ nicknameWithoutTokenName = nickname;
+ else if (index > 0 && (index < (nickname.length() - 1))) {
+ tokenName = nickname.substring(0, index);
+ nicknameWithoutTokenName = nickname.substring(index + 1);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
+ }
+
+ /*
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_RA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_OCSP_SIGNING_CERT) ||
+ certType.equals(Constants.PR_KRA_TRANSPORT_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ String oldnickname = getNickname(certType);
+ try {
+ jssSubsystem.deleteTokenCertificate(oldnickname,
+ pathname);
+ //jssSubsystem.deleteTokenCertificate(nickname,
+ pathname);
+ } catch (EBaseException e) {
+ // skip it
+ }
+ } else {
+ try {
+ jssSubsystem.deleteTokenCertificate(nickname, pathname);
+ } catch (EBaseException e) {
+ // skip it
+ }
+ }
+ */
+
+ // 600124 - renewal of SSL crash the server
+ // we now do not delete previously installed certificates.
+
+ // Same Subject | Same Nickname | Same Key | Legal
+ // -----------------------------------------------------------
+ // 1. Yes Yes No Yes
+ // 2. Yes Yes Yes Yes
+ // 3. No No Yes Yes
+ // 4. No No No Yes
+ // 5. No Yes Yes No
+ // 6. No Yes No No
+ // 7. Yes No Yes No
+ // 8. Yes No No No
+
+ // Based on above table, the following cases are permitted:
+ // Existing Key:
+ // (a) Same Subject & Same Nickname --- (2)
+ // (b) Different Subject & Different Nickname --- (3)
+ // (In order to support Case b., we need to use a different
+ // nickname).
+ // New Key:
+ // (c) Same Subject & Same Nickname --- (1)
+ // (d) Different Subject & Different Nickname --- (4)
+ // (In order to support Case b., we need to use a different
+ // nickname).
+ //
+
+ try {
+ jssSubSystem.importCert(pkcs, nicknameWithoutTokenName,
+ certType);
+ } catch (EBaseException e) {
+ // if it fails, let use a different nickname to try
+ Date now = new Date();
+ String newNickname = nicknameWithoutTokenName + "-" +
+ now.getTime();
+
+ jssSubSystem.importCert(pkcs, newNickname, certType);
+ nicknameWithoutTokenName = newNickname;
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = newNickname;
+ } else {
+ nickname = tokenName + ":" + newNickname;
+ }
+ CMS.debug("CMSAdminServlet: installCert(): nickname="+nickname);
+ }
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ ICertificateAuthority ca =
+ (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getSigningUnit();
+ String signatureAlg =
+ jssSubSystem.getSignatureAlgorithm(nickname);
+
+ signingUnit.setDefaultAlgorithm(signatureAlg);
+ setCANewnickname("", "");
+ try {
+ CertificateExtensions extensions = null;
+
+ if (nickname.equals(nicknameWithoutTokenName)) {
+ signingUnit.updateConfig(nickname,
+ Constants.PR_INTERNAL_TOKEN_NAME);
+ extensions = jssSubSystem.getExtensions(
+ Constants.PR_INTERNAL_TOKEN_NAME, nickname);
+ } else {
+ String tokenname1 = nickname.substring(0, index);
+
+ signingUnit.updateConfig(nickname, tokenname1);
+ extensions = jssSubSystem.getExtensions(tokenname1,
+ nicknameWithoutTokenName);
+ }
+ if (extensions != null) {
+ BasicConstraintsExtension basic =
+ (BasicConstraintsExtension)
+ extensions.get(BasicConstraintsExtension.NAME);
+
+ if (basic == null)
+ log(CMS.getLogMessage("ADMIN_SRVLT_BASIC_CONSTRAIN_NULL"));
+ else {
+ Integer pathlen = (Integer)
+ basic.get(BasicConstraintsExtension.PATH_LEN);
+ int num = pathlen.intValue();
+
+ if (num == 0)
+ ca.setBasicConstraintMaxLen(num);
+ else if (num > 0) {
+ num = num - 1;
+ ca.setBasicConstraintMaxLen(num);
+ }
+ }
+ } else {
+ log(CMS.getLogMessage("ADMIN_SRVLT_CERT_NO_EXT"));
+ }
+ } catch (Exception eee) {
+ log("CMSAdminServlet: Exception: " + eee.toString());
+ }
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ setRANewnickname("", "");
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ ra.setNickname(nickname);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ setOCSPNewnickname("", "");
+ IOCSPAuthority ocsp =
+ (IOCSPAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_OCSP);
+
+ if (ocsp != null) {
+ ISigningUnit signingUnit = ocsp.getSigningUnit();
+
+ if (nickname.equals(nicknameWithoutTokenName)) {
+ signingUnit.updateConfig(nickname,
+ Constants.PR_INTERNAL_TOKEN_NAME);
+ } else {
+ String tokenname1 = nickname.substring(0, index);
+
+ signingUnit.updateConfig(nickname, tokenname1);
+ }
+ } else {
+ ICertificateAuthority ca =
+ (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getOCSPSigningUnit();
+
+ if (nickname.equals(nicknameWithoutTokenName)) {
+ signingUnit.updateConfig(nickname,
+ Constants.PR_INTERNAL_TOKEN_NAME);
+ } else {
+ String tokenname1 = nickname.substring(0, index);
+
+ signingUnit.updateConfig(nickname, tokenname1);
+ }
+ }
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ setKRANewnickname("", "");
+ IKeyRecoveryAuthority kra =
+ (IKeyRecoveryAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+
+ kra.setNickname(nickname);
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ setAgentNewnickname("", "");
+ //modifyRADMCert(nickname);
+ modifyAgentGatewayCert(nickname);
+ if (isSubsystemInstalled("ra")) {
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ modifyEEGatewayCert(ra, nickname);
+ }
+ if (isSubsystemInstalled("ca")) {
+ ICertificateAuthority ca =
+ (ICertificateAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+
+ modifyCAGatewayCert(ca, nickname);
+ }
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ setRADMNewnickname("", "");
+ modifyRADMCert(nickname);
+ }
+
+ boolean verified = CMS.verifySystemCertByNickname(nickname, null);
+ if (verified == true) {
+ CMS.debug("CMSAdminServlet: installCert(): verifySystemCertByNickname() succeeded:"+ nickname);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ nickname);
+
+ audit(auditMessage);
+ } else {
+ CMS.debug("CMSAdminServlet: installCert(): verifySystemCertByNickname() failed:"+ nickname);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ auditSubjectID,
+ ILogger.FAILURE,
+ nickname);
+
+ audit(auditMessage);
+ }
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ mConfig.commit(true);
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * For "importing" cross-signed cert into internal db for further
+ * cross pair matching and publishing
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY used when
+ * "Certificate Setup Wizard" is used to import a CA cross-signed
+ * certificate into the database
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to import a cross-certificate pair
+ */
+ private void importXCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String b64Cert = "";
+ String certType = "";
+ String pathname = "";
+ String serverRoot = "";
+ String serverID = "";
+ String certpath = "";
+ Enumeration enum1 = req.getParameterNames();
+ NameValuePairs results = new NameValuePairs();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ // really should be PR_CERT_CONTENT
+ if (key.equals(Constants.PR_PKCS10))
+ b64Cert = value;
+ else if (key.equals(Constants.RS_ID))
+ certType = value;
+ else if (key.equals("pathname"))
+ pathname = value;
+ else if (key.equals(Constants.PR_SERVER_ROOT))
+ serverRoot = value;
+ else if (key.equals(Constants.PR_SERVER_ID))
+ serverID = value;
+ else if (key.equals(Constants.PR_CERT_FILEPATH))
+ certpath = value;
+ }
+
+ try {
+ if (b64Cert == null || b64Cert.equals("")) {
+ if (certpath == null || certpath.equals("")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ EBaseException ex = new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_FILE_PATH"));
+
+ throw ex;
+ } else {
+ FileInputStream in = new FileInputStream(certpath);
+ BufferedReader d =
+ new BufferedReader(new InputStreamReader(in));
+ String content = "";
+
+ b64Cert = "";
+ StringBuffer sb = new StringBuffer();
+ while ((content = d.readLine()) != null) {
+ sb.append(content);
+ sb.append("\n");
+ }
+ b64Cert = sb.toString();
+ if (d != null) {
+ d.close();
+ }
+ b64Cert = b64Cert.substring(0, b64Cert.length() - 1);
+ }
+ }
+ } catch (IOException ee) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_OPEN_FILE_FAILED"));
+ }
+ CMS.debug("CMSAdminServlet: got b64Cert");
+ b64Cert = Cert.stripBrackets(b64Cert.trim());
+
+ // Base64 decode cert
+ byte[] bCert = null;
+
+ try {
+ bCert = (byte[]) (com.netscape.osutil.OSUtil.AtoB(b64Cert));
+ } catch (Exception e) {
+ CMS.debug("CMSAdminServlet: exception: " + e.toString());
+ }
+
+ pathname = serverRoot + File.separator + serverID
+ + File.separator + "config" + File.separator + pathname;
+
+ ICrossCertPairSubsystem ccps =
+ (ICrossCertPairSubsystem) CMS.getSubsystem("CrossCertPair");
+
+ try {
+ //this will import into internal ldap crossCerts entry
+ ccps.importCert(bCert);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(1, "xcert importing failure:" + e.toString(),
+ null, resp);
+ return;
+ }
+
+ try {
+ // this will publish all of the cross cert pairs from internal
+ // db to publishing directory, if turned on
+ ccps.publishCertPairs();
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(1, "xcerts publishing failure:" + e.toString(), null, resp);
+ return;
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String content = jssSubSystem.getCertPrettyPrint(b64Cert,
+ super.getLocale(req));
+
+ results.add(Constants.PR_NICKNAME, "FBCA cross-signed cert");
+ results.add(Constants.PR_CERT_CONTENT, content);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, results, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private String getNickname(String certType) throws EBaseException {
+ String nickname = "";
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ ICertificateAuthority ca =
+ (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getSigningUnit();
+
+ nickname = signingUnit.getNickname();
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ IOCSPAuthority ocsp =
+ (IOCSPAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_OCSP);
+
+ if (ocsp == null) {
+ // this is a local CA service
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ISigningUnit signingUnit = ca.getOCSPSigningUnit();
+
+ nickname = signingUnit.getNickname();
+ } else {
+ ISigningUnit signingUnit = ocsp.getSigningUnit();
+
+ nickname = signingUnit.getNickname();
+ }
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+
+ nickname = ra.getNickname();
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ IKeyRecoveryAuthority kra =
+ (IKeyRecoveryAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+
+ nickname = kra.getNickname();
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ nickname = CMS.getServerCertNickname();
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ nickname = CMS.getServerCertNickname();
+ }
+
+ return nickname;
+ }
+
+ private void getCertInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ NameValuePairs results = new NameValuePairs();
+ String pkcs = "";
+ String path = "";
+ String certType = "";
+ String otherNickname = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_PKCS10)) {
+ pkcs = value;
+ } else if (key.equals(Constants.RS_ID)) {
+ certType = value;
+ } else if (key.equals(Constants.PR_CERT_FILEPATH)) {
+ path = value;
+ } else if (key.equals(Constants.PR_NICKNAME)) {
+ otherNickname = value;
+ }
+ }
+
+ try {
+ if (pkcs == null || pkcs.equals("")) {
+
+ if (path == null || path.equals("")) {
+ EBaseException ex = new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_FILE_PATH"));
+
+ throw ex;
+ } else {
+ FileInputStream in = new FileInputStream(path);
+ BufferedReader d =
+ new BufferedReader(new InputStreamReader(in));
+ String content = "";
+
+ pkcs = "";
+ StringBuffer sb = new StringBuffer();
+ while ((content = d.readLine()) != null) {
+ sb.append(content);
+ sb.append("\n");
+ }
+ pkcs = sb.toString();
+ if (d != null) {
+ d.close();
+ }
+ pkcs = pkcs.substring(0, pkcs.length() - 1);
+ }
+ }
+ } catch (IOException ee) {
+ throw new EBaseException(CMS.getLogMessage("BASE_OPEN_FILE_FAILED"));
+ }
+
+ pkcs = pkcs.trim();
+ int totalLen = pkcs.length();
+
+ if (pkcs.indexOf(BEGIN_HEADER) != 0 ||
+ pkcs.indexOf(END_HEADER) != (totalLen - 25)) {
+ throw (new EBaseException(CMS.getLogMessage("BASE_INVALID_CERT_FORMAT")));
+ }
+
+ String nickname = "";
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ nickname = getCANewnickname();
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ nickname = getRANewnickname();
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ nickname = getKRANewnickname();
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ nickname = getAgentNewnickname();
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ nickname = getRADMNewnickname();
+ } else if (certType.equals(Constants.PR_OTHER_CERT)) {
+ nickname = otherNickname;
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ nickname = getOCSPNewnickname();
+ }
+ if (nickname.equals(""))
+ nickname = getNickname(certType);
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String content = jssSubSystem.getCertPrettyPrint(pkcs,
+ super.getLocale(req));
+
+ if (nickname != null && !nickname.equals(""))
+ results.add(Constants.PR_NICKNAME, nickname);
+ results.add(Constants.PR_CERT_CONTENT, content);
+ //results = jssSubSystem.getCertInfo(value);
+
+ sendResponse(SUCCESS, null, results, resp);
+ }
+
+ private void getCertPrettyPrint(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String nickname = "";
+ String serialno = "";
+ String issuername = "";
+ Locale locale = super.getLocale(req);
+ NameValuePairs pairs = new NameValuePairs();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.OP_TYPE))
+ continue;
+ if (key.equals(Constants.RS_ID))
+ continue;
+ if (key.equals(Constants.OP_SCOPE))
+ continue;
+ if (key.equals(Constants.PR_NICK_NAME)) {
+ nickname = value;
+ continue;
+ }
+ if (key.equals(Constants.PR_SERIAL_NUMBER)) {
+ serialno = value;
+ continue;
+ }
+ if (key.equals(Constants.PR_ISSUER_NAME)) {
+ issuername = value;
+ continue;
+ }
+ }
+
+ String print = jssSubSystem.getCertPrettyPrintAndFingerPrint(nickname,
+ serialno, issuername, locale);
+ pairs.add(nickname, print);
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void getRootCertTrustBit(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String nickname = "";
+ String serialno = "";
+ String issuername = "";
+ Locale locale = super.getLocale(req);
+ NameValuePairs pairs = new NameValuePairs();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.OP_TYPE))
+ continue;
+ if (key.equals(Constants.RS_ID))
+ continue;
+ if (key.equals(Constants.OP_SCOPE))
+ continue;
+ if (key.equals(Constants.PR_NICK_NAME)) {
+ nickname = value;
+ continue;
+ }
+ if (key.equals(Constants.PR_SERIAL_NUMBER)) {
+ serialno = value;
+ continue;
+ }
+ if (key.equals(Constants.PR_ISSUER_NAME)) {
+ issuername = value;
+ continue;
+ }
+ }
+
+ String trustbit = jssSubSystem.getRootCertTrustBit(nickname,
+ serialno, issuername);
+ pairs.add(nickname, trustbit);
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void getCACerts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ NameValuePairs pairs = jssSubSystem.getCACerts();
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void deleteRootCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ int mindex = id.indexOf(":SERIAL#<");
+ String nickname = id.substring(0, mindex);
+ String sstr1 = id.substring(mindex);
+ int lindex = sstr1.indexOf(">");
+ String serialno = sstr1.substring(9, lindex);
+ String issuername = sstr1.substring(lindex+1);
+ jssSubSystem.deleteRootCert(nickname, serialno, issuername);
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void deleteUserCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ int mindex = id.indexOf(":SERIAL#<");
+ String nickname = id.substring(0, mindex);
+ String sstr1 = id.substring(mindex);
+ int lindex = sstr1.indexOf(">");
+ String serialno = sstr1.substring(9, lindex);
+ String issuername = sstr1.substring(lindex+1);
+ jssSubSystem.deleteUserCert(nickname, serialno, issuername);
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void getRootCerts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ NameValuePairs pairs = jssSubSystem.getRootCerts();
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void getAllCertsManage(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ NameValuePairs pairs = jssSubSystem.getAllCertsManage();
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void getUserCerts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ NameValuePairs pairs = jssSubSystem.getUserCerts();
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void deleteCerts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String nickname = "";
+ String date = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.OP_TYPE))
+ continue;
+ if (key.equals(Constants.RS_ID))
+ continue;
+ if (key.equals(Constants.OP_SCOPE))
+ continue;
+ int index = value.indexOf(";");
+
+ nickname = value.substring(0, index);
+ date = value.substring(index + 1);
+ // cant use this one now since jss doesnt have the interface to
+ // do it.
+ jssSubSystem.deleteCert(nickname, date);
+ // jssSubsystem.deleteCACert(nickname, date);
+ }
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void validateSubjectName(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_SUBJECT_NAME)) {
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ jssSubSystem.isX500DN(value);
+ }
+ }
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void validateKeyLength(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ String keyType = "RSA";
+ String keyLen = "512";
+ String certType = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_CERTIFICATE_TYPE)) {
+ certType = value;
+ } else if (key.equals(Constants.PR_KEY_TYPE)) {
+ keyType = value;
+ } else if (key.equals(Constants.PR_KEY_LENGTH)) {
+ keyLen = value;
+ }
+ }
+ int keyLength = Integer.parseInt(keyLen);
+ int minKey = mConfig.getInteger(
+ ConfigConstants.PR_RSA_MIN_KEYLENGTH, 512);
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ // jssSubSystem.checkKeyLength(keyType, keyLength, certType, minKey);
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void validateCurveName(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ String curveName = null;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_KEY_CURVENAME)) {
+ curveName = value;
+ }
+ }
+ // check that the curvename is in the list of supported curves
+ String curveList = mConfig.getString("keys.ecc.curve.list", "nistp521");
+ String[] curves = curveList.split(",");
+ boolean match = false;
+ for (int i=0; i<curves.length; i++) {
+ if (curves[i].equals(curveName)) {
+ match = true;
+ }
+ }
+ if (!match) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ECC_CURVE_NAME"));
+ }
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void validateCertExtension(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ String certExt = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(ConfigConstants.PR_CERTIFICATE_EXTENSION)) {
+ certExt = value;
+ break;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ jssSubSystem.checkCertificateExt(certExt);
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void getSubjectName(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration enum1 = req.getParameterNames();
+
+ String nickname = "";
+ String keyType = "RSA";
+ String keyLen = "512";
+ String certType = "";
+ String configDir = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.RS_ID)) {
+ certType = value;
+ nickname = getNickname(value);
+ break;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String subjectName = jssSubSystem.getSubjectDN(nickname);
+
+ params.add(Constants.PR_SUBJECT_NAME, subjectName);
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void processSubjectName(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration enum1 = req.getParameterNames();
+
+ String nickname = "";
+ String keyType = "RSA";
+ String keyLen = "512";
+ String certType = "";
+ String configDir = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_NICKNAME)) {
+ nickname = value;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String subjectName = jssSubSystem.getSubjectDN(nickname);
+
+ params.add(Constants.PR_SUBJECT_NAME, subjectName);
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ public void setRootCertTrust(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String nickname = req.getParameter(Constants.PR_NICK_NAME);
+ String serialno = req.getParameter(Constants.PR_SERIAL_NUMBER);
+ String issuername = req.getParameter(Constants.PR_ISSUER_NAME);
+ String trust = req.getParameter("trustbit");
+
+ CMS.debug("CMSAdminServlet: setRootCertTrust()");
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ try {
+ jssSubSystem.setRootCertTrust(nickname, serialno, issuername, trust);
+ } catch (EBaseException e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ // rethrow the specific exception to be handled later
+ throw e;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /**
+ * Establish trust of a CA certificate
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY used when
+ * "Manage Certificate" is used to edit the trustness of certs and
+ * deletion of certs
+ * </ul>
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException failed to establish CA certificate trust
+ */
+ private void trustCACert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ CMS.debug("CMSAdminServlet: trustCACert()");
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ Enumeration enum1 = req.getParameterNames();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String trust = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.RS_ID)) {
+ trust = value;
+ } else if (key.equals("certName0")) {
+ int index = value.indexOf(";");
+ String nickname = value.substring(0, index);
+ String date = value.substring(index + 1);
+
+ jssSubSystem.trustCert(nickname, date, trust);
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ //sendResponse(SUCCESS, null, null, resp);
+ sendResponse(RESTART, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Execute all self tests specified to be run on demand.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION used when self
+ * tests are run on demand
+ * </ul>
+ * @exception EMissingSelfTestException a self test plugin instance
+ * property name was missing
+ * @exception ESelfTestException a self test is missing a required
+ * configuration parameter
+ * @exception IOException an input/output error has occurred
+ */
+ private synchronized void
+ runSelfTestsOnDemand(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws EMissingSelfTestException,
+ ESelfTestException,
+ IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ if (CMS.debugOn()) {
+ CMS.debug("CMSAdminServlet::runSelfTestsOnDemand():"
+ + " ENTERING . . .");
+ }
+
+ Enumeration enum1 = req.getParameterNames();
+ String request = "";
+ NameValuePairs results = new NameValuePairs();
+ String content = "";
+ String instanceName = null;
+ String instanceFullName = null;
+ String logMessage = null;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_RUN_SELFTESTS_ON_DEMAND)) {
+ request = value;
+ }
+ }
+
+ ISelfTestSubsystem mSelfTestSubsystem = (ISelfTestSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_SELFTESTS);
+
+ if ((request == null) ||
+ (request.equals(""))) {
+ // self test plugin run on demand request parameter was missing
+ // log the error
+ logMessage = CMS.getLogMessage("SELFTESTS_RUN_ON_DEMAND_REQUEST",
+ getServletInfo(),
+ Constants.PR_RUN_SELFTESTS_ON_DEMAND
+ );
+
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // notify console of FAILURE
+ content += logMessage
+ + "\n";
+ sendResponse(ERROR, content, null, resp);
+
+ // raise an exception
+ throw new ESelfTestException(logMessage);
+ }
+
+ // run all self test plugin instances (designated on-demand)
+ String[] selftests = mSelfTestSubsystem.listSelfTestsEnabledOnDemand();
+
+ if (selftests != null && selftests.length > 0) {
+ // log that execution of on-demand self tests has begun
+ logMessage = CMS.getLogMessage("SELFTESTS_RUN_ON_DEMAND",
+ getServletInfo());
+
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store this information for console notification
+ content += logMessage
+ + "\n";
+
+ for (int i = 0; i < selftests.length; i++) {
+ if (selftests[i] != null) {
+ instanceName = selftests[i].trim();
+ instanceFullName = ISelfTestSubsystem.ID
+ + "."
+ + ISelfTestSubsystem.PROP_CONTAINER
+ + "."
+ + ISelfTestSubsystem.PROP_INSTANCE
+ + "."
+ + instanceName;
+ } else {
+ // self test plugin instance property name was missing
+ // log the error
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_PARAMETER_WAS_NULL",
+ getServletInfo());
+
+ mSelfTestSubsystem.log(
+ mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // notify console of FAILURE
+ content += logMessage
+ + "\n";
+ sendResponse(ERROR, content, null, resp);
+
+ // raise an exception
+ throw new EMissingSelfTestException();
+ }
+
+ ISelfTest test = (ISelfTest)
+ mSelfTestSubsystem.getSelfTest(instanceName);
+
+ if (test == null) {
+ // self test plugin instance property name is not present
+ // log the error
+ logMessage = CMS.getLogMessage("SELFTESTS_MISSING_NAME",
+ getServletInfo(),
+ instanceFullName);
+
+ mSelfTestSubsystem.log(
+ mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // notify console of FAILURE
+ content += logMessage
+ + "\n";
+ sendResponse(ERROR, content, null, resp);
+
+ // raise an exception
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+
+ try {
+ if (CMS.debugOn()) {
+ CMS.debug("CMSAdminServlet::runSelfTestsOnDemand():"
+ + " running \""
+ + test.getSelfTestName()
+ + "\"");
+ }
+
+ // store this information for console notification
+ content += "CMSAdminServlet::runSelfTestsOnDemand():"
+ + " running \""
+ + test.getSelfTestName()
+ + "\" . . .\n";
+
+ test.runSelfTest(mSelfTestSubsystem.getSelfTestLogger());
+
+ // store this information for console notification
+ content += "COMPLETED SUCCESSFULLY\n";
+ } catch (ESelfTestException e) {
+ // Check to see if the self test was critical:
+ if (mSelfTestSubsystem.isSelfTestCriticalOnDemand(
+ instanceName)) {
+ // log the error
+ logMessage = CMS.getLogMessage(
+ "SELFTESTS_RUN_ON_DEMAND_FAILED",
+ getServletInfo(),
+ instanceFullName);
+
+ mSelfTestSubsystem.log(
+ mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // notify console of FAILURE
+ content += "FAILED WITH CRITICAL ERROR\n";
+ content += logMessage
+ + "\n";
+ sendResponse(ERROR, content, null, resp);
+
+ // shutdown the system gracefully
+ CMS.shutdown();
+
+ return;
+ } else {
+ // store this information for console notification
+ content += "FAILED WITH NON-CRITICAL ERROR\n";
+ }
+ }
+ }
+
+ // log that execution of all "critical" on-demand self tests
+ // has completed "successfully"
+ logMessage = CMS.getLogMessage("SELFTESTS_RUN_ON_DEMAND_SUCCEEDED",
+ getServletInfo());
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store this information for console notification
+ content += logMessage
+ + "\n";
+ } else {
+ // log this fact
+ logMessage = CMS.getLogMessage("SELFTESTS_NOT_RUN_ON_DEMAND",
+ getServletInfo());
+
+ mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
+ logMessage);
+
+ // store this information for console notification
+ content += logMessage
+ + "\n";
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.SUCCESS);
+
+ audit(auditMessage);
+
+ // notify console of SUCCESS
+ results.add(Constants.PR_RUN_SELFTESTS_ON_DEMAND_CLASS,
+ CMSAdminServlet.class.getName());
+ results.add(Constants.PR_RUN_SELFTESTS_ON_DEMAND_CONTENT,
+ content);
+ sendResponse(SUCCESS, null, results, resp);
+
+ if (CMS.debugOn()) {
+ CMS.debug("CMSAdminServlet::runSelfTestsOnDemand():"
+ + " EXITING.");
+ }
+ } catch (EMissingSelfTestException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (ESelfTestException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ } catch (IOException eAudit3) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ auditSubjectID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit3;
+ }
+ }
+
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level, "CMSAdminServlet: " + msg);
+ }
+
+ /**
+ * Signed Audit Log Public Key
+ *
+ * This method is called to obtain the public key from the passed in
+ * "KeyPair" object for a signed audit log message.
+ * <P>
+ *
+ * @param object a Key Pair Object
+ * @return key string containing the public key
+ */
+ private String auditPublicKey(KeyPair object) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (object == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ rawData = object.getPublic().getEncoded();
+
+ String key = null;
+ StringBuffer sb = new StringBuffer();
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ sb.append(base64Data.substring(i, i));
+ }
+ }
+ }
+ key = sb.toString();
+
+ if (key != null) {
+ key = key.trim();
+
+ if (key.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return key;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java
new file mode 100644
index 000000000..af506433d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java
@@ -0,0 +1,1004 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class representing an administration servlet for the
+ * Jobs Scheduler and it's scheduled jobs.
+ *
+ * @version $Revision$, $Date$
+ */
+public class JobsAdminServlet extends AdminServlet {
+ // ... remove later
+ private final static String EDIT = ";edit";
+ private final static String VISIBLE = ";visible";
+ private final static String ENABLED = ";enabled";
+ private final static String DISABLED = ";disabled";
+
+ private final static String INFO = "JobsAdminServlet";
+ private IJobsScheduler mJobsSched = null;
+
+ /**
+ * Constructs JobsAdminServlet.
+ */
+ public JobsAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mJobsSched = (IJobsScheduler)
+ CMS.getSubsystem(CMS.SUBSYSTEM_JOBS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description, type info
+ * from jobs
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+
+ NameValuePairs params =
+ getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+
+ JobPlugin jp =
+ (JobPlugin) mJobsSched.getPlugins().get(implName);
+
+ if (jp != null)
+ impl = getClassByNameAsExtendedPluginInfo(jp.getClassPath());
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op == null) {
+ //System.out.println("SRVLT_INVALID_PROTOCOL");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ try {
+ super.authenticate(req);
+ } catch (IOException e) {
+ sendResponse(ERROR,CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+
+ try {
+ AUTHZ_RES_NAME = "certServer.job.configuration";
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_JOBS))
+ getSettings(req, resp);
+ else if (scope.equals(ScopeDef.SC_JOBS_IMPLS))
+ getConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_JOBS_INSTANCE))
+ getInstConfig(req, resp);
+ else if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ try {
+ getExtendedPluginInfo(req, resp);
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ } else {
+ //System.out.println("SRVLT_INVALID_OP_SCOPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_JOBS)) {
+ setSettings(req, resp);
+ } else if (scope.equals(ScopeDef.SC_JOBS_INSTANCE)) {
+ modJobsInst(req, resp, scope);
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_JOBS_IMPLS))
+ listJobPlugins(req, resp);
+ else if (scope.equals(ScopeDef.SC_JOBS_INSTANCE))
+ listJobsInsts(req, resp);
+ else {
+ //System.out.println("SRVLT_INVALID_OP_SCOPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_JOBS_IMPLS))
+ addJobPlugin(req, resp, scope);
+ else if (scope.equals(ScopeDef.SC_JOBS_INSTANCE))
+ addJobsInst(req, resp, scope);
+ else {
+ //System.out.println("SRVLT_INVALID_OP_SCOPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_JOBS_IMPLS))
+ delJobPlugin(req, resp, scope);
+ else if (scope.equals(ScopeDef.SC_JOBS_INSTANCE))
+ delJobsInst(req, resp, scope);
+ else {
+ //System.out.println("SRVLT_INVALID_OP_SCOPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_TYPE", op),
+ null, resp);
+ return;
+ }
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ }
+
+ private synchronized void addJobPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+ // is the job plugin id unique?
+ if (mJobsSched.getPlugins().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ new EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ILL_JOB_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_JOBS_CLASS);
+
+ if (classPath == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_NULL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_NO_CLASS"),
+ null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_NO_CLASS"),
+ null, resp);
+ return;
+ }
+
+ // is the class an IJob?
+ try {
+ if (IJob.class.isAssignableFrom(newImpl) == false) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_JOBS_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add manager to registry.
+ JobPlugin plugin = new JobPlugin(id, classPath);
+
+ mJobsSched.getPlugins().put(id, plugin);
+ mJobsSched.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_JS_PLUGIN_ADD", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void addJobsInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the job instance id unique?
+ if (mJobsSched.getInstances().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ILL_JOB_INST_ID"),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ // SC_JOBS_IMPL_NAME is absolutely required, the rest depend on
+ // on each job plugin
+ String implname = req.getParameter(Constants.PR_JOBS_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ADD_MISSING_PARAMS"),
+ null, resp);
+ return;
+ }
+
+ // check if implementation exists.
+ JobPlugin plugin =
+ (JobPlugin) mJobsSched.getPlugins().get(implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new
+ EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_PLUGIN_NOT_FOUND",
+ id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // now the rest of config parameters
+ // note that we only check to see if the required parameters
+ // are there, but not checking the values are valid
+ String[] configParams = mJobsSched.getConfigParams(implname);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+ String val = req.getParameter(key);
+
+ if (val != null && !val.equals("")) {
+ substore.put(key, val);
+ } else if (!key.equals("profileId")) {
+ sendResponse(ERROR,
+ new
+ EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_MISSING_INST_PARAM_VAL",
+ key)).toString(),
+ null, resp);
+ return;
+ }
+ }
+ }
+
+ substore.put(IJobsScheduler.PROP_PLUGIN, implname);
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ IJob jobsInst = null;
+
+ try {
+ jobsInst = (IJob) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ IJobsScheduler scheduler = (IJobsScheduler)
+ CMS.getSubsystem(CMS.SUBSYSTEM_JOBS);
+
+ // initialize the job plugin
+ try {
+ jobsInst.init(scheduler, id, implname, substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // inited and commited ok. now add manager instance to list.
+ mJobsSched.getInstances().put(id, jobsInst);
+
+ mJobsSched.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_JOB_INST_ADD", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_JOBS_IMPL_NAME, implname);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listJobPlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mJobsSched.getPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ JobPlugin value = (JobPlugin)
+ mJobsSched.getPlugins().get(name);
+
+ params.add(name, value.getClassPath());
+ // params.add(name, value.getClassPath()+EDIT);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listJobsInsts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ for (Enumeration e = mJobsSched.getInstances().keys();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ IJob value = (IJob)
+ mJobsSched.getInstances().get((Object) name);
+
+ // params.add(name, value.getImplName());
+ params.add(name, value.getImplName() + VISIBLE +
+ (value.isEnabled() ? ENABLED : DISABLED)
+ );
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delJobPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does this job plugin exist?
+ if (mJobsSched.getPlugins().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new
+ EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_PLUGIN_NOT_FOUND",
+ id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this job plugin
+ // DON'T remove job plugin if any instance
+ for (Enumeration e = mJobsSched.getInstances().elements();
+ e.hasMoreElements();) {
+ IJob jobs = (IJob) e.nextElement();
+
+ if ((jobs.getImplName()).equals(id)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_IN_USE"),
+ null, resp);
+ return;
+ }
+ }
+
+ // then delete this job plugin
+ mJobsSched.getPlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delJobsInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does job plugin instance exist?
+ if (mJobsSched.getInstances().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_NOT_FOUND",
+ id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ IJob jobInst = (IJob) mJobsSched.getInstances().get(id);
+
+ mJobsSched.getInstances().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * used for getting the required configuration parameters (with
+ * possible default values) for a particular job plugin
+ * implementation name specified in the RS_ID. Actually, there is
+ * no logic in here to set any default value here...there's no
+ * default value for any parameter in this job scheduler subsystem
+ * at this point. Later, if we do have one (or some), it can be
+ * added. The interface remains the same.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ String[] configParams = mJobsSched.getConfigParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_JOBS_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ params.add(configParams[i], "");
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does job plugin instance exist?
+ if (mJobsSched.getInstances().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_NOT_FOUND",
+ id)).toString(),
+ null, resp);
+ return;
+ }
+
+ IJob jobInst = (IJob) mJobsSched.getInstances().get(id);
+ IConfigStore config = jobInst.getConfigStore();
+ String[] configParams = jobInst.getConfigParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_JOBS_IMPL_NAME, jobInst.getImplName());
+
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+
+ String val = (String) config.get(key);
+
+ if (val != null && !val.equals("")) {
+ params.add(key, val);
+ } else {
+ params.add(key, "");
+ }
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Modify job plugin instance.
+ * This will actually create a new instance with new configuration
+ * parameters and replace the old instance, if the new instance
+ * created and initialized successfully.
+ * The old instance is left running. so this is very expensive.
+ * Restart of server recommended.
+ */
+ private synchronized void modJobsInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ // expensive operation.
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the job instance exist?
+ if (!mJobsSched.getInstances().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ILL_JOB_INST_ID"),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_JOBS_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_ADD_MISSING_PARAMS"),
+ null, resp);
+ return;
+ }
+
+ // get plugin for implementation
+ JobPlugin plugin =
+ (JobPlugin) mJobsSched.getPlugins().get(implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_JOB_PLUGIN_NOT_FOUND",
+ id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ IJob oldinst =
+ (IJob) mJobsSched.getInstances().get((Object) id);
+ IConfigStore oldConfig = oldinst.getConfigStore();
+
+ String[] oldConfigParms = oldinst.getConfigParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.add(IJobsScheduler.PROP_PLUGIN,
+ (String) oldConfig.get(IJobsScheduler.PROP_PLUGIN));
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.length; i++) {
+ String key = oldConfigParms[i];
+ Object val = oldConfig.get(key);
+
+ if (val != null) {
+ saveParams.add(key, (String) val);
+ }
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+ IConfigStore instancesConfig =
+ destStore.getSubStore(scope);
+
+ instancesConfig.removeSubStore(id);
+
+ // create new substore.
+
+ String[] configParams = mJobsSched.getConfigParams(implname);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(IJobsScheduler.PROP_PLUGIN, implname);
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ String key = configParams[i];
+ String val = req.getParameter(key);
+
+ if (val != null && !val.equals("")) {
+ substore.put(key, val);
+ } else if (!key.equals("profileId")) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new
+ EJobsException(CMS.getUserMessage(getLocale(req),"CMS_JOB_SRVLT_MISSING_INST_PARAM_VAL",
+ key)).toString(),
+ null, resp);
+ return;
+ }
+ }
+ }
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ IJob newJobInst = null;
+
+ try {
+ newJobInst = (IJob) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new EJobsException(
+ CMS.getUserMessage(getLocale(req),"CMS_JOB_LOAD_CLASS_FAILED", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the job plugin
+
+ IJobsScheduler scheduler = (IJobsScheduler)
+ CMS.getSubsystem(CMS.SUBSYSTEM_JOBS);
+
+ try {
+ newJobInst.init(scheduler, id, implname, substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Exception e) {
+ CMS.debug("JobsAdminServlet: modJobsInst: " + e);
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, "unidentified error" + e, null, resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+
+ } catch (EBaseException e) {
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ mJobsSched.getInstances().put(id, newJobInst);
+
+ mJobsSched.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_JOB_INST_REP", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private void getSettings(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ IConfigStore config = mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+
+ params.add(Constants.PR_ENABLE,
+ config.getString(IJobsScheduler.PROP_ENABLED,
+ Constants.FALSE));
+ // default 1 minute
+ params.add(Constants.PR_JOBS_FREQUENCY,
+ config.getString(IJobsScheduler.PROP_INTERVAL, "1"));
+
+ //System.out.println("Send: "+params.toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setSettings(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ //Save New Settings to the config file
+ IConfigStore config = mConfig.getSubStore(DestDef.DEST_JOBS_ADMIN);
+
+ String enabled = config.getString(IJobsScheduler.PROP_ENABLED);
+ String enabledSetTo = req.getParameter(Constants.PR_ENABLE);
+ boolean enabledChanged = false;
+
+ if (!enabled.equalsIgnoreCase(enabledSetTo)) {
+ enabledChanged = true;
+ // set enable flag
+ config.putString(IJobsScheduler.PROP_ENABLED, enabledSetTo);
+ }
+
+ //set frequency
+ String interval =
+ req.getParameter(Constants.PR_JOBS_FREQUENCY);
+
+ if (interval != null) {
+ config.putString(IJobsScheduler.PROP_INTERVAL, interval);
+ mJobsSched.setInterval(
+ config.getInteger(IJobsScheduler.PROP_INTERVAL));
+ }
+
+ if (enabledChanged == true) {
+ if (enabled.equalsIgnoreCase("false")) { // turned on
+ mJobsSched.startDaemon();
+ }
+ }
+ mConfig.commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ // convenience routine.
+ private static void restore(IConfigStore store,
+ String id, NameValuePairs saveParams) {
+ store.removeSubStore(id);
+ IConfigStore rstore = store.makeSubStore(id);
+
+ Enumeration keys = saveParams.getNames();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String value = saveParams.getValue(key);
+
+ if (!value.equals(""))
+ rstore.put(key, value);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java
new file mode 100644
index 000000000..423095d51
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java
@@ -0,0 +1,887 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.usrgrp.*;
+
+
+/**
+ * A class representings an administration servlet for Key
+ * Recovery Authority. This servlet is responsible to serve
+ * KRA administrative operation such as configuration
+ * parameter updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KRAAdminServlet extends AdminServlet {
+ protected static final String PROP_ENABLED = "enabled";
+
+ private final static String INFO = "KRAAdminServlet";
+
+ private IKeyRecoveryAuthority mKRA = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_DRM =
+ "LOGGING_SIGNED_AUDIT_CONFIG_DRM_3";
+
+ /**
+ * Constructs KRA servlet.
+ */
+ public KRAAdminServlet() {
+ super();
+ }
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mKRA = (IKeyRecoveryAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+ }
+
+ /**
+ * Returns serlvet information.
+ *
+ * @return name of this servlet
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP admin request.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ super.authenticate(req);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (scope == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_TYPE", op),
+ null, resp);
+ return;
+ }
+
+ try {
+ AUTHZ_RES_NAME = "certServer.kra.configuration";
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ /* Functions not implemented in console
+ if (scope.equals(ScopeDef.SC_AUTO_RECOVERY)) {
+ readAutoRecoveryConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RECOVERY)) {
+ readRecoveryConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ)) {
+ getNotificationRIQConfig(req, resp);
+ return;
+ } else
+ */
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ getGeneralConfig(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ /* Functions not implemented in console
+ if (scope.equals(ScopeDef.SC_AUTO_RECOVERY)) {
+ modifyAutoRecoveryConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_AGENT_PWD)) {
+ changeAgentPwd(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MNSCHEME)) {
+ changeMNScheme(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ)) {
+ setNotificationRIQConfig(req, resp);
+ return;
+ } else
+ */
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ setGeneralConfig(req,resp);
+ }
+ }
+ } catch (EBaseException e) {
+ // convert exception into locale-specific message
+ sendResponse(ERROR, e.toString(getLocale(req)),
+ null, resp);
+ return;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ }
+
+ private void getGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ int value = 1;
+
+ value = mKRA.getNoOfRequiredAgents();
+ params.add(Constants.PR_NO_OF_REQUIRED_RECOVERY_AGENTS, Integer.toString(value));
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ Enumeration enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_NO_OF_REQUIRED_RECOVERY_AGENTS)) {
+ try {
+ int number = Integer.parseInt(value);
+ mKRA.setNoOfRequiredAgents(number);
+ } catch (NumberFormatException e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ throw new EBaseException("Number of agents must be an integer");
+ }
+ }
+ }
+
+ commit(true);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ if (restart)
+ sendResponse(RESTART, null, null, resp);
+ else
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /**
+ * Changes M-N scheme.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_DRM used when configuring
+ * DRM (Key recovery scheme, change of any secret component)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void changeMNScheme(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ try {
+ NameValuePairs params = new NameValuePairs();
+ String recN = getParameter(req,
+ Constants.PR_RECOVERY_N);
+ String recM = getParameter(req,
+ Constants.PR_RECOVERY_M);
+ String oldAgents = getParameter(req,
+ Constants.PR_OLD_RECOVERY_AGENT);
+ String agents = getParameter(req,
+ Constants.PR_RECOVERY_AGENT);
+
+ if (recN == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EKRAException(
+ CMS.getLogMessage("KRA_INVALID_N"));
+ }
+
+ if (recM == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EKRAException(
+ CMS.getLogMessage("KRA_INVALID_M"));
+ }
+
+ if (recN != null && recM != null && oldAgents != null
+ && agents != null) {
+ int nVal = Integer.parseInt(recN);
+
+ int mVal = Integer.parseInt(recM);
+
+ Credential oldcreds[] =
+ parseCredentialStr(oldAgents);
+
+ if (oldcreds == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EKRAException(
+ CMS.getLogMessage("KRA_INVALID_PASSWORD"));
+ }
+
+ Credential creds[] =
+ parseCredentialStr(agents);
+
+ if (creds == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EKRAException(
+ CMS.getLogMessage("KRA_INVALID_PASSWORD"));
+ } else {
+ for (int i = 0; i < creds.length; i++) {
+ Credential credential = creds[i];
+ String pass = credential.getPassword();
+ IPasswordCheck checker = CMS.getPasswordChecker();
+
+ if (!checker.isGoodPassword(pass)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(checker.getReason(pass));
+ }
+ }
+ }
+ if (mKRA.getStorageKeyUnit().changeAgentMN(
+ nVal, mVal, oldcreds, creds)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // successful operation
+ sendResponse(SUCCESS, null, params,
+ resp);
+ return;
+ }
+ }
+ } catch (IOException e) {
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ /**
+ * Changes recovery agent password.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_DRM used when configuring
+ * DRM (Key recovery scheme, change of any secret component)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void changeAgentPwd(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ try {
+ String id = getParameter(req, Constants.RS_ID);
+ String oldpwd = getParameter(req,
+ Constants.PR_OLD_AGENT_PWD);
+ String newpwd = getParameter(req,
+ Constants.PR_AGENT_PWD);
+ IPasswordCheck checker = CMS.getPasswordChecker();
+
+ if (!checker.isGoodPassword(newpwd)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(checker.getReason(newpwd));
+ }
+
+ if (mKRA.getStorageKeyUnit().changeAgentPassword(id,
+ oldpwd, newpwd)) {
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EKRAException(
+ CMS.getLogMessage("KRA_INVALID_PASSWORD"));
+ }
+ } catch (IOException e) {
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ /**
+ * Modifies auto recovery configuration.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_DRM used when configuring
+ * DRM (Key recovery scheme, change of any secret component)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modifyAutoRecoveryConfig(
+ HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ try {
+ NameValuePairs params = new NameValuePairs();
+ String autoOn = getParameter(req,
+ Constants.PR_AUTO_RECOVERY_ON);
+ String agents = getParameter(req,
+ Constants.PR_RECOVERY_AGENT);
+
+ if (autoOn.equals(Constants.TRUE)) {
+ Credential creds[] = parseCredentialStr(
+ agents);
+
+ if (mKRA.setAutoRecoveryState(creds, true)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params,
+ resp);
+ return;
+ }
+ } else if (autoOn.equals(Constants.FALSE)) {
+ if (mKRA.setAutoRecoveryState(null, false)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params,
+ resp);
+ return;
+ }
+ }
+ } catch (IOException e) {
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ /**
+ * Reads auto recovery status.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ private synchronized void readAutoRecoveryConfig(
+ HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_AUTO_RECOVERY_ON,
+ mKRA.getAutoRecoveryState() ?
+ Constants.TRUE : Constants.FALSE);
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ }
+ }
+
+ /**
+ * Reads recovery configuration.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ private synchronized void readRecoveryConfig(
+ HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+ try {
+ IStorageKeyUnit sku = mKRA.getStorageKeyUnit();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_RECOVERY_N,
+ Integer.toString(sku.getNoOfAgents()));
+ params.add(Constants.PR_RECOVERY_M,
+ Integer.toString(sku.getNoOfRequiredAgents()));
+ Enumeration e = sku.getAgentIdentifiers();
+ StringBuffer as = new StringBuffer();
+
+ while (e.hasMoreElements()) {
+ as.append((String)e.nextElement());
+ if (e.hasMoreElements()) {
+ as.append(",");
+ }
+ }
+ params.add(Constants.PR_RECOVERY_AGENT, as.toString());
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ }
+ }
+
+ /**
+ * Reads information about auto recovery agents.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ private synchronized void readAutoRecoveryAgents(
+ HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+ try {
+ // send the entire list anyway
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mKRA.getAutoRecoveryIDs();
+ StringBuffer users = new StringBuffer();
+
+ while (e.hasMoreElements()) {
+ users.append((String) e.nextElement());
+ if (e.hasMoreElements()) {
+ users.append(",");
+ }
+ }
+ params.add(Constants.PR_GROUP_USER, users.toString());
+ params.add(Constants.PR_GROUP_DESC,
+ "Auto Recovery Agents"); // XXX - localized
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getLogMessage("BASE_INVALID_OPERATION"));
+ }
+ }
+
+ /**
+ * Modifies information about auto recovery agents.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ private synchronized void modifyAutoRecoveryAgents(
+ HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+ Vector v = new Vector();
+ String users = getParameter(req,
+ Constants.PR_GROUP_USER);
+ StringTokenizer st = new StringTokenizer(users, ",");
+
+ while (st.hasMoreTokens()) {
+ v.addElement(st.nextToken());
+ }
+ String desc = getParameter(req,
+ Constants.PR_GROUP_DESC);
+ String agents = getParameter(req,
+ Constants.PR_RECOVERY_AGENT);
+ Credential creds[] = parseCredentialStr(
+ agents);
+ // XXX - check if the given password matched
+ // put ids into hashtable so that we can
+ // figure out what should be saved and deleted
+ Enumeration e = mKRA.getAutoRecoveryIDs();
+ Hashtable h = new Hashtable();
+
+ while (e.hasMoreElements()) {
+ h.put(e.nextElement(), "");
+ }
+
+ // go through each of the user in the new list
+ for (int i = 0; i < v.size(); i++) {
+ String key = (String) v.elementAt(i);
+
+ if (h.containsKey(key)) {
+ h.remove(key);
+ } else {
+ mKRA.addAutoRecovery(key, creds);
+ }
+ }
+
+ // delete all the unreferenced
+ Enumeration dels = h.keys();
+
+ while (dels.hasMoreElements()) {
+ mKRA.removeAutoRecovery((String)
+ dels.nextElement());
+ }
+ }
+
+ /**
+ * Parses uid0=pwd0,uid1=pwd1,... into AgentCredential.
+ *
+ * @param s credential string
+ * @return a list of credentials
+ */
+ private Credential[] parseCredentialStr(String s) {
+ StringTokenizer st = new StringTokenizer(s, ",");
+ Vector v = new Vector();
+
+ while (st.hasMoreTokens()) {
+ String a = st.nextToken();
+ StringTokenizer st0 = new StringTokenizer(a, "=");
+
+ v.addElement(new Credential(st0.nextToken(),
+ st0.nextToken()));
+ }
+ Credential ac[] = new Credential[v.size()];
+
+ v.copyInto(ac);
+ return ac;
+ }
+
+ /*
+ * handle getting request in queue notification config info
+ */
+ private void getNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ IConfigStore config = mKRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mKRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mKRA.PROP_REQ_IN_Q_SUBSTORE);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, riq.getString(name, ""));
+ }
+
+ params.add(Constants.PR_ENABLE,
+ riq.getString(PROP_ENABLED, Constants.FALSE));
+ //System.out.println("Send: "+params.toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Handle setting request in queue notification config info
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_DRM used when configuring
+ * DRM (Key recovery scheme, change of any secret component)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ IConfigStore config = mKRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mKRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mKRA.PROP_REQ_IN_Q_SUBSTORE);
+
+ //set rest of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String val = req.getParameter(name);
+
+ riq.putString(name, val);
+ mKRA.getRequestInQListener().set(name, val);
+ }
+
+ // set enable flag
+ String enabledString = req.getParameter(Constants.PR_ENABLE);
+
+ riq.putString(PROP_ENABLED, enabledString);
+ mKRA.getRequestInQListener().set(PROP_ENABLED, enabledString);
+
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_DRM,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java
new file mode 100644
index 000000000..f8350da9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java
@@ -0,0 +1,2550 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class representings an administration servlet for logging
+ * subsystem. This servlet is responsible to serve
+ * logging administrative operation such as configuration
+ * parameter updates and log retriever.
+ *
+ * @version $Revision$, $Date$
+ */
+public class LogAdminServlet extends AdminServlet {
+
+ private final static String INFO = "LogAdminServlet";
+
+ private ILogSubsystem mSys = null;
+
+ private final static String VIEW = ";" + Constants.VIEW;
+ private final static String EDIT = ";" + Constants.EDIT;
+
+ private final static String SIGNED_AUDIT_LOG_TYPE = "SignedAudit";
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT =
+ "LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT_3";
+ private final static String LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE =
+ "LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE_4";
+ private final static String LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE =
+ "LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE_4";
+
+ /**
+ * Constructs Log servlet.
+ */
+ public LogAdminServlet() {
+ super();
+ }
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ httpReqHash.put(name, req.getParameter(name));
+ }
+ return httpReqHash;
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mSys = (ILogSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_LOG);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ super.authenticate(req);
+
+ try {
+ // perform operation based on scope
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (scope != null) {
+ AUTHZ_RES_NAME = "certServer.log.configuration";
+ if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ try {
+ getExtendedPluginInfo(req, resp);
+ return;
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ }
+
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ if (scope.equals(ScopeDef.SC_LOG_IMPLS)) {
+ getConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_RULES)) {
+ getInstConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_GENERAL)) {
+ getGeneralConfig(req, resp);
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ if (scope.equals(ScopeDef.SC_LOG_IMPLS)) {
+ delLogPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_RULES)) {
+ delLogInst(req, resp, scope);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ if (scope.equals(ScopeDef.SC_LOG_IMPLS)) {
+ addLogPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_RULES)) {
+ addLogInst(req, resp, scope);
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ AUTHZ_RES_NAME = "certServer.log.configuration";
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ if (scope.equals(ScopeDef.SC_LOG_RULES)) {
+ modLogInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_GENERAL)) {
+ setGeneralConfig(req, resp);
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LOG_IMPLS)) {
+ listLogPlugins(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_RULES)) {
+ listLogInsts(req, resp, true);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_INSTANCES)) {
+ listLogInsts(req, resp, false);
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_CONTENT)) {
+ String instName = req.getParameter(Constants.PR_LOG_INSTANCE);
+
+ if (instName.equals("System")) {
+ AUTHZ_RES_NAME = "certServer.log.content.system";
+ } else if (instName.equals("Transactions")) {
+ AUTHZ_RES_NAME = "certServer.log.content.transactions";
+ } else if (instName.equals(Constants.PR_LOG_SIGNED_AUDIT)) {
+ AUTHZ_RES_NAME = "certServer.log.content.signedAudit";
+ }
+
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ ILogEventListener loginst =
+ mSys.getLogInstance(instName);
+
+ if (loginst != null) {
+ NameValuePairs nvps = loginst.retrieveLogContent(toHashtable(req));
+
+ sendResponse(SUCCESS, null, nvps, resp);
+ }
+ return;
+ } else if (scope.equals(ScopeDef.SC_LOG_ARCH)) {
+ String instName = req.getParameter(Constants.PR_LOG_INSTANCE);
+
+ if (instName.equals("System")) {
+ AUTHZ_RES_NAME = "certServer.log.content.system";
+ } else if (instName.equals("Transactions")) {
+ AUTHZ_RES_NAME = "certServer.log.content.transactions";
+ } else if (instName.equals(Constants.PR_LOG_SIGNED_AUDIT)) {
+ AUTHZ_RES_NAME = "certServer.log.content.signedAudit";
+ }
+
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ ILogEventListener loginst =
+ mSys.getLogInstance(instName);
+
+ if (loginst != null) {
+ NameValuePairs nvps = loginst.retrieveLogList(toHashtable(req));
+
+ sendResponse(SUCCESS, null, nvps, resp);
+ }
+ return;
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_TYPE", op),
+ null, resp);
+ return;
+ }
+ }
+ } catch (EBaseException e) {
+ // if it is EBaseException, we can output better
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ } catch (Exception e) {
+ System.out.println("XXX >>>" + e.toString() + "<<<");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ }
+
+ return;
+ }
+
+ private synchronized void listLogInsts(HttpServletRequest req,
+ HttpServletResponse resp, boolean all) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String insts = null;
+ Enumeration e = mSys.getLogInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILogEventListener value = ((ILogSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_LOG)).getLogInstance(name);
+
+ if (value == null)
+ continue;
+ String pName = mSys.getLogPluginName(value);
+ LogPlugin pClass = (LogPlugin)
+ mSys.getLogPlugins().get(pName);
+ String c = pClass.getClassPath();
+
+ // not show ntEventlog here
+ if (all || (!all && !c.endsWith("NTEventLog")))
+ params.add(name, pName + ";visible");
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description, type info
+ * from logging
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+ NameValuePairs params = getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+ LogPlugin lp = (LogPlugin) mSys.getLogPlugins().get(implName);
+
+ if (lp != null) {
+ impl = getClassByNameAsExtendedPluginInfo(lp.getClassPath());
+ }
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+
+ }
+
+ /**
+ * Add log plug-in
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT used when
+ * configuring signedAudit
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of the log's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addLogPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String logType = null;
+ String id = req.getParameter(Constants.RS_ID);
+
+ // if this "required" parameter is not present,
+ // always log messages to the signed audit log
+ logType = id;
+ if (logType == null) {
+ logType = SIGNED_AUDIT_LOG_TYPE;
+ }
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the log id unique?
+ if (mSys.getLogPlugins().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ILL_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_LOG_CLASS);
+
+ if (classPath == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_NULL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore destStore = null;
+
+ destStore = mConfig.getSubStore("log");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("impl");
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_NO_CLASS"),
+ null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_NO_CLASS"),
+ null, resp);
+ return;
+ }
+
+ // is the class an ILogEventListner?
+ try {
+ if (ILogEventListener.class.isAssignableFrom(newImpl) == false) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ILL_CLASS"),
+ null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_LOG_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add log to registry.
+ LogPlugin plugin = new LogPlugin(id, classPath);
+
+ mSys.getLogPlugins().put(id, plugin);
+
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private boolean isValidID(String id) {
+ if (id == null)
+ return false;
+ for (int i = 0; i < id.length(); i++) {
+ if (!Character.isLetterOrDigit(id.charAt(i)))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add log instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT used when
+ * configuring signedAudit
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of the log's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addLogInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String logType = null;
+ String id = req.getParameter(Constants.RS_ID);
+
+ // if this "required" parameter is not present,
+ // always log messages to the signed audit log
+ logType = id;
+ if (logType == null) {
+ logType = SIGNED_AUDIT_LOG_TYPE;
+ }
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (!isValidID(id)) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR, "Invalid ID '" + id + "'",
+ null, resp);
+ return;
+ }
+
+ if (mSys.getLogInsts().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ILL_INST_ID"),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ String implname = req.getParameter(
+ Constants.PR_LOG_IMPL_NAME);
+
+ if (implname == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ADD_MISSING_PARAMS"),
+ null, resp);
+ return;
+ }
+
+ // check if implementation exists.
+ LogPlugin plugin =
+ (LogPlugin) mSys.getLogPlugins().get(
+ implname);
+
+ if (plugin == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LOG_PLUGIN_NOT_FOUND",implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mSys.getLogDefaultParams(implname);
+
+ IConfigStore destStore =
+ mConfig.getSubStore("log");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("instance");
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String val = req.getParameter(kv.substring(0, index));
+
+ if (val == null) {
+ substore.put(kv.substring(0, index),
+ kv.substring(index + 1));
+ } else {
+ substore.put(kv.substring(0, index),
+ val);
+ }
+ }
+ }
+ substore.put("pluginName", implname);
+
+ // Fix Blackflag Bug #615603: Currently, although expiring log
+ // files is no longer supported, it is still a required parameter
+ // that must be present during the creation and modification of
+ // custom log plugins.
+ substore.put("expirationTime", "0");
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ ILogEventListener logInst = null;
+
+ try {
+ logInst = (ILogEventListener) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the log
+ try {
+ logInst.init(mSys, substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ instancesConfig.removeSubStore(id);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // inited and commited ok. now add log instance to list.
+ mSys.getLogInsts().put(id, logInst);
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_LOG_IMPL_NAME, implname);
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private synchronized void listLogPlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mSys.getLogPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ LogPlugin value = (LogPlugin)
+ mSys.getLogPlugins().get(name);
+ // get Description
+ String c = value.getClassPath();
+ String desc = "unknown";
+
+ try {
+ ILogEventListener lp = (ILogEventListener)
+ Class.forName(c).newInstance();
+
+ desc = lp.getDescription();
+ } catch (Exception exp) {
+ sendResponse(ERROR, exp.toString(), null,
+ resp);
+ return;
+ }
+ params.add(name, value.getClassPath() + "," + desc);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ public String getLogPluginName(ILogEventListener log) {
+ IConfigStore cs = log.getConfigStore();
+
+ try {
+ return cs.getString("pluginName", "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ /**
+ * Delete log instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT used when
+ * configuring signedAudit
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of the log's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void delLogInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String logType = null;
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ // if this "required" parameter is not present,
+ // always log messages to the signed audit log
+ logType = id;
+ if (logType == null) {
+ logType = SIGNED_AUDIT_LOG_TYPE;
+ }
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the log instance exist?
+ if (mSys.getLogInsts().containsKey(id) == false) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogNotFound(CMS.getUserMessage(getLocale(req), "CMS_LOG_INSTANCE_NOT_FOUND",id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ ILogEventListener logInst = (ILogEventListener)
+ mSys.getLogInstance(id);
+
+ mSys.getLogInsts().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore("log");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("instance");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Delete log plug-in
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT used when
+ * configuring signedAudit
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of the log's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void delLogPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String logType = null;
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ // if this "required" parameter is not present,
+ // always log messages to the signed audit log
+ logType = id;
+ if (logType == null) {
+ logType = SIGNED_AUDIT_LOG_TYPE;
+ }
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (mSys.getLogPlugins().containsKey(id) == false) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogPluginNotFound(CMS.getUserMessage(getLocale(req),"CMS_LOG_PLUGIN_NOT_FOUND",id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this log
+ // DON'T remove log if any instance
+ for (Enumeration e = mSys.getLogInsts().keys();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILogEventListener log = mSys.getLogInstance(name);
+
+ if (getLogPluginName(log) == id) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_IN_USE"),
+ null, resp);
+ return;
+ }
+ }
+
+ // then delete this log
+ mSys.getLogPlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore("log");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("impl");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private synchronized void getLogConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mSys.getLogDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_LOG_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getLogInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does log instance exist?
+ if (mSys.getLogInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new ELogNotFound(CMS.getUserMessage(getLocale(req),"CMS_LOG_INSTANCE_NOT_FOUND",id)).toString(),
+ null, resp);
+ return;
+ }
+
+ ILogEventListener logInst = (ILogEventListener)
+ mSys.getLogInstance(id);
+ Vector configParams = logInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_LOG_IMPL_NAME,
+ getLogPluginName(logInst));
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Modify log instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT used when
+ * configuring signedAudit
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE used when log file
+ * name (including any path changes) for any of audit, system, transaction,
+ * or other customized log file change is attempted (authorization should
+ * not allow, but make sure it's written after the attempt)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE used when log
+ * expiration time change is attempted (authorization should not allow, but
+ * make sure it's written after the attempt)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param scope string used to obtain the contents of the log's substore
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modLogInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String logType = null;
+ String origLogPath = req.getParameter(Constants.PR_LOG_FILENAME);
+ String newLogPath = origLogPath;
+ String origExpirationTime = req.getParameter(
+ Constants.PR_LOG_EXPIRED_TIME);
+ String newExpirationTime = origExpirationTime;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+ String type = "";
+
+ // if this "required" parameter is not present,
+ // always log messages to the signed audit log
+ logType = id;
+ if (logType == null) {
+ logType = SIGNED_AUDIT_LOG_TYPE;
+ }
+
+ if (origLogPath != null) {
+ origLogPath = origLogPath.trim();
+ newLogPath = newLogPath.trim();
+ } else {
+ origLogPath = "";
+ newLogPath = "";
+ }
+
+ if (origExpirationTime != null) {
+ origExpirationTime = origExpirationTime.trim();
+ newExpirationTime = newExpirationTime.trim();
+ } else {
+ origExpirationTime = "";
+ newExpirationTime = "";
+ }
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the manager instance exist?
+ if (!mSys.getLogInsts().containsKey((Object) id)) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ILL_INST_ID"),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_LOG_IMPL_NAME);
+
+ if (implname == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),"CMS_LOG_SRVLT_ADD_MISSING_PARAMS"),
+
+ null, resp);
+ return;
+ }
+ // get plugin for implementation
+ LogPlugin plugin =
+ (LogPlugin) mSys.getLogPlugins().get(implname);
+
+ if (plugin == null) {
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogPluginNotFound(CMS.getUserMessage(getLocale(req),"CMS_LOG_PLUGIN_NOT_FOUND",implname)).toString(), null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ ILogEventListener oldinst =
+ (ILogEventListener) mSys.getLogInstance(id);
+ Vector oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.add("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = (String) oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore("log");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("instance");
+
+ // create new substore.
+
+ Vector configParams = mSys.getLogInstanceParams(id);
+
+ //instancesConfig.removeSubStore(id);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put("pluginName", implname);
+
+ // Fix Blackflag Bug #615603: Currently, although expiring log
+ // files is no longer supported, it is still a required parameter
+ // that must be present during the creation and modification of
+ // custom log plugins.
+ substore.put("expirationTime", "0");
+
+ // IMPORTANT: save a copy of the original log file path
+ origLogPath = substore.getString(Constants.PR_LOG_FILENAME);
+ newLogPath = origLogPath;
+
+ if (origLogPath != null) {
+ origLogPath = origLogPath.trim();
+ newLogPath = newLogPath.trim();
+ } else {
+ origLogPath = "";
+ newLogPath = "";
+ }
+
+ // IMPORTANT: save a copy of the original log expiration time
+ origExpirationTime = substore.getString(
+ Constants.PR_LOG_EXPIRED_TIME);
+ newExpirationTime = origExpirationTime;
+
+ if (origExpirationTime != null) {
+ origExpirationTime = origExpirationTime.trim();
+ newExpirationTime = newExpirationTime.trim();
+ } else {
+ origExpirationTime = "";
+ newExpirationTime = "";
+ }
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ AUTHZ_RES_NAME =
+ "certServer.log.configuration";
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String key = kv.substring(0, index);
+ String val = req.getParameter(key);
+
+ if
+ (key.equals("level")) {
+ if (val.equals(ILogger.LL_DEBUG_STRING))
+ val = "0";
+ else if (val.equals(ILogger.LL_INFO_STRING))
+ val = "1";
+ else if (val.equals(ILogger.LL_WARN_STRING))
+ val = "2";
+ else if (val.equals(ILogger.LL_FAILURE_STRING))
+ val = "3";
+ else if (val.equals(ILogger.LL_MISCONF_STRING))
+ val = "4";
+ else if (val.equals(ILogger.LL_CATASTRPHE_STRING))
+ val = "5";
+ else if (val.equals(ILogger.LL_SECURITY_STRING))
+ val = "6";
+
+ }
+
+ if
+ (key.equals("rolloverInterval")) {
+ if (val.equals("Hourly"))
+ val = Integer.toString(60 * 60);
+ else if (val.equals("Daily"))
+ val = Integer.toString(60 * 60 * 24);
+ else if (val.equals("Weekly"))
+ val = Integer.toString(60 * 60 * 24 * 7);
+ else if (val.equals("Monthly"))
+ val = Integer.toString(60 * 60 * 24 * 30);
+ else if (val.equals("Yearly"))
+ val = Integer.toString(60 * 60 * 24 * 365);
+ }
+
+ if
+ (key.equals(Constants.PR_LOG_TYPE)) {
+ type = val;
+ }
+
+ if (val != null) {
+ if (key.equals("fileName")) {
+ String origVal = substore.getString(key);
+
+ val = val.trim();
+ newLogPath = val;
+ if (!val.equals(origVal.trim())) {
+ AUTHZ_RES_NAME =
+ "certServer.log.configuration.fileName";
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ // store a message in the signed audit log
+ // file (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log
+ // file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ }
+ }
+/*
+ if (key.equals("expirationTime")) {
+ String origVal = substore.getString(key);
+
+ val = val.trim();
+ newExpirationTime = val;
+ if (!val.equals(origVal.trim())) {
+ if (id.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ AUTHZ_RES_NAME =
+ "certServer.log.configuration.signedAudit.expirationTime";
+ }
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ // store a message in the signed audit log
+ // file (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log
+ // file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ }
+ }
+*/
+ substore.put(key, val);
+ }
+ }
+ }
+
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ ILogEventListener newMgrInst = null;
+
+ try {
+ newMgrInst = (ILogEventListener)
+ Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ restore(instancesConfig, id, saveParams);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ restore(instancesConfig, id, saveParams);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ new ELogException(CMS.getUserMessage(getLocale(req),"CMS_LOG_LOAD_CLASS_FAIL", className)).toString(),
+ null, resp);
+ return;
+ }
+ // initialize the log
+
+ try {
+ if (false) {
+ newMgrInst.init(mSys, substore);
+ }
+ } catch (EBaseException e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR, e.toString(getLocale(req)), null,
+ resp);
+ return;
+ } catch (Throwable e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ restore(instancesConfig, id, saveParams);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR, e.toString(), null,
+ resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ // REMOVED - we didn't do anything to shut off the old instance
+ // so, it will still be running at this point. You'd have two
+ // log isntances writing to the same file - this would be a big PROBLEM!!!
+
+ //mSys.getLogInsts().put(id, newMgrInst);
+
+ NameValuePairs params = new NameValuePairs();
+
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ sendResponse(RESTART, null, params, resp);
+ return;
+ } catch (EBaseException eAudit1) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // check to see if the log file path parameter was changed
+ newLogPath = auditCheckLogPath(req);
+
+ // check to see if the log expiration time parameter was changed
+ newExpirationTime = auditCheckLogExpirationTime(req);
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newLogPath.equals(origLogPath))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newLogPath);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ // (regardless of logType)
+ if (!(newExpirationTime.equals(origExpirationTime))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ logType,
+ newExpirationTime);
+
+ audit(auditMessage);
+ }
+
+ // store a message in the signed audit log file
+ if (logType.equals(SIGNED_AUDIT_LOG_TYPE)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ }
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // check to see if the log file path parameter was changed
+ // newLogPath = auditCheckLogPath( req );
+ //
+ // // check to see if the log expiration time parameter was changed
+ // newExpirationTime = auditCheckLogExpirationTime( req );
+ //
+ // // store a message in the signed audit log file
+ // // (regardless of logType)
+ // if( !( newLogPath.equals( origLogPath ) ) ) {
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_LOG_PATH_CHANGE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // logType,
+ // newLogPath );
+ //
+ // audit( auditMessage );
+ // }
+ //
+ // // store a message in the signed audit log file
+ // // (regardless of logType)
+ // if( !( newExpirationTime.equals( origExpirationTime ) ) ) {
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_LOG_EXPIRATION_CHANGE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // logType,
+ // newExpirationTime );
+ //
+ // audit( auditMessage );
+ // }
+ //
+ // // store a message in the signed audit log file
+ // if( logType.equals( SIGNED_AUDIT_LOG_TYPE ) ) {
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ // }
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * used for getting the required configuration parameters (with
+ * possible default values) for a particular plugin
+ * implementation name specified in the RS_ID. Actually, there is
+ * no logic in here to set any default value here...there's no
+ * default value for any parameter in this log subsystem
+ * at this point. Later, if we do have one (or some), it can be
+ * added. The interface remains the same.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mSys.getLogDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_LOG_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ if (index == -1) {
+ params.add(kv, "");
+ } else {
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does log instance exist?
+ if (mSys.getLogInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new ELogNotFound(CMS.getUserMessage(getLocale(req),"CMS_LOG_INSTANCE_NOT_FOUND",id)).toString(),
+ null, resp);
+ return;
+ }
+
+ ILogEventListener logInst = (ILogEventListener)
+ mSys.getLogInstance(id);
+ Vector configParams = logInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_LOG_IMPL_NAME,
+ getLogPluginName(logInst));
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ // convenience routine.
+ private static void restore(IConfigStore store,
+ String id, NameValuePairs saveParams) {
+ store.removeSubStore(id);
+ IConfigStore rstore = store.makeSubStore(id);
+
+ Enumeration keys = saveParams.getNames();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String value = saveParams.getValue(key);
+
+ if (value != null)
+ rstore.put(key, value);
+ }
+ }
+
+ /**
+ * Signed Audit Check Log Path
+ *
+ * This method is called to extract the log file path.
+ * <P>
+ *
+ * @param req http servlet request
+ * @return a string containing the log file path
+ */
+ private String auditCheckLogPath(HttpServletRequest req) {
+ // check to see if the log file path parameter was changed
+ String logPath = req.getParameter(Constants.PR_LOG_FILENAME);
+
+ if (logPath == null) {
+ logPath = "";
+ }
+
+ logPath = logPath.trim();
+
+ return logPath;
+ }
+
+ /**
+ * Signed Audit Check Log Expiration Time
+ *
+ * This method is called to extract the log expiration time.
+ * <P>
+ *
+ * @param req http servlet request
+ * @return a string containing the log expiration time
+ */
+ private String auditCheckLogExpirationTime(HttpServletRequest req) {
+ // check to see if the log expiration time parameter was changed
+ String expirationTime = req.getParameter(
+ Constants.PR_LOG_EXPIRED_TIME);
+
+ if (expirationTime == null) {
+ expirationTime = "";
+ }
+
+ expirationTime = expirationTime.trim();
+
+ return expirationTime;
+ }
+
+ private void getGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String value = "false";
+
+ value = mConfig.getString(Constants.PR_DEBUG_LOG_ENABLE, "false");
+ params.add(Constants.PR_DEBUG_LOG_ENABLE, value);
+
+ value = mConfig.getString(Constants.PR_DEBUG_LOG_LEVEL, "0");
+ params.add(Constants.PR_DEBUG_LOG_LEVEL, value);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ Enumeration enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_DEBUG_LOG_ENABLE)) {
+ if (value.equals("true") || value.equals("false")) {
+ mConfig.putString(Constants.PR_DEBUG_LOG_ENABLE, value);
+ } else {
+ CMS.debug("setGeneralConfig: Invalid value for " + Constants.PR_DEBUG_LOG_ENABLE + ": " + value);
+ throw new EBaseException("Invalid value for " + Constants.PR_DEBUG_LOG_ENABLE);
+ }
+ } else if (key.equals(Constants.PR_DEBUG_LOG_LEVEL)) {
+ try {
+ int number = Integer.parseInt(value);
+ mConfig.putString(Constants.PR_DEBUG_LOG_LEVEL, value);
+ } catch (NumberFormatException e) {
+ CMS.debug("setGeneralConfig: Invalid value for " + Constants.PR_DEBUG_LOG_LEVEL + ": " + value);
+ throw new EBaseException("Invalid value for " + Constants.PR_DEBUG_LOG_LEVEL);
+ }
+ }
+ }
+
+ mConfig.commit(true);
+
+ if (restart)
+ sendResponse(RESTART, null, null, resp);
+ else
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java
new file mode 100644
index 000000000..aafe4f4bc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java
@@ -0,0 +1,560 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class representings an administration servlet for Certificate
+ * Authority. This servlet is responsible to serve OCSP
+ * administrative operations such as configuration parameter
+ * updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSPAdminServlet extends AdminServlet {
+
+ protected static final String PROP_ENABLED = "enabled";
+
+ private final static String INFO = "OCSPAdminServlet";
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE_3";
+
+ private IOCSPAuthority mOCSP = null;
+
+ public OCSPAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mOCSP = (IOCSPAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_OCSP);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. Each request is authenticated to
+ * the authenticate manager.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ //get all operational flags
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ //check operational flags
+ if ((op == null) || (scope == null)) {
+ sendResponse(1, "Invalid Protocol", null, resp);
+ return;
+ }
+
+ super.authenticate(req);
+
+ try {
+ AUTHZ_RES_NAME = "certServer.ocsp.configuration";
+ if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ try {
+ getExtendedPluginInfo(req, resp);
+ return;
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ }
+ }
+
+ if (scope.equals(ScopeDef.SC_OCSPSTORE_DEFAULT)) {
+ if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ setDefaultStore(req, resp);
+ return;
+ }
+ }
+
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ getGeneralConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_OCSPSTORES_RULES)) {
+ getOCSPStoresConfig(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ setGeneralConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_OCSPSTORES_RULES)) {
+ setOCSPStoresConfig(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_OCSPSTORES_RULES)) {
+ listOCSPStoresConfig(req, resp);
+ return;
+ }
+ }
+ } catch (Exception e) {
+ sendResponse(1, e.toString(), null, resp);
+ return;
+ }
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description,
+ * type info from CRL extensions
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+
+ NameValuePairs params =
+ getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+
+ impl = getClassByNameAsExtendedPluginInfo(implName);
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+
+ }
+
+ /**
+ * Set default OCSP store
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE used when
+ * configuring OCSP profile (everything under Online Certificate Status
+ * Manager)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setDefaultStore(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ mOCSP.getConfigStore().putString(IOCSPAuthority.PROP_DEF_STORE_ID,
+ id);
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void getOCSPStoresConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ IOCSPStore store = mOCSP.getOCSPStore(id);
+ NameValuePairs params = store.getConfigParameters();
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Set OCSP store configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE used when
+ * configuring OCSP profile (everything under Online Certificate Status
+ * Manager)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setOCSPStoresConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ IOCSPStore store = mOCSP.getOCSPStore(id);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_CRLEXT_IMPL_NAME))
+ continue;
+ if (name.equals("RULENAME"))
+ continue;
+ String value = req.getParameter(name);
+
+ params.add(name, value);
+ }
+ store.setConfigParameters(params);
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void listOCSPStoresConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ IConfigStore config = mOCSP.getConfigStore();
+ String defStore = config.getString(mOCSP.PROP_DEF_STORE_ID);
+ IConfigStore SubStore = config.getSubStore(mOCSP.PROP_STORE);
+ Enumeration enumStores = SubStore.getSubStoreNames();
+
+ while (enumStores.hasMoreElements()) {
+ String storeName = (String) enumStores.nextElement();
+ boolean storeEnabled = false;
+
+ if (storeName.equals(defStore)) {
+ storeEnabled = true;
+ }
+ params.add(storeName, storeName + ";visible;" + ((storeEnabled) ? "enabled" : "disabled"));
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ getSigningAlgConfig(params);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getSigningAlgConfig(NameValuePairs params) {
+ params.add(Constants.PR_DEFAULT_ALGORITHM,
+ mOCSP.getDefaultAlgorithm());
+ String[] algorithms = mOCSP.getOCSPSigningAlgorithms();
+ StringBuffer algorStr = new StringBuffer();
+
+ for (int i = 0; i < algorithms.length; i++) {
+ if (i == 0)
+ algorStr.append(algorithms[i]);
+ else
+ algorStr.append(":");
+ algorStr.append(algorithms[i]);
+ }
+ params.add(Constants.PR_ALL_ALGORITHMS, algorStr.toString());
+ }
+
+ /**
+ * Set general OCSP configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE used when
+ * configuring OCSP profile (everything under Online Certificate Status
+ * Manager)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ Enumeration enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.PR_DEFAULT_ALGORITHM)) {
+ mOCSP.setDefaultAlgorithm(value);
+ }
+ }
+
+ commit(true);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_OCSP_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "CAAdminServlet: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java
new file mode 100644
index 000000000..91309e08c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java
@@ -0,0 +1,1243 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+
+
+/**
+ * This class is an administration servlet for policy management.
+ *
+ * Each service (CA, KRA, RA) should be responsible
+ * for registering an instance of this with the remote
+ * administration subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PolicyAdminServlet extends AdminServlet {
+ public final static String PROP_AUTHORITY = "authority";
+
+ private final static String INFO = "PolicyAdminServlet";
+ private final static String PW_PASSWORD_CACHE_ADD =
+ "PASSWORD_CACHE_ADD";
+
+ public final static String PROP_PREDICATE = "predicate";
+ private IPolicyProcessor mProcessor = null;
+ private IAuthority mAuthority = null;
+
+ // These will be moved to PolicyResources
+ public static String INVALID_POLICY_SCOPE = "Invalid policy administration scope";
+ public static String INVALID_POLICY_IMPL_OP = "Invalid operation for policy implementation management";
+ public static String NYI = "Not Yet Implemented";
+ public static String INVALID_POLICY_IMPL_CONFIG = "Invalid policy implementation configuration";
+ public static String INVALID_POLICY_INSTANCE_CONFIG = "Invalid policy instance configuration";
+ public static String MISSING_POLICY_IMPL_ID = "Missing policy impl id in request";
+ public static String MISSING_POLICY_IMPL_CLASS = "Missing policy impl class in request";
+ public static String INVALID_POLICY_IMPL_ID = "Invalid policy impl id in request";
+ public static String MISSING_POLICY_INST_ID = "Missing policy impl id in request";
+ public static String INVALID_POLICY_INST_ID = "Invalid policy impl id in request";
+ public static String COMMA = ",";
+ public static String MISSING_POLICY_ORDERING = "Missing policy ordering";
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY =
+ "LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY_3";
+
+ /**
+ * Constructs administration servlet.
+ */
+ public PolicyAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+ String policyStatus = null;
+
+ CMS.debug( "PolicyAdminServlet: In Policy Admin Servlet init!" );
+
+ // CMS 6.1 began utilizing the "Certificate Profiles" framework
+ // instead of the legacy "Certificate Policies" framework.
+ //
+ // Beginning with CS 8.1, to meet the Common Criteria evaluation
+ // performed on this version of the product, it was determined
+ // that this legacy "Certificate Policies" framework would be
+ // deprecated and disabled by default (see Bugzilla Bug #472597).
+ //
+ // NOTE: The "Certificate Policies" framework ONLY applied to
+ // to CA, KRA, and legacy RA (pre-CMS 7.0) subsystems.
+ //
+ // Further, the "PolicyAdminServlet.java" servlet is ONLY used
+ // by the CA Console for the following:
+ //
+ // SERVLET-NAME URL-PATTERN
+ // ====================================================
+ // capolicy ca/capolicy
+ //
+ // Finally, the "PolicyAdminServlet.java" servlet is ONLY used
+ // by the KRA Console for the following:
+ //
+ // SERVLET-NAME URL-PATTERN
+ // ====================================================
+ // krapolicy kra/krapolicy
+ //
+ if (authority != null)
+ mAuthority = (IAuthority) CMS.getSubsystem(authority);
+ if (mAuthority != null)
+ if (mAuthority instanceof ICertificateAuthority) {
+ mProcessor = ((ICertificateAuthority) mAuthority).getPolicyProcessor();
+ try {
+ policyStatus = ICertificateAuthority.ID
+ + "." + "Policy"
+ + "." + IPolicyProcessor.PROP_ENABLE;
+ if( mConfig.getBoolean( policyStatus, true ) == true ) {
+ // NOTE: If "ca.Policy.enable=<boolean>" is missing,
+ // then the referenced instance existed prior
+ // to this name=value pair existing in its
+ // 'CS.cfg' file, and thus we err on the
+ // side that the user may still need to
+ // use the policy framework.
+ CMS.debug( "PolicyAdminServlet::init "
+ + "Certificate Policy Framework (deprecated) "
+ + "is ENABLED" );
+ } else {
+ // CS 8.1 Default: ca.Policy.enable=false
+ CMS.debug( "PolicyAdminServlet::init "
+ + "Certificate Policy Framework (deprecated) "
+ + "is DISABLED" );
+ return;
+ }
+ } catch( EBaseException e ) {
+ throw new ServletException( authority
+ + " does not have a "
+ + "master policy switch called '"
+ + policyStatus + "'" );
+ }
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ // this refers to the legacy RA (pre-CMS 7.0)
+ mProcessor = ((IRegistrationAuthority) mAuthority).getPolicyProcessor();
+ } else if (mAuthority instanceof IKeyRecoveryAuthority) {
+ mProcessor = ((IKeyRecoveryAuthority) mAuthority).getPolicyProcessor();
+ try {
+ policyStatus = IKeyRecoveryAuthority.ID
+ + "." + "Policy"
+ + "." + IPolicyProcessor.PROP_ENABLE;
+ if( mConfig.getBoolean( policyStatus, true ) == true ) {
+ // NOTE: If "kra.Policy.enable=<boolean>" is missing,
+ // then the referenced instance existed prior
+ // to this name=value pair existing in its
+ // 'CS.cfg' file, and thus we err on the
+ // side that the user may still need to
+ // use the policy framework.
+ CMS.debug( "PolicyAdminServlet::init "
+ + "Certificate Policy Framework (deprecated) "
+ + "is ENABLED" );
+ } else {
+ // CS 8.1 Default: kra.Policy.enable=false
+ CMS.debug( "PolicyAdminServlet::init "
+ + "Certificate Policy Framework (deprecated) "
+ + "is DISABLED" );
+ return;
+ }
+ } catch( EBaseException e ) {
+ throw new ServletException( authority
+ + " does not have a "
+ + "master policy switch called '"
+ + policyStatus + "'" );
+ }
+ } else
+ throw new ServletException(authority + " does not have policy processor!");
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description, type info
+ * from policy, authentication,
+ * need to add: listener, mapper and publishing plugins
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ if (!readAuthorize(req, resp))
+ return;
+ String id = req.getParameter(Constants.RS_ID);
+ NameValuePairs params = null;
+
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName1 = id.substring(colon + 1);
+ String implName = implName1;
+ String instName = null;
+
+ colon = implName1.indexOf(':');
+ if (colon > -1) {
+ implName = implName1.substring(0, colon);
+ instName = implName1.substring(colon + 1);
+ params = getExtendedPluginInfo(getLocale(req), implType, implName, instName);
+ } else {
+ params = getExtendedPluginInfo(getLocale(req), implType, implName);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+ IPolicyRule policy = mProcessor.getPolicyImpl(implName);
+
+ impl = policy;
+
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+ }
+
+ public NameValuePairs getExtendedPluginInfo(Locale locale, String pluginType,
+ String implName,
+ String instName) {
+ IExtendedPluginInfo ext_info = null;
+
+ Object impl = null;
+
+ IPolicyRule policy = mProcessor.getPolicyInstance(instName);
+
+ impl = policy;
+ if (impl == null) {
+ impl = mProcessor.getPolicyImpl(implName);
+ }
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+
+ }
+
+ if (nvps != null) {
+ addDefaultParams(impl, nvps);
+ }
+
+ return nvps;
+ }
+
+ private void addDefaultParams(Object ext_info, NameValuePairs nvps) {
+
+ /* make sure policy rules have 'enable' and 'predicate' */
+
+ if (ext_info instanceof IPolicyRule) {
+ if (nvps.getPair(IPolicyRule.PROP_ENABLE) == null) {
+ nvps.add(IPolicyRule.PROP_ENABLE, "boolean;Enable this policy rule");
+ }
+ if (nvps.getPair(PROP_PREDICATE) == null) {
+ nvps.add(PROP_PREDICATE, "string;Rules describing when this policy should run.");
+ }
+ }
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ super.authenticate(req);
+
+ AUTHZ_RES_NAME = "certServer.policy.configuration";
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (scope.equals(ScopeDef.SC_POLICY_RULES))
+ processPolicyRuleMgmt(req, resp);
+ else if (scope.equals(ScopeDef.SC_POLICY_IMPLS))
+ processPolicyImplMgmt(req, resp);
+ else if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ try {
+ getExtendedPluginInfo(req, resp);
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ } else
+ sendResponse(ERROR, INVALID_POLICY_SCOPE, null, resp);
+ }
+
+ private boolean readAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean modifyAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Process Policy Implementation Management.
+ */
+ public void processPolicyImplMgmt(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ if (!readAuthorize(req, resp))
+ return;
+ listPolicyImpls(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deletePolicyImpl(req, resp);
+ } else if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getPolicyImplConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addPolicyImpl(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_IMPL_OP,
+ null, resp);
+ }
+
+ public void processPolicyRuleMgmt(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ if (!readAuthorize(req, resp))
+ return;
+ listPolicyInstances(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deletePolicyInstance(req, resp);
+ } else if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getPolicyInstanceConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addPolicyInstance(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id.equalsIgnoreCase(Constants.RS_ID_ORDER))
+ changePolicyInstanceOrdering(req, resp);
+ else
+ modifyPolicyInstance(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_IMPL_OP,
+ null, resp);
+ }
+
+ public void listPolicyImpls(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ Enumeration policyImplNames = mProcessor.getPolicyImplsInfo();
+ Enumeration policyImpls = mProcessor.getPolicyImpls();
+
+ if (policyImplNames == null ||
+ policyImpls == null) {
+ sendResponse(ERROR, INVALID_POLICY_IMPL_CONFIG, null, resp);
+ return;
+ }
+
+ // Assemble a name value pair;
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (policyImplNames.hasMoreElements() &&
+ policyImpls.hasMoreElements()) {
+ String id = (String) policyImplNames.nextElement();
+ IPolicyRule impl = (IPolicyRule)
+ policyImpls.nextElement();
+ String className =
+ impl.getClass().getName();
+ String desc = impl.getDescription();
+
+ nvp.add(id, className + "," + desc);
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void listPolicyInstances(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ Enumeration instancesInfo = mProcessor.getPolicyInstancesInfo();
+
+ if (instancesInfo == null) {
+ sendResponse(ERROR, INVALID_POLICY_INSTANCE_CONFIG, null, resp);
+ return;
+ }
+
+ // Assemble name value pairs
+ NameValuePairs nvp = new NameValuePairs();
+ String instName, rest;
+
+ while (instancesInfo.hasMoreElements()) {
+ String info = (String) instancesInfo.nextElement();
+ int i = info.indexOf(";");
+
+ nvp.add(info.substring(0, i), info.substring(i + 1));
+
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ /**
+ * Delete policy implementation
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deletePolicyImpl(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID).trim();
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ try {
+ mProcessor.deletePolicyImpl(id);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ //e.printStackTrace();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ public void getPolicyImplConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ Vector v = mProcessor.getPolicyImplConfig(id);
+
+ if (v == null) {
+ sendResponse(ERROR, INVALID_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ for (Enumeration e = v.elements(); e.hasMoreElements();) {
+ String nv = (String) e.nextElement();
+ int index = nv.indexOf("=");
+
+ nvp.add(nv.substring(0, index), nv.substring(index + 1));
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ /**
+ * Add policy implementation
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addPolicyImpl(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_POLICY_CLASS);
+
+ if (classPath == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_IMPL_CLASS, null, resp);
+ return;
+ }
+ try {
+ mProcessor.addPolicyImpl(id, classPath);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Delete policy instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deletePolicyInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID).trim();
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ try {
+ mProcessor.deletePolicyInstance(id);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ //e.printStackTrace();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ public void getPolicyInstanceConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get the policy rule id.
+ String id = req.getParameter(Constants.RS_ID).trim();
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ Vector v = mProcessor.getPolicyInstanceConfig(id);
+
+ if (v == null) {
+ sendResponse(ERROR, INVALID_POLICY_INST_ID, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ for (Enumeration e = v.elements(); e.hasMoreElements();) {
+ String nv = (String) e.nextElement();
+ int index = nv.indexOf("=");
+ String name = nv.substring(0, index);
+ String value = nv.substring(index + 1);
+
+ if (value == null) {
+ value = "";
+ }
+
+ nvp.add(name, value);
+
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void
+ putUserPWPair(String combo) {
+ int semicolon;
+
+ semicolon = combo.indexOf(";");
+ String user = combo.substring(0, semicolon);
+ String pw = combo.substring(semicolon + 1);
+
+ CMS.putPasswordCache(user, pw);
+ }
+
+ /**
+ * Add policy instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addPolicyInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ // Get the default config params for the implementation.
+ String implName = req.getParameter(IPolicyRule.PROP_IMPLNAME);
+
+ if (implName == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ // We need to fetch parameters: enable, predicate and implname
+ // always, and any additional parameters as required by the
+ // implementation.
+ Hashtable ht = new Hashtable();
+ String val = req.getParameter(IPolicyRule.PROP_ENABLE).trim();
+
+ if (val == null)
+ val = "true";
+ ht.put(IPolicyRule.PROP_ENABLE, val);
+
+ val = req.getParameter(IPolicyRule.PROP_PREDICATE);
+ if (val != null)
+ ht.put(IPolicyRule.PROP_PREDICATE, val);
+ ht.put(IPolicyRule.PROP_IMPLNAME, implName);
+
+ Vector v = mProcessor.getPolicyImplConfig(implName);
+
+ if (v == null) {
+ // Invalid impl id
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, INVALID_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+ for (Enumeration e = v.elements(); e.hasMoreElements();) {
+ String nv = (String) e.nextElement();
+ int index = nv.indexOf("=");
+ String key = nv.substring(0, index);
+
+ val = req.getParameter(key).trim();
+ if (val != null)
+ ht.put(key, val);
+ }
+
+ String pwadd = req.getParameter(PW_PASSWORD_CACHE_ADD);
+
+ if (pwadd != null) {
+ putUserPWPair(pwadd);
+ }
+
+ try {
+ mProcessor.addPolicyInstance(id, ht);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Change ordering of policy instances
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void changePolicyInstanceOrdering(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String policyOrder =
+ req.getParameter(Constants.PR_POLICY_ORDER);
+
+ if (policyOrder == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_ORDERING, null, resp);
+ return;
+ }
+ try {
+ mProcessor.changePolicyInstanceOrdering(policyOrder);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify policy instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY used when
+ * configuring cert policy constraints and extensions
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyPolicyInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ // Get the default config params for the implementation.
+ String implName = req.getParameter(IPolicyRule.PROP_IMPLNAME).trim();
+
+ if (implName == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ // We need to fetch parameters: enable, predicate and implname
+ // always, and any additional parameters as required by the
+ // implementation.
+ Hashtable ht = new Hashtable();
+ String val = req.getParameter(IPolicyRule.PROP_ENABLE).trim();
+
+ if (val == null)
+ val = "true";
+ ht.put(IPolicyRule.PROP_ENABLE, val);
+
+ val = req.getParameter(IPolicyRule.PROP_PREDICATE);
+ if (val != null)
+ ht.put(IPolicyRule.PROP_PREDICATE, val);
+ ht.put(IPolicyRule.PROP_IMPLNAME, implName);
+ Vector v = mProcessor.getPolicyImplConfig(implName);
+
+ if (v == null) {
+ // Invalid impl id
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, INVALID_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+ // XXX
+ for (Enumeration n = req.getParameterNames(); n.hasMoreElements();) {
+ String p = (String) n.nextElement();
+ String l = (String) req.getParameter(p);
+
+ if (l != null)
+ ht.put(p, l);
+ }
+
+ /*
+ for(Enumeration e = v.elements(); e.hasMoreElements(); )
+ {
+ String nv = (String)e.nextElement();
+ int index = nv.indexOf("=");
+ String key = nv.substring(0, index);
+ val = req.getParameter(key);
+ if (val != null)
+ ht.put(key, val);
+ }
+ */
+
+ try {
+ mProcessor.modifyPolicyInstance(id, ht);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, e.toString(), null, resp);
+ }
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_POLICY,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java
new file mode 100644
index 000000000..8306bc77e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java
@@ -0,0 +1,2683 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.registry.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+
+
+/**
+ * This class is an administration servlet for policy management.
+ *
+ * Each service (CA, KRA, RA) should be responsible
+ * for registering an instance of this with the remote
+ * administration subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileAdminServlet extends AdminServlet {
+ public final static String PROP_AUTHORITY = "authority";
+
+ private final static String INFO = "ProfileAdminServlet";
+ private final static String PW_PASSWORD_CACHE_ADD =
+ "PASSWORD_CACHE_ADD";
+
+ public final static String PROP_PREDICATE = "predicate";
+ private IAuthority mAuthority = null;
+ private IPluginRegistry mRegistry = null;
+ private IProfileSubsystem mProfileSub = null;
+
+ // These will be moved to PolicyResources
+ public static String INVALID_POLICY_SCOPE = "Invalid policy administration scope";
+ public static String INVALID_POLICY_IMPL_OP = "Invalid operation for policy implementation management";
+ public static String NYI = "Not Yet Implemented";
+ public static String INVALID_POLICY_IMPL_CONFIG = "Invalid policy implementation configuration";
+ public static String INVALID_POLICY_INSTANCE_CONFIG = "Invalid policy instance configuration";
+ public static String MISSING_POLICY_IMPL_ID = "Missing policy impl id in request";
+ public static String MISSING_POLICY_IMPL_CLASS = "Missing policy impl class in request";
+ public static String INVALID_POLICY_IMPL_ID = "Invalid policy impl id in request";
+ public static String MISSING_POLICY_INST_ID = "Missing policy id in request";
+ public static String POLICY_INST_ID_ALREADY_USED = "policy id already used";
+ public static String INVALID_POLICY_INST_ID = "Invalid policy id in request";
+ public static String COMMA = ",";
+ public static String MISSING_POLICY_ORDERING = "Missing policy ordering";
+ public static String BAD_CONFIGURATION_VAL = "Invalid configuration value.";
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE_3";
+
+ /**
+ * Constructs administration servlet.
+ */
+ public ProfileAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority) CMS.getSubsystem(authority);
+ mRegistry = (IPluginRegistry) CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ mProfileSub = (IProfileSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_PROFILE);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ private void addDefaultParams(Object ext_info, NameValuePairs nvps) {
+
+ /* make sure policy rules have 'enable' and 'predicate' */
+
+ if (ext_info instanceof IPolicyRule) {
+ if (nvps.getPair(IPolicyRule.PROP_ENABLE) == null) {
+ nvps.add(IPolicyRule.PROP_ENABLE, "boolean;Enable this policy rule");
+ }
+ if (nvps.getPair(PROP_PREDICATE) == null) {
+ nvps.add(PROP_PREDICATE, "string;Rules describing when this policy should run.");
+ }
+ }
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ super.authenticate(req);
+
+ AUTHZ_RES_NAME = "certServer.profile.configuration";
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ CMS.debug("ProfileAdminServlet: service scope: " + scope);
+ if (scope.equals(ScopeDef.SC_PROFILE_RULES)) {
+ processProfileRuleMgmt(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_POLICIES)) {
+ processProfilePolicy(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_DEFAULT_POLICY)) {
+ processPolicyDefaultConfig(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_CONSTRAINT_POLICY)) {
+ processPolicyConstraintConfig(req, resp);
+ } else if (scope.equals(ScopeDef.SC_POLICY_IMPLS)) {
+ processPolicyImplMgmt(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_INPUT)) {
+ processProfileInput(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_OUTPUT)) {
+ processProfileOutput(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_INPUT_CONFIG)) {
+ processProfileInputConfig(req, resp);
+ } else if (scope.equals(ScopeDef.SC_PROFILE_OUTPUT_CONFIG)) {
+ processProfileOutputConfig(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_SCOPE, null, resp);
+ }
+
+ private boolean readAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean modifyAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ public void processProfilePolicy(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getProfilePolicy(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addProfilePolicy(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deleteProfilePolicy(req, resp);
+ }
+ }
+
+ public void processProfileInput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = super.getParameter(req, Constants.OP_SCOPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getProfileInput(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addProfileInput(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deleteProfileInput(req, resp);
+ }
+ }
+
+ public void processProfileOutput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = super.getParameter(req, Constants.OP_SCOPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getProfileOutput(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addProfileOutput(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deleteProfileOutput(req, resp);
+ }
+ }
+
+ public void processProfileInputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getInputConfig(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ modifyInputConfig(req, resp);
+ }
+ }
+
+ public void processProfileOutputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getOutputConfig(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ modifyOutputConfig(req, resp);
+ }
+ }
+
+ public void processPolicyDefaultConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getPolicyDefaultConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addPolicyDefaultConfig(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ modifyPolicyDefaultConfig(req, resp);
+ }
+ }
+
+ public void processPolicyConstraintConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ CMS.debug("ProfileAdminServlet: processPolicyConstraintConfig op " + op);
+ if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getPolicyConstraintConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addPolicyConstraintConfig(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ modifyPolicyConstraintConfig(req, resp);
+ }
+ }
+
+ /**
+ * Process Policy Implementation Management.
+ */
+ public void processPolicyImplMgmt(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ if (!readAuthorize(req, resp))
+ return;
+ listProfileImpls(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_IMPL_OP,
+ null, resp);
+ }
+
+ public void processProfileRuleMgmt(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ if (!readAuthorize(req, resp))
+ return;
+ listProfileInstances(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deleteProfileInstance(req, resp);
+ } else if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getProfileInstanceConfig(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addProfileInstance(req, resp);
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ modifyProfileInstance(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_IMPL_OP,
+ null, resp);
+ }
+
+ /**
+ * Lists all registered profile impementations
+ */
+ public void listProfileImpls(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ Enumeration impls = mRegistry.getIds("profile");
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (impls.hasMoreElements()) {
+ String id = (String) impls.nextElement();
+ IPluginInfo info = mRegistry.getPluginInfo("profile", id);
+
+ nvp.add(id, info.getClassName() + "," +
+ info.getDescription(getLocale(req)));
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ /**
+ * Add policy profile
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addProfilePolicy(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ CMS.debug("ProfileAdminServlet: in addProfilePolicy");
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+ String defImpl = st.nextToken();
+ String conImpl = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ if (mProfileSub.isProfileEnable(profileId)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),
+ "CMS_PROFILE_CREATE_POLICY_FAILED",
+ "Profile is currently enabled"),
+ null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+
+ IProfilePolicy policy = null;
+
+ try {
+ if (!isValidId(setId)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),
+ "CMS_PROFILE_CREATE_POLICY_FAILED",
+ "Invalid set id " + setId),
+ null, resp);
+ return;
+ }
+ if (!isValidId(pId)) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req),
+ "CMS_PROFILE_CREATE_POLICY_FAILED",
+ "Invalid policy id " + pId),
+ null, resp);
+ return;
+ }
+ policy = profile.createProfilePolicy(setId, pId,
+ defImpl, conImpl);
+ } catch (EBaseException e1) {
+ // error
+ CMS.debug("ProfileAdminServlet: addProfilePolicy " +
+ e1.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_PROFILE_CREATE_POLICY_FAILED",
+ e1.toString()),
+ null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Add profile input
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addProfileInput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String inputId = st.nextToken();
+ String inputImpl = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ IProfileInput input = null;
+ Enumeration names = req.getParameterNames();
+ NameValuePairs nvps = new NameValuePairs();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ nvps.add(name, req.getParameter(name));
+ }
+
+ try {
+ input = profile.createProfileInput(inputId, inputImpl, nvps);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_PROFILE_CREATE_INPUT_FAILED",
+ e1.toString()),
+ null, resp);
+
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Add profile output
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addProfileOutput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String outputId = st.nextToken();
+ String outputImpl = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ IProfileOutput output = null;
+ Enumeration names = req.getParameterNames();
+ NameValuePairs nvps = new NameValuePairs();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ nvps.add(name, req.getParameter(name));
+ }
+
+ try {
+ output = profile.createProfileOutput(outputId, outputImpl,
+ nvps);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_PROFILE_CREATE_OUTPUT_FAILED",
+ e1.toString()),
+ null, resp);
+
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Delete policy profile
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deleteProfilePolicy(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String profileId = "";
+ String policyId = "";
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ profileId = req.getParameter(name);
+ if (name.equals("POLICYID"))
+ policyId = req.getParameter(name);
+ }
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+
+ try {
+ profile.deleteProfilePolicy(setId, pId);
+ } catch (EBaseException e1) {
+ CMS.debug("ProfileAdminServlet: " + e1.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Delete profile input
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deleteProfileInput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String profileId = "";
+ String inputId = "";
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ profileId = req.getParameter(name);
+ if (name.equals("INPUTID"))
+ inputId = req.getParameter(name);
+ }
+ CMS.debug("ProfileAdminServlet: deleteProfileInput profileId -> " + profileId);
+ CMS.debug("ProfileAdminServlet: deleteProfileInput inputId -> " + inputId);
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ CMS.debug("deleteProfileInput profile -> " + profile);
+ try {
+ profile.deleteProfileInput(inputId);
+ } catch (EBaseException e1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Delete profile output
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deleteProfileOutput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String profileId = "";
+ String outputId = "";
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ profileId = req.getParameter(name);
+ if (name.equals("OUTPUTID"))
+ outputId = req.getParameter(name);
+ }
+ CMS.debug("ProfileAdminServlet: deleteProfileOutput profileId -> " + profileId);
+ CMS.debug("ProfileAdminServlet: deleteProfileOutput outputId -> " + outputId);
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ CMS.debug("ProfileAdminServlet: deleteProfileOutput profile -> " + profile);
+ try {
+ profile.deleteProfileOutput(outputId);
+ } catch (EBaseException e1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Add default policy profile configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addPolicyDefaultConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+
+ IProfilePolicy policy = profile.getProfilePolicy(setId, pId);
+ IPolicyDefault def = policy.getDefault();
+ IConfigStore defConfig = def.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ try {
+ def.setConfig(name,req.getParameter(name));
+
+ } catch (EPropertyException e) {
+
+ CMS.debug("ProfileAdminServlet: modifyPolicyDefConfig setConfig exception.");
+ try {
+ profile.deleteProfilePolicy(setId, pId);
+ } catch (Exception e11) {}
+ sendResponse(ERROR,BAD_CONFIGURATION_VAL,null,resp);
+ return;
+ }
+ // defConfig.putString("params." + name, req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Add policy constraints profile configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addPolicyConstraintConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+
+ IProfilePolicy policy = profile.getProfilePolicy(setId, pId);
+ IPolicyConstraint con = policy.getConstraint();
+ IConfigStore conConfig = con.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+
+ try {
+ con.setConfig(name,req.getParameter(name));
+
+ } catch (EPropertyException e) {
+
+ CMS.debug("ProfileAdminServlet: addPolicyConstraintsConfig setConfig exception.");
+ try {
+ profile.deleteProfilePolicy(setId, pId);
+ } catch (Exception e11) {}
+ sendResponse(ERROR,BAD_CONFIGURATION_VAL,null,resp);
+ return;
+ }
+ // conConfig.putString("params." + name, req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify default policy profile configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyPolicyDefaultConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+ IProfilePolicy policy = profile.getProfilePolicy(setId, pId);
+ IPolicyDefault def = policy.getDefault();
+ IConfigStore defConfig = def.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ try {
+ def.setConfig(name,req.getParameter(name));
+
+ } catch (EPropertyException e) {
+
+ CMS.debug("ProfileAdminServlet: modifyPolicyDefConfig setConfig exception.");
+ sendResponse(ERROR,BAD_CONFIGURATION_VAL,null,resp);
+ return;
+ }
+ // defConfig.putString("params." + name, req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify profile input configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyInputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String inputId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ IProfileInput input = profile.getProfileInput(inputId);
+ IConfigStore inputConfig = input.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ inputConfig.putString("params." + name, req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify profile output configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyOutputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String outputId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ IProfileOutput output = profile.getProfileOutput(outputId);
+ IConfigStore outputConfig = output.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ outputConfig.putString("params." + name,
+ req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify policy constraints profile configuration
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyPolicyConstraintConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+ IProfilePolicy policy = profile.getProfilePolicy(setId, pId);
+ IPolicyConstraint con = policy.getConstraint();
+ IConfigStore conConfig = con.getConfigStore();
+
+ Enumeration names = req.getParameterNames();
+
+ CMS.debug("ProfileAdminServlet: modifyPolicyConstraintConfig policy " + policy + " con " + con);
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+
+ // CMS.debug("ProfileAdminServlet: modifyPolicyConstraintConfig name" + name + " val " + req.getParameter(name));
+ try {
+ con.setConfig(name,req.getParameter(name));
+
+ } catch (EPropertyException e) {
+
+ CMS.debug("ProfileAdminServlet: modifyPolicyConstraintsConfig setConfig exception.");
+ sendResponse(ERROR,BAD_CONFIGURATION_VAL,null,resp);
+ return;
+ }
+ //conConfig.putString("params." + name, req.getParameter(name));
+ }
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ public void getPolicyDefaultConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getPolicyDefaultConfig() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ IProfilePolicy policy = null;
+ IPolicyDefault rule = null;
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+
+ policy = profile.getProfilePolicy(setId, pId);
+ rule = policy.getDefault();
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration names = rule.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ IDescriptor desc = rule.getConfigDescriptor(getLocale(req), name);
+
+ if (desc == null) {
+ nvp.add(name, ";" + ";" + rule.getConfig(name));
+ } else {
+ nvp.add(name, desc.getSyntax() + ";" + ";" + getNonNull(desc.getConstraint()) + ";" + desc.getDescription(getLocale(req)) + ";" + rule.getConfig(name));
+ }
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getPolicyConstraintConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+ String constraintsList = req.getParameter(Constants.PR_CONSTRAINTS_LIST);
+
+ // this one gets called when one of the elements in the default list get
+ // selected, then it returns the list of supported constraintsPolicy
+ if (constraintsList != null) {
+
+ }
+
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getPolicyConstraintConfig() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ StringTokenizer ss = new StringTokenizer(policyId, ":");
+ String setId = ss.nextToken();
+ String pId = ss.nextToken();
+ IProfilePolicy policy = profile.getProfilePolicy(setId, pId);
+ IPolicyConstraint rule = policy.getConstraint();
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration names = rule.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ IDescriptor desc = rule.getConfigDescriptor(getLocale(req), name);
+
+ if (desc == null) {
+ nvp.add(name, ";" + rule.getConfig(name));
+ } else {
+ nvp.add(name, desc.getSyntax() + ";" + getNonNull(desc.getConstraint()) + ";" + desc.getDescription(getLocale(req)) + ";" + rule.getConfig(name));
+ }
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getProfilePolicy(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ // only allow profile retrival if it is disabled
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(id);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getProfilePolicy() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration setIds = profile.getProfilePolicySetIds();
+
+ if (!setIds.hasMoreElements()) {
+ // no set id; this is a brand new profile
+ sendResponse(SUCCESS, null, nvp, resp);
+ return;
+ }
+ while (setIds.hasMoreElements()) {
+ String setId = (String) setIds.nextElement();
+ Enumeration policies = profile.getProfilePolicies(setId);
+
+ while (policies.hasMoreElements()) {
+ IProfilePolicy policy = (IProfilePolicy) policies.nextElement();
+ IPolicyDefault def = policy.getDefault();
+ IConfigStore defConfig = def.getConfigStore();
+ IPolicyConstraint con = policy.getConstraint();
+ IConfigStore conConfig = con.getConfigStore();
+
+ nvp.add(setId + ":" + policy.getId(),
+ def.getName(getLocale(req)) + ";" +
+ con.getName(getLocale(req)));
+ }
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getProfileOutput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(id);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getProfileOutput() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration outputs = profile.getProfileOutputIds();
+
+ while (outputs.hasMoreElements()) {
+ String outputId = (String) outputs.nextElement();
+ IProfileOutput output = profile.getProfileOutput(outputId);
+
+ nvp.add(outputId, output.getName(getLocale(req)));
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getProfileInput(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(id);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getProfileInput() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration inputs = profile.getProfileInputIds();
+
+ while (inputs.hasMoreElements()) {
+ String inputId = (String) inputs.nextElement();
+ IProfileInput input = profile.getProfileInput(inputId);
+
+ nvp.add(inputId, input.getName(getLocale(req)));
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getInputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String id = req.getParameter(Constants.RS_ID);
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String inputId = st.nextToken();
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getInputConfig() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ IProfileInput profileInput = null;
+ NameValuePairs nvp = new NameValuePairs();
+
+ profileInput = profile.getProfileInput(inputId);
+ Enumeration names = profileInput.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ IDescriptor desc = profileInput.getConfigDescriptor(
+ getLocale(req), name);
+ if (desc == null) {
+ nvp.add(name, ";" + ";" + profileInput.getConfig(name));
+ } else {
+ nvp.add(name, desc.getSyntax() + ";" +
+ getNonNull(desc.getConstraint()) + ";" +
+ desc.getDescription(getLocale(req)) + ";" +
+ profileInput.getConfig(name));
+ }
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getOutputConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String id = req.getParameter(Constants.RS_ID);
+ StringTokenizer st = new StringTokenizer(id, ";");
+ String profileId = st.nextToken();
+ String outputId = st.nextToken();
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getOutputConfig() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ IProfileOutput profileOutput = null;
+ NameValuePairs nvp = new NameValuePairs();
+
+ profileOutput = profile.getProfileOutput(outputId);
+ Enumeration names = profileOutput.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ IDescriptor desc = profileOutput.getConfigDescriptor(
+ getLocale(req), name);
+ if (desc == null) {
+ nvp.add(name, ";" + ";" + profileOutput.getConfig(name));
+ } else {
+ nvp.add(name, desc.getSyntax() + ";" +
+ getNonNull(desc.getConstraint()) + ";" +
+ desc.getDescription(getLocale(req)) + ";" +
+ profileOutput.getConfig(name));
+ }
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void listProfileInstances(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ NameValuePairs nvp = new NameValuePairs();
+ Enumeration e = mProfileSub.getProfileIds();
+
+ while (e.hasMoreElements()) {
+ String profileId = (String) e.nextElement();
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(profileId);
+ } catch (EBaseException e1) {
+ // error
+ }
+
+ String status = null;
+
+ if (mProfileSub.isProfileEnable(profileId)) {
+ status = "enabled";
+ } else {
+ status = "disabled";
+ }
+
+ // mInstanceId + ";visible;" + enabled
+ nvp.add(profileId, profileId + ";visible;" + status);
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getProfileInstanceConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String id = req.getParameter(Constants.RS_ID);
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(id);
+ } catch (EBaseException e1) {
+ CMS.debug( "ProfileAdminServlet::getProfileInstanceConfig() - " +
+ "profile is null!" );
+ throw new ServletException( e1.toString() );
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ nvp.add("name", profile.getName(getLocale(req)));
+ nvp.add("desc", profile.getDescription(getLocale(req)));
+ nvp.add("visible", Boolean.toString(profile.isVisible()));
+ nvp.add("enable", Boolean.toString(
+ mProfileSub.isProfileEnable(id)));
+
+ String authid = profile.getAuthenticatorId();
+
+ if (authid == null) {
+ nvp.add("auth", "");
+ } else {
+ nvp.add("auth", authid);
+ }
+ CMS.debug("ProfileAdminServlet: authid=" + authid);
+ nvp.add("plugin", mProfileSub.getProfileClassId(id));
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ /**
+ * Delete profile instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void deleteProfileInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ String config = null;
+
+ ISubsystem subsystem = CMS.getSubsystem("ca");
+ String subname = "ca";
+
+ if (subsystem == null)
+ subname = "ra";
+
+ try {
+ config = CMS.getConfigStore().getString("instanceRoot") +
+ "/profiles/" + subname + "/" + id + ".cfg";
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ try {
+ mProfileSub.deleteProfile(id, config);
+ } catch (EProfileException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), e.toString(), id), null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ public void
+ putUserPWPair(String combo) {
+ int semicolon;
+
+ semicolon = combo.indexOf(";");
+ String user = combo.substring(0, semicolon);
+ String pw = combo.substring(semicolon + 1);
+
+ CMS.putPasswordCache(user, pw);
+ }
+
+ public boolean isValidId(String id)
+ {
+ for (int i = 0; i < id.length(); i++) {
+ char c = id.charAt(i);
+ if (!Character.isLetterOrDigit(c))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add profile instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void addProfileInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null || id.trim().equals("") || !isValidId(id)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, MISSING_POLICY_INST_ID, null, resp);
+ return;
+ }
+
+ // see if profile id already used
+ IProfile p = null;
+
+ try {
+ p = mProfileSub.getProfile(id);
+ } catch (EProfileException e1) {
+ }
+ if (p != null) {
+ sendResponse(ERROR, POLICY_INST_ID_ALREADY_USED, null, resp);
+ return;
+ }
+
+ String impl = req.getParameter("impl");
+ String name = req.getParameter("name");
+ String desc = req.getParameter("desc");
+ String visible = req.getParameter("visible");
+ String auth = req.getParameter("auth");
+ String config = null;
+
+ ISubsystem subsystem = CMS.getSubsystem("ca");
+ String subname = "ca";
+
+ if (subsystem == null)
+ subname = "ra";
+
+ try {
+ config = CMS.getConfigStore().getString("instanceRoot") + "/profiles/" + subname + "/" + id + ".cfg";
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ IPluginInfo info = mRegistry.getPluginInfo("profile", impl);
+
+ IProfile profile = null;
+
+ // create configuration file
+ File configFile = new File(config);
+
+ configFile.createNewFile();
+
+ // create profile
+ try {
+ profile = mProfileSub.createProfile(id, impl,
+ info.getClassName(),
+ config);
+ profile.setName(getLocale(req), name);
+ profile.setDescription(getLocale(req), name);
+ if (visible != null && visible.equals("true")) {
+ profile.setVisible(true);
+ } else {
+ profile.setVisible(false);
+ }
+ profile.setAuthenticatorId(auth);
+ profile.getConfigStore().commit(false);
+
+ mProfileSub.createProfileConfig(id, impl, config);
+ if (profile instanceof IProfileEx) {
+ // populates profile specific plugins such as
+ // policies, inputs and outputs
+ ((IProfileEx)profile).populate();
+ }
+ } catch (Exception e) {
+ CMS.debug("ProfileAdminServlet: " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ /**
+ * Modify profile instance
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE used when
+ * configuring cert profile (general settings and cert profile; obsoletes
+ * extensions and constraints policies)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ */
+ public void modifyProfileInstance(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // Get the policy impl id and class path.
+ String id = req.getParameter(Constants.RS_ID);
+
+ IProfile profile = null;
+
+ try {
+ profile = mProfileSub.getProfile(id);
+ } catch (EBaseException e1) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, null, null, resp);
+ return;
+ }
+ String name = req.getParameter("name");
+ String desc = req.getParameter("desc");
+ String auth = req.getParameter("auth");
+ String visible = req.getParameter("visible");
+
+ // String config = req.getParameter("config");
+
+ profile.setAuthenticatorId(auth);
+ profile.setName(getLocale(req), name);
+ profile.setDescription(getLocale(req), desc);
+ if (visible != null && visible.equals("true")) {
+ profile.setVisible(true);
+ } else {
+ profile.setVisible(false);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (Exception e) {
+ }
+
+ sendResponse(SUCCESS, null, null, resp);
+ } catch (IOException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+ }
+
+ protected String getNonNull(String s) {
+ if (s == null)
+ return "";
+ return s;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
new file mode 100644
index 000000000..d840f6cda
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
@@ -0,0 +1,3054 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import org.mozilla.jss.ssl.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.cmsutil.password.*;
+
+
+/**
+ * A class representing an publishing servlet for the
+ * Publishing subsystem. This servlet is responsible
+ * to serve configuration requests for the Publishing subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PublisherAdminServlet extends AdminServlet {
+ public final static String PROP_AUTHORITY = "authority";
+
+ private final static String INFO = "PublisherAdminServlet";
+ private final static String PW_TAG_CA_LDAP_PUBLISHING =
+ "CA LDAP Publishing";
+ public final static String NOMAPPER = "<NONE>";
+ private IPublisherProcessor mProcessor = null;
+ private IAuthority mAuth = null;
+
+ private final static String VIEW = ";" + Constants.VIEW;
+ private final static String EDIT = ";" + Constants.EDIT;
+
+ public PublisherAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuth = (IAuthority) CMS.getSubsystem(authority);
+ if (mAuth != null)
+ if (mAuth instanceof ICertificateAuthority) {
+ mProcessor = ((ICertificateAuthority) mAuth).getPublisherProcessor();
+ } else
+ throw new ServletException(authority + " does not have publishing processor!");
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ CMS.debug("PublisherAdminServlet: in service");
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (op == null) {
+ //System.out.println("SRVLT_INVALID_PROTOCOL");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ // for the rest
+ try {
+ super.authenticate(req);
+
+ if (op.equals(OpDef.OP_AUTH)) { // for admin authentication only
+ sendResponse(SUCCESS, null, null, resp);
+ return;
+ }
+ } catch (IOException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req),"CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+ try {
+ AUTHZ_RES_NAME = "certServer.publisher.configuration";
+ if (scope != null) {
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LDAP)) {
+ getLDAPDest(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_IMPLS)) {
+ getConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_RULES)) {
+ getInstConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_IMPLS)) {
+ getMapperConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_RULES)) {
+ getMapperInstConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_IMPLS)) {
+ getRuleConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_EXTENDED_PLUGIN_INFO)) {
+ getExtendedPluginInfo(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_RULES)) {
+ getRuleInstConfig(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LDAP)) {
+ setLDAPDest(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_RULES)) {
+ modPublisherInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_RULES)) {
+ modMapperInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_RULES)) {
+ modRuleInst(req, resp, scope);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_PROCESS)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_LDAP)) {
+ testSetLDAPDest(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_PUBLISHER_IMPLS)) {
+ listPublisherPlugins(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_RULES)) {
+ listPublisherInsts(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_IMPLS)) {
+ listMapperPlugins(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_RULES)) {
+ listMapperInsts(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_IMPLS)) {
+ listRulePlugins(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_RULES)) {
+ listRuleInsts(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_PUBLISHER_IMPLS)) {
+ addPublisherPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_RULES)) {
+ addPublisherInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_IMPLS)) {
+ addMapperPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_RULES)) {
+ addMapperInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_IMPLS)) {
+ addRulePlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_RULES)) {
+ addRuleInst(req, resp, scope);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_PUBLISHER_IMPLS)) {
+ delPublisherPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_PUBLISHER_RULES)) {
+ delPublisherInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_IMPLS)) {
+ delMapperPlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_MAPPER_RULES)) {
+ delMapperInst(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_IMPLS)) {
+ delRulePlugin(req, resp, scope);
+ return;
+ } else if (scope.equals(ScopeDef.SC_RULE_RULES)) {
+ delRuleInst(req, resp, scope);
+ return;
+ }
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_TYPE", op),
+ null, resp);
+ return;
+ }
+ } else {
+ //System.out.println("SRVLT_INVALID_OP_SCOPE");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ } catch (EBaseException e) {
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ }
+ //System.out.println("SRVLT_FAIL_PERFORM 2");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+
+ private IExtendedPluginInfo getExtendedPluginInfo(IPublisherProcessor
+ p) {
+ Enumeration mappers = p.getMapperInsts().keys();
+ Enumeration publishers = p.getPublisherInsts().keys();
+
+ StringBuffer map = new StringBuffer();
+
+ for (; mappers.hasMoreElements();) {
+ String name = (String) mappers.nextElement();
+
+ if (map.length()== 0) {
+ map.append(name);
+ } else {
+ map.append(",");
+ map.append(name);
+ }
+ }
+ StringBuffer publish = new StringBuffer();
+
+ for (; publishers.hasMoreElements();) {
+ String name = (String) publishers.nextElement();
+
+ publish.append(",");
+ publish.append(name);
+ }
+
+ String epi[] = new String[] {
+ "type;choice(cacert,crl,certs,xcert);The certType of the request",
+ "mapper;choice(" + map.toString() + ");Use the mapper to find the ldap dn to publish the certificate or crl",
+ "publisher;choice(" + publish.toString() + ");Use the publisher to publish the certificate or crl a directory etc",
+ "enable;boolean;",
+ "predicate;string;"
+ };
+
+ return new ExtendedPluginInfo(epi);
+ }
+
+ private NameValuePairs getExtendedPluginInfo(Locale locale, String implType, String implName) {
+ IExtendedPluginInfo ext_info = null;
+ Object impl = null;
+
+ if (implType.equals(Constants.PR_EXT_PLUGIN_IMPLTYPE_PUBLISHRULE)) {
+ IPublisherProcessor p_processor = mProcessor;
+ Plugin plugin = (Plugin) p_processor.getRulePlugins().get(implName);
+
+ // Should get the registered rules from processor
+ // instead of plugin
+ // OLD: impl = getClassByNameAsExtendedPluginInfo(plugin.getClassPath());
+ impl = getExtendedPluginInfo(p_processor);
+ } else if (implType.equals(Constants.PR_EXT_PLUGIN_IMPLTYPE_MAPPER)) {
+ IPublisherProcessor p_processor = mProcessor;
+ Plugin plugin = (Plugin) p_processor.getMapperPlugins().get(implName
+ );
+
+ impl = getClassByNameAsExtendedPluginInfo(plugin.getClassPath());
+
+ } else if (implType.equals(Constants.PR_EXT_PLUGIN_IMPLTYPE_PUBLISHER)
+ ) {
+ IPublisherProcessor p_processor = mProcessor;
+ Plugin plugin = (Plugin) p_processor.getPublisherPlugins().get(implName);
+
+ impl = getClassByNameAsExtendedPluginInfo(plugin.getClassPath());
+ }
+ if (impl != null) {
+ if (impl instanceof IExtendedPluginInfo) {
+ ext_info = (IExtendedPluginInfo) impl;
+ }
+ }
+
+ NameValuePairs nvps = null;
+
+ if (ext_info == null) {
+ nvps = new NameValuePairs();
+ } else {
+ nvps = convertStringArrayToNVPairs(ext_info.getExtendedPluginInfo(locale));
+ }
+
+ return nvps;
+
+ }
+
+ /**
+ * retrieve extended plugin info such as brief description, type info
+ * from policy, authentication,
+ * need to add: listener, mapper and publishing plugins
+ */
+ private void getExtendedPluginInfo(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ int colon = id.indexOf(':');
+
+ String implType = id.substring(0, colon);
+ String implName = id.substring(colon + 1);
+
+ NameValuePairs params =
+ getExtendedPluginInfo(getLocale(req), implType, implName);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getLDAPDest(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ IConfigStore config = mAuth.getConfigStore();
+ IConfigStore publishcfg = config.getSubStore(IPublisherProcessor.PROP_PUBLISH_SUBSTORE);
+ IConfigStore ldapcfg = publishcfg.getSubStore(IPublisherProcessor.PROP_LDAP_PUBLISH_SUBSTORE);
+ IConfigStore ldap = ldapcfg.getSubStore(IPublisherProcessor.PROP_LDAP);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_ENABLE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_ENABLE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_THREADS))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PRIORITY))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_STATUS))
+ continue;
+ if (name.equals(Constants.PR_CERT_NAMES)) {
+ ICryptoSubsystem jss = (ICryptoSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ params.add(name, jss.getAllCerts());
+ } else {
+ String value = ldap.getString(name, "");
+
+ if (value == null || value.equals("")) {
+ if (name.equals(ILdapBoundConnFactory.PROP_LDAPCONNINFO + "." + ILdapConnInfo.PROP_HOST)) {
+ value = mConfig.getString(ConfigConstants.PR_MACHINE_NAME, null);
+ } else if (name.equals(ILdapBoundConnFactory.PROP_LDAPCONNINFO + "." + ILdapConnInfo.PROP_PORT)) {
+ value = ILdapConnInfo.PROP_PORT_DEFAULT;
+ } else if (name.equals(ILdapBoundConnFactory.PROP_LDAPAUTHINFO + "." + ILdapAuthInfo.PROP_BINDDN)) {
+ value = ILdapAuthInfo.PROP_BINDDN_DEFAULT;
+ }
+ }
+ params.add(name, value);
+ }
+ }
+ params.add(Constants.PR_PUBLISHING_ENABLE,
+ publishcfg.getString(IPublisherProcessor.PROP_ENABLE, Constants.FALSE));
+ params.add(Constants.PR_PUBLISHING_QUEUE_ENABLE,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_ENABLE, Constants.TRUE));
+ params.add(Constants.PR_PUBLISHING_QUEUE_THREADS,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_THREADS, "3"));
+ params.add(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE, "40"));
+ params.add(Constants.PR_PUBLISHING_QUEUE_PRIORITY,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_PRIORITY, "0"));
+ params.add(Constants.PR_PUBLISHING_QUEUE_STATUS,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_STATUS, "200"));
+ params.add(Constants.PR_ENABLE,
+ ldapcfg.getString(IPublisherProcessor.PROP_ENABLE, Constants.FALSE));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setLDAPDest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ //Save New Settings to the config file
+ IConfigStore config = mAuth.getConfigStore();
+ IConfigStore publishcfg = config.getSubStore(IPublisherProcessor.PROP_PUBLISH_SUBSTORE);
+ IConfigStore ldapcfg = publishcfg.getSubStore(IPublisherProcessor.PROP_LDAP_PUBLISH_SUBSTORE);
+ IConfigStore ldap = ldapcfg.getSubStore(IPublisherProcessor.PROP_LDAP);
+
+ //set enable flag
+ publishcfg.putString(IPublisherProcessor.PROP_ENABLE, req.getParameter(Constants.PR_PUBLISHING_ENABLE));
+ String enable = req.getParameter(Constants.PR_ENABLE);
+
+ ldapcfg.putString(IPublisherProcessor.PROP_ENABLE, enable);
+ if (enable.equals("false")) {
+ // need to disable the ldap module here
+ mProcessor.setLdapConnModule(null);
+ }
+
+ //set reset of the parameters
+ Enumeration e = req.getParameterNames();
+ String pwd = null;
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_ENABLE))
+ continue;
+ // don't store password in the config file.
+ if (name.equals(Constants.PR_BIND_PASSWD))
+ continue; // old style password read from config.
+ if (name.equals(Constants.PR_DIRECTORY_MANAGER_PWD)) {
+ pwd = req.getParameter(name);
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_ENABLE)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_THREADS)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PRIORITY)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_STATUS)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+
+ /* Don't enter the publishing pw into the config store */
+ ldap.putString(name, req.getParameter(name));
+ }
+
+ commit(true);
+
+ /* Do a "PUT" of the new pw to the watchdog"
+ ** do not remove - cfu
+ if (pwd != null)
+ CMS.putPasswordCache(PW_TAG_CA_LDAP_PUBLISHING, pwd);
+ */
+
+ // support publishing dirsrv with different pwd than internaldb
+ // update passwordFile
+ String prompt = ldap.getString(Constants.PR_BINDPWD_PROMPT);
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): saving password for "+ prompt + " to password file");
+ pwdStore.putPassword(prompt, pwd);
+ pwdStore.commit();
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): password saved");
+
+/* we'll shut down and restart the PublisherProcessor instead
+ // what a hack to do this without require restart server
+// ILdapAuthInfo authInfo = CMS.getLdapAuthInfo();
+ ILdapConnModule connModule = mProcessor.getLdapConnModule();
+ ILdapAuthInfo authInfo = null;
+ if (connModule != null) {
+ authInfo = connModule.getLdapAuthInfo();
+ }
+
+// authInfo.addPassword(PW_TAG_CA_LDAP_PUBLISHING, pwd);
+ if (authInfo != null) {
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): adding password to memory cache");
+ authInfo.addPassword(prompt, pwd);
+ } else
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): authInfo null");
+*/
+
+ try {
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): restarting publishing processor");
+ mProcessor.shutdown();
+ mProcessor.startup();
+ CMS.debug("PublisherAdminServlet: setLDAPDest(): publishing processor restarted");
+ } catch (Exception ex) {
+ // force to save the config even there is error
+ // ignore any exception
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_RES_LDAP", ex.toString()));
+ }
+
+ //XXX See if we can dynamically in B2
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void testSetLDAPDest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ CMS.debug("PublisherAdmineServlet: in testSetLDAPDest");
+ //Save New Settings to the config file
+ IConfigStore config = mAuth.getConfigStore();
+ IConfigStore publishcfg = config.getSubStore(IPublisherProcessor.PROP_PUBLISH_SUBSTORE);
+ IConfigStore ldapcfg = publishcfg.getSubStore(IPublisherProcessor.PROP_LDAP_PUBLISH_SUBSTORE);
+ IConfigStore ldap = ldapcfg.getSubStore(IPublisherProcessor.PROP_LDAP);
+
+ //set enable flag
+ publishcfg.putString(IPublisherProcessor.PROP_ENABLE,
+ req.getParameter(Constants.PR_PUBLISHING_ENABLE));
+ String ldapPublish = req.getParameter(Constants.PR_ENABLE);
+
+ ldapcfg.putString(IPublisherProcessor.PROP_ENABLE, ldapPublish);
+ if (ldapPublish.equals("false")) {
+ // need to disable the ldap module here
+ mProcessor.setLdapConnModule(null);
+ }
+
+ //set reset of the parameters
+ Enumeration e = req.getParameterNames();
+ String pwd = null;
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ if (name.equals(Constants.PR_PUBLISHING_ENABLE))
+ continue;
+ // don't store password in the config file.
+ if (name.equals(Constants.PR_BIND_PASSWD))
+ continue; // old style password read from config.
+ if (name.equals(Constants.PR_DIRECTORY_MANAGER_PWD)) {
+ pwd = req.getParameter(name);
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_ENABLE)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_THREADS)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_PRIORITY)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+ if (name.equals(Constants.PR_PUBLISHING_QUEUE_STATUS)) {
+ publishcfg.putString(name, req.getParameter(name));
+ continue;
+ }
+
+ /* Don't enter the publishing pw into the config store */
+ ldap.putString(name, req.getParameter(name));
+ }
+
+ // test before commit
+ if (publishcfg.getBoolean(IPublisherProcessor.PROP_ENABLE) &&
+ ldapcfg.getBoolean(IPublisherProcessor.PROP_ENABLE)) {
+ params.add("title",
+ "You've attempted to configure CMS to connect" +
+ " to a LDAP directory. The connection status is" +
+ " as follows:\n \n");
+ LDAPConnection conn = null;
+ ILdapConnInfo connInfo =
+ CMS.getLdapConnInfo(ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPCONNINFO));
+ //LdapAuthInfo authInfo =
+ //new LdapAuthInfo(ldap.getSubStore(
+ // ILdapBoundConnFactory.PROP_LDAPAUTHINFO));
+ String host = connInfo.getHost();
+ int port = connInfo.getPort();
+ boolean secure = connInfo.getSecure();
+ //int authType = authInfo.getAuthType();
+ String authType = ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPAUTHINFO).getString(ILdapAuthInfo.PROP_LDAPAUTHTYPE);
+ int version = connInfo.getVersion();
+ String bindAs = null;
+ String certNickName = null;
+
+ if (authType.equals(ILdapAuthInfo.LDAP_SSLCLIENTAUTH_STR)) {
+ try {
+ //certNickName = authInfo.getParms()[0];
+ certNickName = ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPAUTHINFO).getString(ILdapAuthInfo.PROP_CLIENTCERTNICKNAME);
+ conn = new LDAPConnection(CMS.getLdapJssSSLSocketFactory(
+ certNickName));
+ CMS.debug("Publishing Test certNickName=" + certNickName);
+ params.add(Constants.PR_CONN_INITED,
+ "Create ssl LDAPConnection with certificate: " +
+ certNickName + dashes(70 - 44 - certNickName.length()) + " Success");
+ } catch (Exception ex) {
+ params.add(Constants.PR_CONN_INIT_FAIL,
+ "Create ssl LDAPConnection with certificate: " +
+ certNickName + dashes(70 - 44 - certNickName.length()) + " failure\n" + " exception: " + ex);
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then LDAP publishing will fail.\n" +
+ "Do you want to save the configuration anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ try {
+ conn.connect(host, port);
+ params.add(Constants.PR_CONN_OK,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) + " Success");
+ params.add(Constants.PR_AUTH_OK,
+ "Authentication: SSL client authentication" +
+ dashes(70 - 41) + " Success" +
+ "\nBind to the directory as: " + certNickName +
+ dashes(70 - 26 - certNickName.length()) + " Success");
+ } catch (LDAPException ex) {
+ if (ex.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ params.add(Constants.PR_CONN_FAIL,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) +
+ " Failure\n" +
+ " error: server unavailable");
+ } else {
+ params.add(Constants.PR_CONN_FAIL,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) +
+ " Failure");
+ }
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "LDAP publishing will fail.\n" +
+ "Do you want to save the configuration anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ } else {
+ try {
+ if (secure) {
+ conn = new LDAPConnection(
+ CMS.getLdapJssSSLSocketFactory());
+ params.add(Constants.PR_CONN_INITED,
+ "Create ssl LDAPConnection" +
+ dashes(70 - 25) + " Success");
+ } else {
+ conn = new LDAPConnection();
+ params.add(Constants.PR_CONN_INITED,
+ "Create LDAPConnection" +
+ dashes(70 - 21) + " Success");
+ }
+ } catch (Exception ex) {
+ params.add(Constants.PR_CONN_INIT_FAIL,
+ "Create LDAPConnection" +
+ dashes(70 - 21) + " Failure\n" +
+ "exception: " + ex);
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "LDAP publishing will fail.\n" +
+ "Do you want to save the configuration anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ try {
+ conn.connect(host, port);
+ params.add(Constants.PR_CONN_OK,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) + " Success");
+ } catch (LDAPException ex) {
+ if (ex.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ params.add(Constants.PR_CONN_FAIL,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) + " Failure" +
+ "\nerror: server unavailable");
+ } else {
+ params.add(Constants.PR_CONN_FAIL,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) + " Failure" +
+ "\nexception: " + ex);
+ }
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "LDAP publishing will fail.\n" +
+ "Do you want to save the configuration anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ try {
+ //bindAs = authInfo.getParms()[0];
+ bindAs = ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPAUTHINFO).getString(ILdapAuthInfo.PROP_BINDDN);
+ conn.authenticate(version, bindAs, pwd);
+ params.add(Constants.PR_AUTH_OK,
+ "Authentication: Basic authentication" +
+ dashes(70 - 36) + " Success" +
+ "\nBind to the directory as: " + bindAs +
+ dashes(70 - 26 - bindAs.length()) + " Success");
+ } catch (LDAPException ex) {
+ if (ex.getLDAPResultCode() ==
+ LDAPException.NO_SUCH_OBJECT) {
+ params.add(Constants.PR_AUTH_FAIL,
+ "Authentication: Basic authentication" +
+ dashes(70 - 36) + "Failure" +
+ "\nBind to the directory as: " + bindAs +
+ dashes(70 - 26 - bindAs.length()) +
+ "Failure" + "\nThe object doesn't exist. " +
+ "Please correct the value assigned in the" +
+ " \"Directory manager DN\" field.");
+ } else if (ex.getLDAPResultCode() ==
+ LDAPException.INVALID_CREDENTIALS) {
+ params.add(Constants.PR_AUTH_FAIL,
+ "Authentication: Basic authentication" +
+ dashes(70 - 36) + " Failure" +
+ "\nBind to the directory as: " + bindAs +
+ dashes(70 - 26 - bindAs.length()) +
+ " Failure" + "\nInvalid password. " +
+ "Please correct the value assigned in the" +
+ " \"Password\" field.");
+ } else {
+ params.add(Constants.PR_AUTH_FAIL,
+ "Authentication: Basic authentication" +
+ dashes(70 - 36) + " Failure" +
+ "\nBind to the directory as: " + bindAs +
+ dashes(70 - 26 - bindAs.length()) +
+ " Failure");
+ }
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "LDAP publishing will fail.\n" +
+ "Do you want to save the configuration anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ }
+
+ }
+
+ //commit(true);
+ if (ldapcfg.getBoolean(IPublisherProcessor.PROP_ENABLE) &&
+ pwd != null) {
+
+ /* Do a "PUT" of the new pw to the watchdog"
+ ** do not remove - cfu
+ CMS.putPasswordCache(PW_TAG_CA_LDAP_PUBLISHING, pwd);
+ */
+
+ // support publishing dirsrv with different pwd than internaldb
+ // update passwordFile
+ String prompt = ldap.getString(Constants.PR_BINDPWD_PROMPT);
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+ CMS.debug("PublisherAdminServlet: testSetLDAPDest(): saving password for "+
+ prompt + " to password file");
+ pwdStore.putPassword(prompt, pwd);
+ pwdStore.commit();
+ CMS.debug("PublisherAdminServlet: testSetLDAPDest(): password saved");
+/* we'll shut down and restart the PublisherProcessor instead
+ // what a hack to do this without require restart server
+// ILdapAuthInfo authInfo = CMS.getLdapAuthInfo();
+ ILdapConnModule connModule = mProcessor.getLdapConnModule();
+ ILdapAuthInfo authInfo = null;
+ if (connModule != null) {
+ authInfo = connModule.getLdapAuthInfo();
+ } else
+ CMS.debug("PublisherAdminServlet: testSetLDAPDest(): connModule null");
+
+// authInfo.addPassword(PW_TAG_CA_LDAP_PUBLISHING, pwd);
+ if (authInfo != null) {
+ CMS.debug("PublisherAdminServlet: testSetLDAPDest(): adding password to memory cache");
+ authInfo.addPassword(prompt, pwd);
+ } else
+ CMS.debug("PublisherAdminServlet: testSetLDAPDest(): authInfo null");
+*/
+ }
+ //params.add(Constants.PR_SAVE_OK,
+ // "\n \nConfiguration changes are now committed.");
+
+ mProcessor.shutdown();
+
+ if (publishcfg.getBoolean(IPublisherProcessor.PROP_ENABLE)) {
+ mProcessor.startup();
+ //params.add("restarted", "Publishing is restarted.");
+
+ if (ldapcfg.getBoolean(IPublisherProcessor.PROP_ENABLE)) {
+ ICertAuthority authority = (ICertAuthority) mProcessor.getAuthority();
+
+ if (!(authority instanceof ICertificateAuthority))
+ return;
+ ICertificateAuthority ca = (ICertificateAuthority) authority;
+
+ // publish ca cert
+ try {
+ mProcessor.publishCACert(ca.getCACert());
+ CMS.debug("PublisherAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_PUB_CA_CERT"));
+ params.add("publishCA",
+ "CA certificate is published.");
+ } catch (Exception ex) {
+ // exception not thrown - not seen as a fatal error.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_NO_PUB_CA_CERT", ex.toString()));
+ params.add("publishCA",
+ "Failed to publish CA certificate.");
+ int index = ex.toString().indexOf("Failed to create CA");
+
+ if (index > -1) {
+ params.add("createError",
+ ex.toString().substring(index));
+ }
+ mProcessor.shutdown();
+ // Do you want to enable LDAP publishing anyway
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "the CA certificate won't be published.\n" +
+ "Do you want to enable LDAP publishing anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+
+ }
+ // publish crl
+ try {
+ CMS.debug("PublisherAdminServlet: about to update CRL");
+ ca.publishCRLNow();
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_PUB_CRL"));
+ params.add("publishCRL",
+ "CRL is published.");
+ } catch (Exception ex) {
+ // exception not thrown - not seen as a fatal error.
+ log(ILogger.LL_FAILURE,
+ "Could not publish crl " + ex.toString());
+ params.add("publishCRL",
+ "Failed to publish CRL.");
+ mProcessor.shutdown();
+ // Do you want to enable LDAP publishing anyway
+ params.add(Constants.PR_SAVE_NOT,
+ "\n \nIf the problem is not fixed then " +
+ "the CRL won't be published.\n" +
+ "Do you want to enable LDAP publishing anyway?");
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+ }
+ commit(true);
+ params.add(Constants.PR_SAVE_OK,
+ "\n \nConfiguration changes are now committed.");
+ params.add("restarted", "Publishing is restarted.");
+ } else {
+ commit(true);
+ params.add(Constants.PR_SAVE_OK,
+ "\n \nConfiguration changes are now committed.");
+ params.add("stopped",
+ "Publishing is stopped.");
+ }
+
+ //XXX See if we can dynamically in B2
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private synchronized void addMapperPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the manager id unique?
+ if (mProcessor.getMapperPlugins().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req),"CMS_LDAP_SRVLT_ILL_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_MAPPER_CLASS);
+
+ if (classPath == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req),"CMS_LDAP_SRVLT_NULL_CLASS"), null, resp);
+ return;
+ }
+
+ IConfigStore destStore = null;
+
+ destStore = mConfig.getSubStore(mAuth.getId() + ".publish.mapper");
+ IConfigStore instancesConfig = destStore.getSubStore("impl");
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ }
+
+ // is the class an ILdapMapper?
+ try {
+ if (ILdapMapper.class.isAssignableFrom(newImpl) == false) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_MAPPER_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add mapper to registry.
+ MapperPlugin plugin = new MapperPlugin(id, classPath);
+
+ mProcessor.getMapperPlugins().put(id, plugin);
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_MAPPER_ADDED", ""));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private boolean isValidID(String id) {
+ if (id == null)
+ return false;
+ for (int i = 0; i < id.length(); i++) {
+ if (!Character.isLetterOrDigit(id.charAt(i)))
+ return false;
+ }
+ return true;
+ }
+
+ private synchronized void addMapperInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (!isValidID(id)) {
+ sendResponse(ERROR, "Invalid ID '" + id + "'",
+ null, resp);
+ return;
+ }
+
+ if (mProcessor.getMapperInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ String implname = req.getParameter(
+ Constants.PR_MAPPER_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+
+ // check if implementation exists.
+ MapperPlugin plugin =
+ (MapperPlugin) mProcessor.getMapperPlugins().get(
+ implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EMapperPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_MAPPER_PLUGIN_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getMapperDefaultParams(implname);
+
+ IConfigStore destStore = mConfig.getSubStore(mAuth.getId() + ".publish.mapper");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String val = req.getParameter(kv.substring(0, index));
+
+ if (val == null) {
+ substore.put(kv.substring(0, index),
+ kv.substring(index + 1));
+ } else {
+ substore.put(kv.substring(0, index),
+ val);
+ }
+ }
+ }
+ substore.put("pluginName", implname);
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ ILdapMapper mapperInst = null;
+
+ try {
+ mapperInst = (ILdapMapper) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the mapper
+ try {
+ mapperInst.init(substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // inited and commited ok. now add mapper instance to list.
+ mProcessor.getMapperInsts().put(id, new MapperProxy(true, mapperInst));
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_MAPPER_INST_ADDED", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_MAPPER_IMPL_NAME, implname);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listMapperPlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mProcessor.getMapperPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ MapperPlugin value = (MapperPlugin)
+ mProcessor.getMapperPlugins().get(name);
+ // get Description
+ String c = value.getClassPath();
+ String desc = "unknown";
+
+ try {
+ ILdapMapper lp = (ILdapMapper)
+ Class.forName(c).newInstance();
+
+ desc = lp.getDescription();
+ } catch (Exception exp) {
+ sendResponse(ERROR, exp.toString(), null,
+ resp);
+ return;
+ }
+ params.add(name, value.getClassPath() + "," + desc);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ public String getMapperPluginName(ILdapMapper mapper) {
+ IConfigStore cs = mapper.getConfigStore();
+
+ try {
+ return cs.getString("pluginName", "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ private synchronized void listMapperInsts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mProcessor.getMapperInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILdapMapper value = mProcessor.getMapperInstance(name);
+
+ params.add(name, getMapperPluginName(value) + ";visible");
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delMapperInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does a`mapper instance exist?
+ if (mProcessor.getMapperInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EMapperNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_MAPPER_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ ILdapMapper mapperInst = (ILdapMapper)
+ mProcessor.getMapperInstance(id);
+
+ mProcessor.getMapperInsts().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore(
+ mAuth.getId() + ".publish.mapper");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delMapperPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (mProcessor.getMapperPlugins().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EMapperPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_MAPPER_PLUGIN_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this mapper
+ // DON'T remove mapper if any instance
+ for (Enumeration e = mProcessor.getMapperInsts().keys();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILdapMapper mapper = mProcessor.getMapperInstance(name);
+
+ if (id.equals(getMapperPluginName(mapper))) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_IN_USE"), null, resp);
+ return;
+ }
+ }
+
+ // then delete this mapper
+ mProcessor.getMapperPlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(
+ mAuth.getId() + ".publish.mapper");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("impl");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void getMapperConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getMapperDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_MAPPER_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getMapperInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does mapper instance exist?
+ if (mProcessor.getMapperInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EMapperNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_MAPPER_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ ILdapMapper mapperInst = (ILdapMapper)
+ mProcessor.getMapperInstance(id);
+ Vector configParams = mapperInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_MAPPER_IMPL_NAME,
+ getMapperPluginName(mapperInst));
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void modMapperInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the manager instance exist?
+ if (!mProcessor.getMapperInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_MAPPER_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+ // get plugin for implementation
+ MapperPlugin plugin =
+ (MapperPlugin) mProcessor.getMapperPlugins().get(implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EMapperPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_MAPPER_PLUGIN_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ ILdapMapper oldinst =
+ (ILdapMapper) mProcessor.getMapperInstance(id);
+ Vector oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.add("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = (String) oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId() +
+ ".publish.mapper");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ // create new substore.
+
+ Vector configParams = mProcessor.getMapperInstanceParams(id);
+
+ instancesConfig.removeSubStore(id);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put("pluginName", implname);
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String key = kv.substring(0, index);
+ String val = req.getParameter(key);
+
+ if (val != null) {
+ substore.put(key, val);
+ }
+ }
+ }
+
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ ILdapMapper newMgrInst = null;
+
+ try {
+ newMgrInst = (ILdapMapper)
+ Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+ // initialize the mapper
+
+ try {
+ newMgrInst.init(substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(getLocale(req)), null,
+ resp);
+ return;
+ } catch (Throwable e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(), null,
+ resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ mProcessor.getMapperInsts().put(id, new MapperProxy(true, newMgrInst));
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_MAPPER_REPLACED", id));
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void addRulePlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the rule id unique?
+ if (mProcessor.getRulePlugins().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage("CMS_LDAP_SRVLT_ILL_PLUGIN_ID", id)).toString(getLocale(req)),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_RULE_CLASS);
+
+ if (classPath == null) {
+ sendResponse(ERROR, CMS.getUserMessage("CMS_LDAP_SRVLT_NULL_CLASS"), null, resp);
+ return;
+ }
+
+ IConfigStore destStore = null;
+
+ destStore = mConfig.getSubStore(
+ mAuth.getId() + ".publish.rule");
+ IConfigStore instancesConfig = destStore.getSubStore("impl");
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ }
+
+ // is the class an ILdapRule?
+ try {
+ if (ILdapRule.class.isAssignableFrom(newImpl) == false) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_RULE_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add rule to registry.
+ RulePlugin plugin = new RulePlugin(id, classPath);
+
+ mProcessor.getRulePlugins().put(id, plugin);
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_RULE_PLUG_ADDED", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void addRuleInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+ if (!isValidID(id)) {
+ sendResponse(ERROR, "Invalid ID '" + id + "'",
+ null, resp);
+ return;
+ }
+
+ if (mProcessor.getRuleInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ String implname = req.getParameter(
+ Constants.PR_RULE_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+
+ // check if implementation exists.
+ RulePlugin plugin =
+ (RulePlugin) mProcessor.getRulePlugins().get(
+ implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EPublisherPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_PLUGIN_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getRuleDefaultParams(implname);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId()
+ + ".publish.rule");
+ IConfigStore instancesConfig =
+ destStore.getSubStore("instance");
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String val = req.getParameter(kv.substring(0, index));
+
+ if (val == null) {
+ substore.put(kv.substring(0, index),
+ kv.substring(index + 1));
+ } else {
+ if (val.equals(NOMAPPER))
+ val = "";
+ substore.put(kv.substring(0, index),
+ val);
+ }
+ }
+ }
+ substore.put("pluginName", implname);
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ ILdapRule ruleInst = null;
+
+ try {
+ ruleInst = (ILdapRule) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the rule
+ try {
+ ruleInst.init(mProcessor, substore);
+ ruleInst.setInstanceName(id);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+ // inited and commited ok. now add manager instance to list.
+ mProcessor.getRuleInsts().put(id, ruleInst);
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_RULE_INST_ADDED", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_RULE_IMPL_NAME, implname);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listRulePlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mProcessor.getRulePlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ RulePlugin value = (RulePlugin)
+ mProcessor.getRulePlugins().get(name);
+ // get Description
+ String c = value.getClassPath();
+ String desc = "unknown";
+
+ try {
+ ILdapRule lp = (ILdapRule)
+ Class.forName(c).newInstance();
+
+ desc = lp.getDescription();
+ } catch (Exception exp) {
+ }
+ params.add(name, value.getClassPath() + "," + desc);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listRuleInsts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String insts = null;
+ Enumeration e = mProcessor.getRuleInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILdapRule value = (ILdapRule)
+ mProcessor.getRuleInsts().get((Object) name);
+ String enabled = value.enabled() ? "enabled" : "disabled";
+
+ params.add(name, value.getInstanceName() + ";visible;" + enabled);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ public String getRulePluginName(ILdapRule rule) {
+ IConfigStore cs = rule.getConfigStore();
+
+ try {
+ return cs.getString("pluginName", "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ private synchronized void delRulePlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does rule exist?
+ if (mProcessor.getRulePlugins().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new ERulePluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_RULE_PLUGIN_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this rule
+ // DON'T remove rule if any instance
+ for (Enumeration e = mProcessor.getRuleInsts().elements();
+ e.hasMoreElements();) {
+ ILdapRule rule = (ILdapRule)
+ e.nextElement();
+
+ if (id.equals(getRulePluginName(rule))) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_IN_USE"), null, resp);
+ return;
+ }
+ }
+
+ // then delete this rule
+ mProcessor.getRulePlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(
+ mAuth.getId() + ".rule");
+ IConfigStore instancesConfig = destStore.getSubStore("impl");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delRuleInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // prevent deletion of admin and agent.
+
+ // does rule instance exist?
+ if (mProcessor.getRuleInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new ERuleNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_RULE_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ ILdapRule ruleInst = (ILdapRule)
+ mProcessor.getRuleInsts().get(id);
+
+ mProcessor.getRuleInsts().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore(
+ mAuth.getId() + ".publish.rule");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void getRuleConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getRuleDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_RULE_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getRuleInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does rule instance exist?
+ if (mProcessor.getRuleInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new ERuleNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_RULE_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ ILdapRule ruleInst = (ILdapRule)
+ mProcessor.getRuleInsts().get(id);
+ Vector configParams = ruleInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_RULE_IMPL_NAME,
+ getRulePluginName(ruleInst));
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void modRuleInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the manager instance exist?
+ if (!mProcessor.getRuleInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_RULE_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+
+ // get plugin for implementation
+ RulePlugin plugin =
+ (RulePlugin) mProcessor.getRulePlugins().get(implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ //new ERulePluginNotFound(implname).toString(getLocale(req)),
+ "",
+ null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ ILdapRule oldinst =
+ (ILdapRule) mProcessor.getRuleInsts().get((Object) id);
+ Vector oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.add("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = (String) oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore(
+ mAuth.getId() + ".publish.rule");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ // create new substore.
+
+ Vector configParams = mProcessor.getRuleDefaultParams(implname);
+
+ instancesConfig.removeSubStore(id);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put("pluginName", implname);
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String key = kv.substring(0, index);
+ String val = req.getParameter(key);
+
+ if (val == null) {
+ substore.put(key,
+ kv.substring(index + 1));
+ } else {
+ if (val.equals(NOMAPPER))
+ val = "";
+ substore.put(key, val);
+ }
+ }
+ }
+
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ ILdapRule newRuleInst = null;
+
+ try {
+ newRuleInst = (ILdapRule) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the rule
+
+ try {
+ newRuleInst.init(mProcessor, substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ mProcessor.getRuleInsts().put(id, newRuleInst);
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_RULE_INST_REP", id));
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void addPublisherPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // is the manager id unique?
+ if (mProcessor.getPublisherPlugins().containsKey((Object) id)) {
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_PLUGIN_ID", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ String classPath = req.getParameter(Constants.PR_PUBLISHER_CLASS);
+
+ if (classPath == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req),"CMS_LDAP_SRVLT_NULL_CLASS"), null, resp);
+ return;
+ }
+
+ IConfigStore destStore = null;
+
+ destStore = mConfig.getSubStore(
+ mAuth.getId() + ".publish.publisher");
+ IConfigStore instancesConfig = destStore.getSubStore("impl");
+
+ // Does the class exist?
+ Class newImpl = null;
+
+ try {
+ newImpl = Class.forName(classPath);
+ } catch (ClassNotFoundException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ } catch (IllegalArgumentException e) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_NO_CLASS"), null, resp);
+ return;
+ }
+
+ // is the class an ILdapPublisher?
+ try {
+ if (ILdapPublisher.class.isAssignableFrom(newImpl) == false) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+ } catch (NullPointerException e) { // unlikely, only if newImpl null.
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_CLASS", classPath), null, resp);
+ return;
+ }
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put(Constants.PR_PUBLISHER_CLASS, classPath);
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // add publisher to registry.
+ PublisherPlugin plugin = new PublisherPlugin(id, classPath);
+
+ mProcessor.getPublisherPlugins().put(id, plugin);
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_PUB_PLUG_ADDED", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void addPublisherInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (!isValidID(id)) {
+ sendResponse(ERROR, "Invalid ID '" + id + "'",
+ null, resp);
+ return;
+ }
+
+ if (mProcessor.getPublisherInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get required parameters
+ String implname = req.getParameter(
+ Constants.PR_PUBLISHER_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+
+ // check if implementation exists.
+ PublisherPlugin plugin =
+ (PublisherPlugin) mProcessor.getPublisherPlugins().get(
+ implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EPublisherPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_PLUGIN_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getPublisherDefaultParams(implname);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId() + ".publish.publisher");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String val = null;
+
+ if (index == -1) {
+ val = req.getParameter(kv);
+ } else {
+ val = req.getParameter(kv.substring(0, index));
+ }
+ if (val == null) {
+ if (index == -1) {
+ substore.put(kv, "");
+ } else {
+ substore.put(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ } else {
+ if (index == -1) {
+ substore.put(kv, val);
+ } else {
+ substore.put(kv.substring(0, index),
+ val);
+ }
+ }
+ }
+ }
+ substore.put("pluginName", implname);
+
+ // Instantiate an object for this implementation
+ String className = plugin.getClassPath();
+ ILdapPublisher publisherInst = null;
+
+ try {
+ publisherInst = (ILdapPublisher) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the publisher
+ try {
+ publisherInst.init(substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ instancesConfig.removeSubStore(id);
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // inited and commited ok. now add manager instance to list.
+ mProcessor.getPublisherInsts().put(id, new PublisherProxy(true, publisherInst));
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_PUB_INST_ADDED", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_PUBLISHER_IMPL_NAME, implname);
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void listPublisherPlugins(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = mProcessor.getPublisherPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ PublisherPlugin value = (PublisherPlugin)
+ mProcessor.getPublisherPlugins().get(name);
+ // get Description
+ String c = value.getClassPath();
+ String desc = "unknown";
+
+ try {
+ ILdapPublisher lp = (ILdapPublisher)
+ Class.forName(c).newInstance();
+
+ desc = lp.getDescription();
+ } catch (Exception exp) {
+ }
+ params.add(name, value.getClassPath() + "," + desc);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ public String getPublisherPluginName(ILdapPublisher pub) {
+ IConfigStore cs = pub.getConfigStore();
+
+ try {
+ return cs.getString("pluginName", "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ private synchronized void listPublisherInsts(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String insts = null;
+ Enumeration e = mProcessor.getPublisherInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILdapPublisher value = mProcessor.getPublisherInstance(name);
+
+ if (value == null)
+ continue;
+ params.add(name, getPublisherPluginName(value) + ";visible");
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delPublisherPlugin(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does publisher exist?
+ if (mProcessor.getPublisherPlugins().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EPublisherPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_PLUGIN_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // first check if any instances from this publisher
+ // DON'T remove publisher if any instance
+ for (Enumeration e = mProcessor.getPublisherInsts().keys();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ILdapPublisher publisher =
+ mProcessor.getPublisherInstance(name);
+
+ if (id.equals(getPublisherPluginName(publisher))) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_IN_USE"), null, resp);
+ return;
+ }
+ }
+
+ // then delete this publisher
+ mProcessor.getPublisherPlugins().remove((Object) id);
+
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId() + ".publish.publisher");
+ IConfigStore instancesConfig = destStore.getSubStore("impl");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ private synchronized void delPublisherInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // prevent deletion of admin and agent.
+
+ // does publisher instance exist?
+ if (mProcessor.getPublisherInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EPublisherNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ // only remove from memory
+ // cannot shutdown because we don't keep track of whether it's
+ // being used.
+ ILdapPublisher publisherInst = mProcessor.getPublisherInstance(id);
+
+ mProcessor.getPublisherInsts().remove((Object) id);
+
+ // remove the configuration.
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId() + ".publish.publisher");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ instancesConfig.removeSubStore(id);
+ // commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * used for getting the required configuration parameters (with
+ * possible default values) for a particular plugin
+ * implementation name specified in the RS_ID. Actually, there is
+ * no logic in here to set any default value here...there's no
+ * default value for any parameter in this publishing subsystem
+ * at this point. Later, if we do have one (or some), it can be
+ * added. The interface remains the same.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException, EBaseException {
+
+ String implname = req.getParameter(Constants.RS_ID);
+
+ if (implname == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Vector configParams = mProcessor.getPublisherDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.add(Constants.PR_PUBLISHER_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ if (index == -1) {
+ params.add(kv, "");
+ } else {
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ }
+ sendResponse(0, null, params, resp);
+ return;
+ }
+
+ private synchronized void getInstConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // does publisher instance exist?
+ if (mProcessor.getPublisherInsts().containsKey(id) == false) {
+ sendResponse(ERROR,
+ new EPublisherNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_NOT_FOUND", id)).toString(),
+ null, resp);
+ return;
+ }
+
+ ILdapPublisher publisherInst = (ILdapPublisher)
+ mProcessor.getPublisherInstance(id);
+ Vector configParams = publisherInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_PUBLISHER_IMPL_NAME,
+ getPublisherPluginName(publisherInst));
+ // implName is always required so always send it.
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Modify publisher instance.
+ * This will actually create a new instance with new configuration
+ * parameters and replace the old instance, if the new instance
+ * created and initialized successfully.
+ * The old instance is left running. so this is very expensive.
+ * Restart of server recommended.
+ */
+ private synchronized void modPublisherInst(HttpServletRequest req,
+ HttpServletResponse resp, String scope)
+ throws ServletException, IOException, EBaseException {
+
+ // expensive operation.
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ //System.out.println("SRVLT_NULL_RS_ID");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // Does the manager instance exist?
+ if (!mProcessor.getPublisherInsts().containsKey((Object) id)) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ILL_INST_ID", id),
+ null, resp);
+ return;
+ }
+
+ // get new implementation (same or different.)
+ String implname = req.getParameter(Constants.PR_PUBLISHER_IMPL_NAME);
+
+ if (implname == null) {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_LDAP_SRVLT_ADD_MISSING_PARAMS"), null, resp);
+ return;
+ }
+
+ // get plugin for implementation
+ PublisherPlugin plugin =
+ (PublisherPlugin) mProcessor.getPublisherPlugins().get(implname);
+
+ if (plugin == null) {
+ sendResponse(ERROR,
+ new EPublisherPluginNotFound(CMS.getUserMessage(getLocale(req), "CMS_LDAP_PUBLISHER_PLUGIN_NOT_FOUND", implname)).toString(),
+ null, resp);
+ return;
+ }
+
+ // save old instance substore params in case new one fails.
+
+ ILdapPublisher oldinst = mProcessor.getPublisherInstance(id);
+ Vector oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+ String pubType = "";
+
+ // implName is always required so always include it it.
+ saveParams.add("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = (String) oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+ if (index > -1) {
+ if (kv.substring(0, index).equalsIgnoreCase("caObjectClass")) {
+ pubType = "cacert";
+ } else if (kv.substring(0, index).equalsIgnoreCase("crlObjectClass")) {
+ pubType = "crl";
+ }
+
+ saveParams.add(kv.substring(0, index),
+ kv.substring(index + 1));
+ }
+ }
+ }
+
+ // on to the new instance.
+
+ // remove old substore.
+
+ IConfigStore destStore =
+ mConfig.getSubStore(mAuth.getId() + ".publish.publisher");
+ IConfigStore instancesConfig = destStore.getSubStore("instance");
+
+ // get objects added and deleted
+ if (pubType.equals("cacert")) {
+ saveParams.add("caObjectClassAdded", instancesConfig.getString(id + ".caObjectClassAdded", ""));
+ saveParams.add("caObjectClassDeleted", instancesConfig.getString(id + ".caObjectClassDeleted", ""));
+ } else if (pubType.equals("crl")) {
+ saveParams.add("crlObjectClassAdded", instancesConfig.getString(id + ".crlObjectClassAdded", ""));
+ saveParams.add("crlObjectClassDeleted", instancesConfig.getString(id + ".crlObjectClassDeleted", ""));
+ }
+
+ // create new substore.
+
+ Vector configParams = mProcessor.getPublisherInstanceParams(id);
+
+ instancesConfig.removeSubStore(id);
+
+ IConfigStore substore = instancesConfig.makeSubStore(id);
+
+ substore.put("pluginName", implname);
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = (String) configParams.elementAt(i);
+ int index = kv.indexOf('=');
+ String key = kv.substring(0, index);
+ String val = req.getParameter(key);
+
+ if (val != null) {
+ substore.put(key, val);
+ }
+ }
+ }
+
+ // process any changes to the ldap object class definitions
+ if (pubType.equals("cacert")) {
+ processChangedOC(saveParams, substore, "caObjectClass");
+ substore.put("pubtype", "cacert");
+ }
+
+ if (pubType.equals("crl")) {
+ processChangedOC(saveParams, substore, "crlObjectClass");
+ substore.put("pubtype", "crl");
+ }
+
+ // Instantiate an object for new implementation
+
+ String className = plugin.getClassPath();
+ ILdapPublisher newMgrInst = null;
+
+ try {
+ newMgrInst = (ILdapPublisher) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ // cleanup
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (InstantiationException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ } catch (IllegalAccessException e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR,
+ new ELdapException(CMS.getUserMessage(getLocale(req), "CMS_LDAP_FAIL_LOAD_CLASS", className)).toString(),
+ null, resp);
+ return;
+ }
+
+ // initialize the publisher
+
+ try {
+ newMgrInst.init(substore);
+ } catch (EBaseException e) {
+ // don't commit in this case and cleanup the new substore.
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(getLocale(req)), null, resp);
+ return;
+ } catch (Throwable e) {
+ restore(instancesConfig, id, saveParams);
+ sendResponse(ERROR, e.toString(), null, resp);
+ return;
+ }
+
+ // initialized ok. commiting
+ try {
+ mConfig.commit(true);
+ } catch (EBaseException e) {
+ // clean up.
+ restore(instancesConfig, id, saveParams);
+ //System.out.println("SRVLT_FAIL_COMMIT");
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_COMMIT_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // commited ok. replace instance.
+
+ mProcessor.getPublisherInsts().put(id, new PublisherProxy(true, newMgrInst));
+
+ mProcessor.log(ILogger.LL_INFO,
+ CMS.getLogMessage("ADMIN_SRVLT_PUB_INST_REP", id));
+
+ NameValuePairs params = new NameValuePairs();
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ // convenience function - takes list1, list2. Returns what is in list1
+ // but not in list2
+ private String[] getExtras(String[] list1, String[] list2) {
+ Vector <String> extras = new Vector<String>();
+ for (int i=0; i< list1.length; i++) {
+ boolean match=false;
+ for (int j=0; j < list2.length; j++) {
+ if ((list1[i].trim()).equalsIgnoreCase(list2[j].trim())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) extras.add(list1[i].trim());
+ }
+
+ return (String[])extras.toArray(new String[extras.size()]);
+ }
+
+ // convenience function - takes list1, list2. Concatenates the two
+ // lists removing duplicates
+ private String[] joinLists(String[] list1, String[] list2) {
+ Vector <String> sum = new Vector<String>();
+ for (int i=0; i< list1.length; i++) {
+ sum.add(list1[i]);
+ }
+
+ for (int i=0; i < list2.length; i++) {
+ boolean match=false;
+ for (int j=0; j < list1.length; j++) {
+ if ((list2[i].trim()).equalsIgnoreCase(list1[j].trim())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) sum.add(list2[i].trim());
+ }
+
+ return (String[])sum.toArray(new String[sum.size()]);
+ }
+
+ // convenience funtion. Takes a string array and delimiter
+ // and returns a String with the concatenation
+ private static String join(String[] s, String delimiter) {
+ if (s.length == 0) return "";
+
+ StringBuffer buffer = new StringBuffer(s[0]);
+ if (s.length > 1) {
+ for (int i=1; i< s.length; i++) {
+ buffer.append(delimiter).append(s[i].trim());
+ }
+ }
+ return buffer.toString();
+ }
+
+ private void processChangedOC(NameValuePairs saveParams, IConfigStore newstore, String objName) {
+ String newOC = null, oldOC = null;
+ String oldAdded = null, oldDeleted = null;
+
+ try {
+ newOC = newstore.getString(objName);
+ } catch (Exception e) {
+ }
+
+ oldOC = saveParams.getValue(objName);
+ oldAdded = saveParams.getValue(objName + "Added");
+ oldDeleted = saveParams.getValue(objName + "Deleted");
+
+ if ((oldOC == null) || (newOC == null)) return;
+ if (oldOC.equalsIgnoreCase(newOC)) return;
+
+ String [] oldList = oldOC.split(",");
+ String [] newList = newOC.split(",");
+ String [] deletedList = getExtras(oldList, newList);
+ String [] addedList = getExtras(newList, oldList);
+
+ // CMS.debug("addedList = " + join(addedList, ","));
+ // CMS.debug("deletedList = " + join(deletedList, ","));
+
+ if ((addedList.length ==0) && (deletedList.length == 0))
+ return; // no changes
+
+ if (oldAdded != null) {
+ // CMS.debug("oldAdded is " + oldAdded);
+ String [] oldAddedList = oldAdded.split(",");
+ addedList = joinLists(addedList, oldAddedList);
+ }
+
+ if (oldDeleted != null) {
+ // CMS.debug("oldDeleted is " + oldDeleted);
+ String [] oldDeletedList = oldDeleted.split(",");
+ deletedList = joinLists(deletedList, oldDeletedList);
+ }
+
+ String[] addedList1 = getExtras(addedList, deletedList);
+ String[] deletedList1 = getExtras(deletedList, addedList);
+
+ //create the final strings and write to config
+ String addedListStr = join(addedList1, ",");
+ String deletedListStr = join(deletedList1, ",");
+
+ CMS.debug("processChangedOC: added list is " + addedListStr);
+ CMS.debug("processChangedOC: deleted list is " + deletedListStr);
+
+ newstore.put(objName + "Added", addedListStr);
+ newstore.put(objName + "Deleted", deletedListStr);
+ }
+
+ // convenience routine.
+ private static void restore(IConfigStore store,
+ String id, NameValuePairs saveParams) {
+ store.removeSubStore(id);
+ IConfigStore rstore = store.makeSubStore(id);
+
+ Enumeration keys = saveParams.getNames();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String value = saveParams.getValue(key);
+
+ if (value != null)
+ rstore.put(key, value);
+ }
+ }
+
+ private String dashes(int len) {
+ String dashes = "...................................................";
+
+ if (len <= 0)
+ return "";
+ String new1 = dashes.substring(0, len);
+
+ return new1;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_LDAP, level, "PublishingAdminServlet: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java
new file mode 100644
index 000000000..c5ec93f3a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java
@@ -0,0 +1,576 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequestListener;
+
+
+/**
+ * A class representings an administration servlet for Registration
+ * Authority. This servlet is responsible to serve RA
+ * administrative operations such as configuration parameter
+ * updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RAAdminServlet extends AdminServlet {
+ protected static final String PROP_ENABLED = "enabled";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private final static String INFO = "RAAdminServlet";
+ private IRegistrationAuthority mRA = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Constructs RA servlet.
+ */
+ public RAAdminServlet() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mRA = (IRegistrationAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. Each request is authenticated to
+ * the authenticate manager.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ //get all operational flags
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ //check operational flags
+ if ((op == null) || (scope == null)) {
+ sendResponse(1, "Invalid Protocol", null, resp);
+ return;
+ }
+
+ //authenticate the user
+ super.authenticate(req);
+
+ //perform services
+ try {
+ AUTHZ_RES_NAME = "certServer.ra.configuration";
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ readGeneralConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_CONNECTOR)) {
+ getConnectorConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_REQ_COMP)) {
+ getNotificationReqCompConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_REV_COMP)) {
+ getNotificationRevCompConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ)) {
+ getNotificationRIQConfig(req, resp);
+ return;
+ } else {
+ sendResponse(1, "Unknown operation", null, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GENERAL)) {
+ modifyGeneralConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_CONNECTOR)) {
+ setConnectorConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_REQ_COMP)) {
+ setNotificationReqCompConfig(req, resp);
+ return;
+ }else if (scope.equals(ScopeDef.SC_NOTIFICATION_REV_COMP)) {
+ setNotificationRevCompConfig(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_NOTIFICATION_RIQ)) {
+ setNotificationRIQConfig(req, resp);
+ return;
+ } else {
+ sendResponse(1, "Unknown operation", null, resp);
+ return;
+ }
+ }
+ } catch (Exception e) {
+ //System.out.println("XXX >>>" + e.toString() + "<<<");
+ sendResponse(1, "Unknown operation", null, resp);
+ }
+
+ return;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /*
+ * handle getting completion (cert issued) notification config info
+ */
+ private void getNotificationCompConfig(HttpServletRequest req,
+ HttpServletResponse resp, IConfigStore rc) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, rc.getString(name, ""));
+ }
+
+ params.add(Constants.PR_ENABLE,
+ rc.getString(PROP_ENABLED, Constants.FALSE));
+ //System.out.println("Send: "+params.toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getNotificationReqCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mRA.PROP_CERT_ISSUED_SUBSTORE);
+
+ getNotificationCompConfig(req, resp, rc);
+
+ }
+
+ private void getNotificationRevCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mRA.PROP_CERT_REVOKED_SUBSTORE);
+
+ getNotificationCompConfig(req, resp, rc);
+
+ }
+
+ /*
+ * handle getting request in queue notification config info
+ */
+ private void getNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mRA.PROP_REQ_IN_Q_SUBSTORE);
+
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ params.add(name, riq.getString(name, ""));
+ }
+
+ params.add(Constants.PR_ENABLE,
+ riq.getString(PROP_ENABLED, Constants.FALSE));
+ //System.out.println("Send: "+params.toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /*
+ * handle setting request in queue notification config info
+ */
+ private void setNotificationRIQConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(mRA.PROP_REQ_IN_Q_SUBSTORE);
+
+ //set rest of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String val = req.getParameter(name);
+
+ riq.putString(name, val);
+ mRA.getRequestInQListener().set(name, val);
+ }
+
+ // set enable flag
+ String enabledString = req.getParameter(Constants.PR_ENABLE);
+
+ riq.putString(PROP_ENABLED, enabledString);
+ mRA.getRequestInQListener().set(PROP_ENABLED, enabledString);
+
+ commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ /*
+ * handle setting request complete notification config info
+ */
+ private void setNotificationCompConfig(HttpServletRequest req,
+ HttpServletResponse resp, IConfigStore rc, IRequestListener thisListener) throws ServletException,
+ IOException, EBaseException {
+ //set rest of the parameters
+ Enumeration e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.PR_ENABLE))
+ continue;
+ String val = req.getParameter(name);
+
+ rc.putString(name, val);
+ thisListener.set(name, val);
+ }
+
+ // set enable flag
+ String enabledString = req.getParameter(Constants.PR_ENABLE);
+
+ rc.putString(PROP_ENABLED, enabledString);
+ thisListener.set(PROP_ENABLED, enabledString);
+
+ commit(true);
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void setNotificationReqCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mRA.PROP_CERT_ISSUED_SUBSTORE);
+
+ setNotificationCompConfig(req, resp, rc, mRA.getCertIssuedListener());
+
+ }
+
+ private void setNotificationRevCompConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore config = mRA.getConfigStore();
+ IConfigStore nc =
+ config.getSubStore(mRA.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(mRA.PROP_CERT_REVOKED_SUBSTORE);
+
+ setNotificationCompConfig(req, resp, rc, mRA.getCertRevokedListener());
+ }
+
+ private void getConnectorConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ IConfigStore raConfig = mRA.getConfigStore();
+ IConfigStore connectorConfig = raConfig.getSubStore("connector");
+ IConfigStore caConnectorConfig = null;
+
+ if (isCAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("CA");
+ } else if (isRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("RA");
+ } else if (isKRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("KRA");
+ }
+
+ /*
+ Enumeration enum = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+ while (enum.hasMoreElements()) {
+ String key = (String)enum.nextElement();
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+ if (val.equals("CA Connector"))
+ }
+ }
+ */
+
+ Enumeration enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+
+ params.add(name, caConnectorConfig.getString(name, ""));
+ }
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setConnectorConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore raConfig = mRA.getConfigStore();
+ IConfigStore connectorConfig = raConfig.getSubStore("connector");
+ IConfigStore caConnectorConfig = null;
+ // String nickname = raConfig.getString("certNickname", "");
+
+ if (isCAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("CA");
+ } else if (isRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("RA");
+ } else if (isKRAConnector(req)) {
+ caConnectorConfig = connectorConfig.getSubStore("KRA");
+ }
+
+ Enumeration enum1 = req.getParameterNames();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+/*
+ if (name.equals("nickName")) {
+ caConnectorConfig.putString(name, nickname);
+ continue;
+ }
+*/
+ caConnectorConfig.putString(name, req.getParameter(name));
+ }
+ }
+
+ commit(true);
+ sendResponse(RESTART, null, null, resp);
+ }
+
+ private boolean isCAConnector(HttpServletRequest req) {
+
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+
+ if (val.equals("Certificate Manager Connector"))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private boolean isRAConnector(HttpServletRequest req) {
+
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+
+ if (val.equals("Registration Manager Connector"))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private boolean isKRAConnector(HttpServletRequest req) {
+
+ Enumeration enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+
+ if (key.equals("RS_ID")) {
+ String val = req.getParameter(key);
+
+ if (val.equals("Data Recovery Manager Connector"))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+ }
+
+ //reading the RA general information
+ private void readGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ /*
+ ISubsystem eeGateway =
+ SubsystemRegistry.getInstance().get("eeGateway");
+ String value = "false";
+ if (eeGateway != null) {
+ IConfigStore eeConfig = eeGateway.getConfigStore();
+ if (eeConfig != null)
+ value = eeConfig.getString("enabled", "true");
+ }
+ params.add(Constants.PR_EE_ENABLED, value);
+ */
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ //mdify RA General Information
+ private void modifyGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ /*
+ ISubsystem eeGateway =
+ SubsystemRegistry.getInstance().get("eeGateway");
+ IConfigStore eeConfig = null;
+ if (eeGateway != null)
+ eeConfig = eeGateway.getConfigStore();
+
+ Enumeration enum = req.getParameterNames();
+ while (enum.hasMoreElements()) {
+ String key = (String)enum.nextElement();
+ if (key.equals(Constants.PR_EE_ENABLED)) {
+ if (eeConfig != null)
+ eeConfig.putString("enabled",
+ req.getParameter(Constants.PR_EE_ENABLED));
+ }
+ }
+
+ */
+ sendResponse(RESTART, null, null, resp);
+ commit(true);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java
new file mode 100644
index 000000000..78d88c9b3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java
@@ -0,0 +1,362 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.registry.*;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.profile.*;
+
+/**
+ * This implements the administration servlet for registry subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RegistryAdminServlet extends AdminServlet {
+ public final static String PROP_AUTHORITY = "authority";
+
+ private final static String INFO = "RegistryAdminServlet";
+ private final static String PW_PASSWORD_CACHE_ADD =
+ "PASSWORD_CACHE_ADD";
+
+ public final static String PROP_PREDICATE = "predicate";
+ private IAuthority mAuthority = null;
+ private IPluginRegistry mRegistry = null;
+
+ // These will be moved to PolicyResources
+ public static String INVALID_POLICY_SCOPE = "Invalid policy administration scope";
+ public static String INVALID_POLICY_IMPL_OP = "Invalid operation for policy implementation management";
+ public static String NYI = "Not Yet Implemented";
+ public static String INVALID_POLICY_IMPL_CONFIG = "Invalid policy implementation configuration";
+ public static String INVALID_POLICY_INSTANCE_CONFIG = "Invalid policy instance configuration";
+ public static String MISSING_POLICY_IMPL_ID = "Missing policy impl id in request";
+ public static String MISSING_POLICY_IMPL_CLASS = "Missing policy impl class in request";
+ public static String INVALID_POLICY_IMPL_ID = "Invalid policy impl id in request";
+ public static String MISSING_POLICY_INST_ID = "Missing policy impl id in request";
+ public static String INVALID_POLICY_INST_ID = "Invalid policy impl id in request";
+ public static String COMMA = ",";
+ public static String MISSING_POLICY_ORDERING = "Missing policy ordering";
+
+ /**
+ * Constructs administration servlet.
+ */
+ public RegistryAdminServlet() {
+ super();
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority) CMS.getSubsystem(authority);
+ mRegistry = (IPluginRegistry) CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP admin request.
+ */
+ public void service(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ super.authenticate(req);
+
+ AUTHZ_RES_NAME = "certServer.registry.configuration";
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ if (scope.equals(ScopeDef.SC_SUPPORTED_CONSTRAINTPOLICIES)) {
+ if (op.equals(OpDef.OP_READ))
+ if (!readAuthorize(req, resp))
+ return;
+ getSupportedConstraintPolicies(req, resp);
+ } else {
+ processImplMgmt(req, resp);
+ }
+ }
+
+ private boolean readAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean modifyAuthorize(HttpServletRequest req,
+ HttpServletResponse resp) throws IOException {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Process Policy Implementation Management.
+ */
+ public void processImplMgmt(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Get operation type
+ String op = req.getParameter(Constants.OP_TYPE);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (op.equals(OpDef.OP_SEARCH)) {
+ if (!readAuthorize(req, resp))
+ return;
+ listImpls(req, resp);
+ } else if (op.equals(OpDef.OP_READ)) {
+ if (!readAuthorize(req, resp))
+ return;
+ getProfileImplConfig(req, resp);
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ deleteImpl(req, resp);
+ } else if (op.equals(OpDef.OP_ADD)) {
+ if (!modifyAuthorize(req, resp))
+ return;
+ addImpl(req, resp);
+ } else
+ sendResponse(ERROR, INVALID_POLICY_IMPL_OP,
+ null, resp);
+ }
+
+ public void addImpl(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String classPath = req.getParameter(Constants.PR_POLICY_CLASS);
+ String desc = req.getParameter(Constants.PR_POLICY_DESC);
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ IPluginInfo info = mRegistry.createPluginInfo(id, desc, classPath);
+ try {
+ mRegistry.addPluginInfo(scope, id, info);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void deleteImpl(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ IPluginInfo info = mRegistry.getPluginInfo(scope, id);
+
+ if (info == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ try {
+ mRegistry.removePluginInfo(scope, id);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ /**
+ * Lists all registered profile impementations
+ */
+ public void listImpls(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ Enumeration impls = mRegistry.getIds(scope);
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (impls.hasMoreElements()) {
+ String id = (String) impls.nextElement();
+ IPluginInfo info = mRegistry.getPluginInfo(scope, id);
+
+ nvp.add(id, info.getClassName() + "," +
+ info.getDescription(getLocale(req)) + "," + info.getName(getLocale(req)));
+ }
+
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getSupportedConstraintPolicies(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException {
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ try {
+ IPluginInfo info = mRegistry.getPluginInfo("defaultPolicy", id);
+ String className = info.getClassName();
+ IPolicyDefault policyDefaultClass = (IPolicyDefault)
+ Class.forName(className).newInstance();
+
+ if (policyDefaultClass != null) {
+ Enumeration impls = mRegistry.getIds("constraintPolicy");
+
+ while (impls.hasMoreElements()) {
+ String constraintID = (String) impls.nextElement();
+ IPluginInfo constraintInfo = mRegistry.getPluginInfo(
+ "constraintPolicy", constraintID);
+ IPolicyConstraint policyConstraintClass = (IPolicyConstraint)
+ Class.forName(constraintInfo.getClassName()).newInstance();
+
+ CMS.debug("RegistryAdminServlet: getSUpportedConstraint " + constraintInfo.getClassName());
+
+ if (policyConstraintClass.isApplicable(policyDefaultClass)) {
+ CMS.debug("RegistryAdminServlet: getSUpportedConstraint isApplicable " + constraintInfo.getClassName());
+ nvp.add(constraintID, constraintInfo.getClassName() + "," +
+ constraintInfo.getDescription(getLocale(req)) + "," + constraintInfo.getName(getLocale(req)));
+ }
+ }
+ }
+ } catch (Exception ex) {
+ CMS.debug("RegistyAdminServlet: getSupportConstraintPolicies: " + ex.toString());
+ CMS.debug(ex);
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void getProfileImplConfig(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ // Get the policy impl id.
+ String id = req.getParameter(Constants.RS_ID);
+ String scope = req.getParameter(Constants.OP_SCOPE);
+
+ if (id == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ IPluginInfo info = mRegistry.getPluginInfo(scope, id);
+
+ if (info == null) {
+ sendResponse(ERROR, MISSING_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ String className = info.getClassName();
+ IConfigTemplate template = null;
+
+ try {
+ template = (IConfigTemplate)
+ Class.forName(className).newInstance();
+ } catch (Exception e) {
+ }
+ if (template != null) {
+ Enumeration names = template.getConfigNames();
+
+ if (names != null) {
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ CMS.debug("RegistryAdminServlet: getProfileImpl descriptor " + name);
+ IDescriptor desc = template.getConfigDescriptor(getLocale(req), name);
+
+ if (desc != null) {
+ try {
+ String value = getNonNull(desc.getSyntax()) + ";" + getNonNull(desc.getConstraint()) + ";" + desc.getDescription(getLocale(req)) + ";" + getNonNull(desc.getDefaultValue());
+
+ CMS.debug("RegistryAdminServlet: getProfileImpl " + value);
+ nvp.add(name, value);
+ } catch (Exception e) {
+
+ CMS.debug("RegistryAdminServlet: getProfileImpl skipped descriptor for " + name);
+ }
+ } else {
+ CMS.debug("RegistryAdminServlet: getProfileImpl cannot find descriptor for " + name);
+ }
+ }
+ }
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ protected String getNonNull(String s) {
+ if (s == null)
+ return "";
+ return s;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java
new file mode 100644
index 000000000..5ac9e0dd1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java
@@ -0,0 +1,2332 @@
+// --- 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.servlet.admin;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.InternalCertificate;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.base.*;
+
+
+/**
+ * A class representing an administration servlet for
+ * User/Group Manager. It communicates with client
+ * SDK to allow remote administration of User/Group
+ * manager.
+ *
+ * This servlet will be registered to remote
+ * administration subsystem by usrgrp manager.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UsrGrpAdminServlet extends AdminServlet {
+
+ private final static String INFO = "UsrGrpAdminServlet";
+ private final static String RES_CA_GROUP = "certServer.ca.group";
+ private final static String RES_RA_GROUP = "certServer.ra.group";
+ private final static String RES_KRA_GROUP = "certServer.kra.group";
+ private final static String RES_OCSP_GROUP = "certServer.ocsp.group";
+ private final static String RES_TKS_GROUP = "certServer.tks.group";
+ private final static String SYSTEM_USER = "$System$";
+ // private final static String RES_GROUP = "root.common.goldfish";
+
+ private final static String BACK_SLASH = "\\";
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ROLE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3";
+
+ private IUGSubsystem mMgr = null;
+
+ private IAuthzSubsystem mAuthz = null;
+
+ private static String [] mMultiRoleGroupEnforceList = null;
+ private final static String MULTI_ROLE_ENABLE= "multiroles.enable";
+ private final static String MULTI_ROLE_ENFORCE_GROUP_LIST = "multiroles.false.groupEnforceList";
+
+
+ /**
+ * Constructs User/Group manager servlet.
+ */
+ public UsrGrpAdminServlet() {
+ super();
+ mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ }
+
+ /**
+ * Initializes this servlet.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mMgr = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves incoming User/Group management request.
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ super.service(req, resp);
+
+ String scope = super.getParameter(req, Constants.OP_SCOPE);
+ String op = super.getParameter(req, Constants.OP_TYPE);
+
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_INVALID_PROTOCOL"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_PROTOCOL"),
+ null, resp);
+ return;
+ }
+
+ Locale clientLocale = super.getLocale(req);
+
+ try {
+ super.authenticate(req);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_AUTHS"));
+
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHS_FAILED"),
+ null, resp);
+ return;
+ }
+
+ // authorization
+ // temporary test before servlets are exposed with authtoken
+ /*
+ SessionContext sc = SessionContext.getContext();
+ AuthToken authToken = (AuthToken) sc.get(SessionContext.AUTH_TOKEN);
+
+ AuthzToken authzTok = null;
+ CMS.debug("UserGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CHECK_AUTHZ_SUB"));
+ // hardcoded for now .. just testing
+ try {
+ authzTok = mAuthz.authorize("DirAclAuthz", authToken, RES_GROUP, "read");
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_CALL_FAIL",e.toString()));
+ }
+ if (AuthzToken.AUTHZ_STATUS_FAIL.equals(authzTok.get(AuthzToken.TOKEN_AUTHZ_STATUS))) {
+ // audit would have been needed here if this weren't just a test...
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_AUTHS"));
+
+ sendResponse(ERROR,
+ MessageFormatter.getLocalizedString(
+ getLocale(req),
+ AdminResources.class.getName(),
+ AdminResources.SRVLT_FAIL_AUTHS),
+ null, resp);
+ return;
+ }
+ */
+
+
+ try {
+ ISubsystem subsystem = CMS.getSubsystem("ca");
+ if (subsystem != null)
+ AUTHZ_RES_NAME = RES_CA_GROUP;
+ subsystem = CMS.getSubsystem("ra");
+ if (subsystem != null)
+ AUTHZ_RES_NAME = RES_RA_GROUP;
+ subsystem = CMS.getSubsystem("kra");
+ if (subsystem != null)
+ AUTHZ_RES_NAME = RES_KRA_GROUP;
+ subsystem = CMS.getSubsystem("ocsp");
+ if (subsystem != null)
+ AUTHZ_RES_NAME = RES_OCSP_GROUP;
+ subsystem = CMS.getSubsystem("tks");
+ if (subsystem != null)
+ AUTHZ_RES_NAME = RES_TKS_GROUP;
+ if (scope != null) {
+ if (scope.equals(ScopeDef.SC_USER_TYPE)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+
+ getUserType(req, resp);
+ return;
+ }
+
+ if (op.equals(OpDef.OP_READ)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GROUPS)) {
+ findGroup(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USERS)) {
+ findUser(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USER_CERTS)) {
+ findUserCerts(req, resp, clientLocale);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_MODIFY)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GROUPS)) {
+ modifyGroup(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USERS)) {
+ modifyUser(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USER_CERTS)) {
+ modifyUserCert(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_ADD)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GROUPS)) {
+ addGroup(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USERS)) {
+ addUser(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USER_CERTS)) {
+ addUserCert(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_DELETE)) {
+ mOp = "modify";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GROUPS)) {
+ removeGroup(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USERS)) {
+ removeUser(req, resp);
+ return;
+ }
+ } else if (op.equals(OpDef.OP_SEARCH)) {
+ mOp = "read";
+ if ((mToken = super.authorize(req)) == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_AUTHZ_FAILED"),
+ null, resp);
+ return;
+ }
+ if (scope.equals(ScopeDef.SC_GROUPS)) {
+ findGroups(req, resp);
+ return;
+ } else if (scope.equals(ScopeDef.SC_USERS)) {
+ findUsers(req, resp);
+ return;
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_INVALID_OP_SCOPE"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_INVALID_OP_SCOPE"),
+ null, resp);
+ return;
+ }
+ }
+ } // if
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ sendResponse(ERROR, e.toString(getLocale(req)),
+ null, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage(" ADMIN_SRVLT_FAIL_PERFORM"));
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_PERFORM_FAILED"),
+ null, resp);
+ return;
+ }
+ }
+
+ private void getUserType(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String id = super.getParameter(req, Constants.RS_ID);
+ IUser user = mMgr.getUser(id);
+ String val = user.getUserType();
+
+ if (val == null || val.equals(""))
+ val = "noType";
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_USER_TYPE, val);
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Retrieves configuration parameters of
+ * authentication manager.
+ */
+ private synchronized void getConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ super.getConfig(mMgr.getConfigStore(), req, resp);
+ }
+
+ /**
+ * Sets configuration parameters of
+ * User/Group manager.
+ */
+ private synchronized void setConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ super.setConfig(mMgr.getConfigStore(), req, resp);
+ }
+
+ /**
+ * Lists configuration parameters.
+ */
+ private synchronized void listConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ super.listConfig(mMgr.getConfigStore(), req, resp);
+ }
+
+ /**
+ * Searches for users in LDAP directory. List uids only
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ */
+ private synchronized void findUsers(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ NameValuePairs params = new NameValuePairs();
+
+ Enumeration e = null;
+
+ try {
+ e = mMgr.listUsers("*");
+ } catch (Exception ex) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ int i = 0;
+
+ while (e.hasMoreElements()) {
+ IUser user = (IUser) e.nextElement();
+
+ if (i > 0) {
+ sb.append(";");
+ sb.append(user.getUserID());
+ sb.append(":");
+ sb.append(user.getFullName());
+ } else {
+ sb.append(user.getUserID());
+ sb.append(":");
+ sb.append(user.getFullName());
+ }
+ i++;
+ }
+ params.add("userInfo", sb.toString());
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * List user information. Certificates covered in a separate
+ * protocol for findUserCerts(). List of group memberships are
+ * also provided.
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ */
+ private synchronized void findUser(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ NameValuePairs params = new NameValuePairs();
+
+ IUser user = null;
+
+ try {
+ user = mMgr.getUser(id);
+ } catch (Exception e) {
+ e.printStackTrace();
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ if (user != null) {
+ params.add(Constants.PR_USER_FULLNAME, user.getFullName());
+ params.add(Constants.PR_USER_EMAIL, user.getEmail());
+ params.add(Constants.PR_USER_PHONE, user.getPhone());
+ params.add(Constants.PR_USER_STATE, user.getState());
+
+ // get list of groups, and get a list of those that this
+ // uid belongs to
+ Enumeration e = null;
+
+ try {
+ e = mMgr.findGroups("*");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ StringBuffer grpString = new StringBuffer();
+
+ while (e.hasMoreElements()) {
+ IGroup group = (IGroup) e.nextElement();
+
+ if (group.isMember(id) == true) {
+ if (grpString.length()!=0) {
+ grpString.append(",");
+ }
+ grpString.append(group.getGroupID());
+ }
+ }
+
+ params.add(Constants.PR_USER_GROUP, grpString.toString());
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_USER_NOT_EXIST"), null, resp);
+ return;
+ }
+
+ /**
+ * List user certificate(s)
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ */
+ private synchronized void findUserCerts(HttpServletRequest req,
+ HttpServletResponse resp, Locale clientLocale)
+ throws ServletException,
+ IOException, EBaseException {
+
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ NameValuePairs params = new NameValuePairs();
+
+ IUser user = null;
+
+ try {
+ user = mMgr.getUser(id);
+ } catch (Exception e) {
+ e.printStackTrace();
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_USER_NOT_EXIST"), null, resp);
+ return;
+ }
+
+ if (user == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_USER_NOT_EXIST"), null, resp);
+ return;
+ }
+
+ X509Certificate[] certs =
+ (X509Certificate[]) user.getX509Certificates();
+
+ if (certs != null) {
+ for (int i = 0; i < certs.length; i++) {
+ ICertPrettyPrint print = CMS.getCertPrettyPrint(certs[i]);
+
+ // add base64 encoding
+ String base64 = CMS.getEncodedCert(certs[i]);
+
+ // pretty print certs
+ params.add(getCertificateString(certs[i]),
+ print.toString(clientLocale) + "\n" + base64);
+ }
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ /**
+ * Converts certificate into string format.
+ */
+ protected String getCertificateString(X509Certificate cert) {
+ if (cert == null) {
+ return null;
+ }
+
+ // note that it did not represent a certificate fully
+ return cert.getVersion() + ";" + cert.getSerialNumber().toString() +
+ ";" + cert.getIssuerDN() + ";" + cert.getSubjectDN();
+ }
+
+ /**
+ * Searchess for groups in LDAP server
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#group
+ */
+ private synchronized void findGroups(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ Enumeration e = null;
+
+ try {
+ e = mMgr.listGroups("*");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ while (e.hasMoreElements()) {
+ IGroup group = (IGroup) e.nextElement();
+ String desc = group.getDescription();
+
+ if (desc != null) {
+ params.add(group.getGroupID(), desc);
+ } else {
+ params.add(group.getGroupID(), "");
+ }
+ }
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * finds a group
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ */
+ private synchronized void findGroup(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ Enumeration e = null;
+
+ try {
+ e = mMgr.findGroups(id);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ if (e.hasMoreElements()) {
+ IGroup group = (IGroup) e.nextElement();
+
+ params.add(Constants.PR_GROUP_GROUP, group.getGroupID());
+ params.add(Constants.PR_GROUP_DESC,
+ group.getDescription());
+
+ Enumeration members = group.getMemberNames();
+ StringBuffer membersString = new StringBuffer();
+
+ if (members != null) {
+ while (members.hasMoreElements()) {
+ if (membersString.length()!=0) {
+ membersString.append(", ");
+ }
+
+ String mn = (String) members.nextElement();
+
+ membersString.append(mn);
+ }
+ }
+
+ params.add(Constants.PR_GROUP_USER, membersString.toString());
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST"));
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_GROUP_NOT_EXIST"), null, resp);
+ return;
+
+ }
+ }
+
+ /**
+ * Adds a new user to LDAP server
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addUser(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ if (id.indexOf(BACK_SLASH) != -1) {
+ // backslashes (BS) are not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_RS_ID_BS"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_RS_ID_BS"),
+ null, resp);
+ return;
+ }
+
+ if (id.equals(SYSTEM_USER)) {
+ // backslashes (BS) are not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_SPECIAL_ID", id));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_SPECIAL_ID", id),
+ null, resp);
+ return;
+ }
+
+ IUser user = mMgr.createUser(id);
+ String fname = super.getParameter(req, Constants.PR_USER_FULLNAME);
+
+ if ((fname == null) || (fname.length() == 0)) {
+ String msg = CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED_1", "full name");
+
+ log(ILogger.LL_FAILURE, msg);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, msg, null, resp);
+ return;
+ } else
+ user.setFullName(fname);
+
+ String email = super.getParameter(req, Constants.PR_USER_EMAIL);
+
+ if (email != null) {
+ user.setEmail(email);
+ } else {
+ user.setEmail("");
+ }
+ String pword = super.getParameter(req, Constants.PR_USER_PASSWORD);
+
+ if (pword != null && !pword.equals("")) {
+ IPasswordCheck passwdCheck = CMS.getPasswordChecker();
+
+ if (!passwdCheck.isGoodPassword(pword)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EUsrGrpException(passwdCheck.getReason(pword));
+
+ //UsrGrpResources.BAD_PASSWD);
+ }
+
+ user.setPassword(pword);
+ } else {
+ user.setPassword("");
+ }
+ String phone = super.getParameter(req, Constants.PR_USER_PHONE);
+
+ if (phone != null) {
+ user.setPhone(phone);
+ } else {
+ user.setPhone("");
+ }
+ String userType = super.getParameter(req, Constants.PR_USER_TYPE);
+
+ if (userType != null) {
+ user.setUserType(userType);
+ } else {
+ user.setUserType("");
+ }
+ String userState = super.getParameter(req, Constants.PR_USER_STATE);
+
+ if (userState != null) {
+ user.setState(userState);
+ }
+
+ try {
+ mMgr.addUser(user);
+
+ // if group is specified, add user to group
+ String groupName = super.getParameter(req,
+ Constants.PR_USER_GROUP);
+
+ if (groupName != null) {
+ Enumeration e = null;
+
+ try {
+ e = mMgr.findGroups(groupName);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED"), null, resp);
+ return;
+ }
+
+ if (e.hasMoreElements()) {
+ IGroup group = (IGroup) e.nextElement();
+
+ group.addMemberName(id);
+ try {
+ mMgr.modifyGroup(group);
+ } catch (Exception ex) {
+ log(ILogger.LL_FAILURE, ex.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED"), null, resp);
+ return;
+ }
+ }
+ // for audit log
+ SessionContext sContext = SessionContext.getContext();
+ String adminId = (String) sContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT,
+ new Object[] {adminId, id, groupName}
+ );
+ }
+
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (EUsrGrpException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ if (user.getUserID() == null) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED_1", "uid"), null, resp);
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED"), null, resp);
+ }
+ return;
+ } catch (LDAPException e) {
+ String errMsg = "addUser()" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_ADD_USER_FAIL", e.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED"), null, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_ADD_FAILED"), null, resp);
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Adds a certificate to a user
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addUserCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IUser user = mMgr.createUser(id);
+ String certS = super.getParameter(req, Constants.PR_USER_CERT);
+ String certsString = Cert.stripBrackets(certS);
+
+ // no cert is a success
+ if (certsString == null) {
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ // only one cert added per operation
+ X509Certificate certs[] = null;
+
+ // Base64 decode cert
+
+ try {
+ byte bCert[] = (byte[]) (com.netscape.osutil.OSUtil.AtoB(certsString));
+ X509Certificate cert = new X509CertImpl(bCert);
+
+ certs = new X509Certificate[1];
+ certs[0] = cert;
+ } catch (CertificateException e) {
+ // cert chain direction
+ boolean assending = true;
+
+ // could it be a pkcs7 blob?
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_IS_PK_BLOB"));
+ byte p7Cert[] = (byte[]) (com.netscape.osutil.OSUtil.AtoB(certsString));
+
+ try {
+ CryptoManager manager = CryptoManager.getInstance();
+
+ PKCS7 pkcs7 = new PKCS7(p7Cert);
+
+ X509Certificate p7certs[] = pkcs7.getCertificates();
+
+ if (p7certs.length == 0) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_ERROR"), null, resp);
+ return;
+ }
+ // fix for 370099 - cert ordering can not be assumed
+ // find out the ordering ...
+ certs = new X509Certificate[p7Cert.length];
+
+ // self-signed and alone? take it. otherwise test
+ // the ordering
+ if (p7certs[0].getSubjectDN().toString().equals(
+ p7certs[0].getIssuerDN().toString()) &&
+ (p7certs.length == 1)) {
+ certs[0] = p7certs[0];
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_SINGLE_CERT_IMPORT"));
+ } else if (p7certs[0].getIssuerDN().toString().equals(p7certs[1].getSubjectDN().toString())) {
+ certs[0] = p7certs[0];
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CERT_CHAIN_ACEND_ORD"));
+ } else if (p7certs[1].getIssuerDN().toString().equals(p7certs[0].getSubjectDN().toString())) {
+ assending = false;
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CERT_CHAIN_DESC_ORD"));
+ certs[0] = p7certs[p7certs.length - 1];
+ } else {
+ // not a chain, or in random order
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CERT_BAD_CHAIN"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_ERROR"), null, resp);
+ return;
+ }
+
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CHAIN_STORED_DB", String.valueOf(p7certs.length)));
+
+ int j = 0;
+ int jBegin = 0;
+ int jEnd = 0;
+
+ if (assending == true) {
+ jBegin = 1;
+ jEnd = p7certs.length;
+ } else {
+ jBegin = 0;
+ jEnd = p7certs.length - 1;
+ }
+ // store the chain into cert db, except for the user cert
+ for (j = jBegin; j < jEnd; j++) {
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_CERT_IN_CHAIN", String.valueOf(j), String.valueOf(p7certs[j].getSubjectDN())));
+ org.mozilla.jss.crypto.X509Certificate leafCert =
+ null;
+
+ leafCert =
+ manager.importCACertPackage(p7certs[j].getEncoded());
+
+ if (leafCert == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_LEAF_CERT_NULL"));
+ } else {
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_LEAF_CERT_NON_NULL"));
+ }
+
+ if (leafCert instanceof InternalCertificate) {
+ ((InternalCertificate) leafCert).setSSLTrust(
+ InternalCertificate.VALID_CA |
+ InternalCertificate.TRUSTED_CA |
+ InternalCertificate.TRUSTED_CLIENT_CA);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NOT_INTERNAL_CERT",
+ String.valueOf(p7certs[j].getSubjectDN())));
+ }
+ }
+
+ /*
+ } catch (CryptoManager.UserCertConflictException ex) {
+ // got a "user cert" in the chain, most likely the CA
+ // cert of this instance, which has a private key. Ignore
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_PKS7_IGNORED", ex.toString()));
+ */
+ } catch (Exception ex) {
+ //-----
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_CERT_ERROR", ex.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_ERROR"), null, resp);
+ return;
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_CERT_O_ERROR", e.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_O_ERROR"), null, resp);
+ return;
+ }
+
+ try {
+ CMS.debug("UsrGrpAdminServlet: " + CMS.getLogMessage("ADMIN_SRVLT_BEFORE_VALIDITY"));
+ certs[0].checkValidity(); // throw exception if fails
+
+ user.setX509Certificates(certs);
+ mMgr.addUserCert(user);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+
+ } catch (CertificateExpiredException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_ADD_CERT_EXPIRED",
+ String.valueOf(certs[0].getSubjectDN())));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_EXPIRED"), null, resp);
+ return;
+ } catch (CertificateNotYetValidException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_CERT_NOT_YET_VALID",
+ String.valueOf(certs[0].getSubjectDN())));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_CERT_NOT_YET_VALID"), null, resp);
+ return;
+
+ } catch (LDAPException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ if (e.getLDAPResultCode() ==
+ LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_USER_CERT_EXISTS"), null, resp);
+ } else {
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_MOD_FAILED"), null, resp);
+ }
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_MOD_FAILED"), null, resp);
+ return;
+ }
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Removes a certificate for a user
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * In this method, "certDN" is actually a combination of version,
+ * serialNumber, issuerDN, and SubjectDN.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modifyUserCert(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IUser user = mMgr.createUser(id);
+ String certDN = super.getParameter(req, Constants.PR_USER_CERT);
+
+ // no certDN is a success
+ if (certDN == null) {
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ }
+
+ user.setCertDN(certDN);
+ try {
+ mMgr.removeUserCert(user);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_MOD_FAILED"), null, resp);
+ return;
+ }
+ // } catch( EBaseException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * removes a user. user not removed if belongs to any group
+ * (Administrators should remove the user from "uniquemember" of
+ * any group he/she belongs to before trying to remove the user
+ * itself.
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void removeUser(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+ boolean mustDelete = false;
+ int index = 0;
+
+ if ((index = id.lastIndexOf(":true")) != -1) {
+ id = id.substring(0, index);
+ mustDelete = true;
+ }
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+ // get list of groups, and see if uid belongs to any
+ Enumeration e = null;
+
+ try {
+ e = mMgr.findGroups("*");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_INTERNAL_ERROR"), null, resp);
+ return;
+ }
+
+ while (e.hasMoreElements()) {
+ IGroup group = (IGroup) e.nextElement();
+
+ if (group.isMember(id) == true) {
+ if (mustDelete) {
+ mMgr.removeUserFromGroup(group, id);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_FAIL_USER_RMV_G"),
+ null, resp);
+ return;
+ }
+ }
+ }
+
+ // comes out clean of group membership...now remove user
+ try {
+ mMgr.removeUser(id);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (Exception ex) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_SRVLT_FAIL_USER_RMV"), null, resp);
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * Adds a new group in local scope.
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#group
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void addGroup(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IGroup group = mMgr.createGroup(id);
+ String members = super.getParameter(req,
+ Constants.PR_GROUP_USER);
+ String desc = super.getParameter(req,
+ Constants.PR_GROUP_DESC);
+
+ if (desc != null) {
+ group.set("description", (Object) desc);
+ } else {
+ group.set("description", (Object) "");
+ }
+
+ if (members != null) {
+ StringTokenizer st = new StringTokenizer(members, ",");
+
+ while (st.hasMoreTokens()) {
+ group.addMemberName(st.nextToken());
+ }
+ }
+
+ // allow adding a group with no members
+ try {
+ mMgr.addGroup(group);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_GROUP_ADD_FAILED"),
+ null, resp);
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * removes a group
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#group
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void removeGroup(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ // if fails, let the exception fall through
+ mMgr.removeGroup(id);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ /**
+ * modifies a group
+ * <P>
+ *
+ * last person of the super power group "Certificate
+ * Server Administrators" can never be removed.
+ * <P>
+ *
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#group
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modifyGroup(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IGroup group = mMgr.createGroup(id);
+
+ String desc = super.getParameter(req,
+ Constants.PR_GROUP_DESC);
+
+ if (desc != null) {
+ group.set("description", (Object) desc);
+ }
+
+ String members = super.getParameter(req, Constants.PR_GROUP_USER);
+
+ if (members != null) {
+ StringTokenizer st = new StringTokenizer(members, ",");
+
+ String groupName = group.getName();
+ boolean multiRole = true;
+
+ try {
+ multiRole = mConfig.getBoolean(MULTI_ROLE_ENABLE);
+ } catch (Exception eee) {
+ }
+ while (st.hasMoreTokens()) {
+ String memberName = st.nextToken();
+ if (multiRole) {
+ group.addMemberName(memberName);
+ } else {
+ if( isGroupInMultiRoleEnforceList(groupName)) {
+ if (!isDuplicate(groupName, memberName)) {
+ group.addMemberName(memberName);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DUPLICATE_ROLES", memberName));
+ }
+ } else {
+ group.addMemberName(memberName);
+ }
+ }
+ }
+ }
+
+ // allow adding a group with no members, except "Certificate
+ // Server Administrators"
+ try {
+ mMgr.modifyGroup(group);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_GROUP_MODIFY_FAILED"),
+ null, resp);
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private boolean isGroupInMultiRoleEnforceList(String groupName)
+ {
+ String groupList = null;
+
+ if (groupName == null || groupName.equals("")) {
+ return true;
+ }
+ if (mMultiRoleGroupEnforceList == null) {
+ try {
+ groupList = mConfig.getString(MULTI_ROLE_ENFORCE_GROUP_LIST);
+ } catch (Exception e) {
+ }
+
+ if (groupList != null && !groupList.equals("")) {
+ mMultiRoleGroupEnforceList = groupList.split(",");
+ for (int j = 0 ; j < mMultiRoleGroupEnforceList.length; j++) {
+ mMultiRoleGroupEnforceList[j] = mMultiRoleGroupEnforceList[j].trim();
+ }
+ }
+ }
+
+ if (mMultiRoleGroupEnforceList == null)
+ return true;
+
+ for (int i = 0; i < mMultiRoleGroupEnforceList.length; i++) {
+ if (groupName.equals(mMultiRoleGroupEnforceList[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isDuplicate(String groupName, String memberName) {
+ Enumeration groups = null;
+
+ // Let's not mess with users that are already a member of this group
+ boolean isMember = false;
+ try {
+ isMember = mMgr.isMemberOf(memberName,groupName);
+ } catch (Exception e) {
+ }
+
+ if (isMember == true) {
+ return false;
+ }
+ try {
+ groups = mMgr.listGroups("*");
+ while (groups.hasMoreElements()) {
+ IGroup group = (IGroup) groups.nextElement();
+ String name = group.getName();
+ Enumeration g = mMgr.findGroups(name);
+ IGroup g1 = (IGroup) g.nextElement();
+ if (!name.equals(groupName)) {
+ if (isGroupInMultiRoleEnforceList(name)) {
+ Enumeration members = g1.getMemberNames();
+ while (members.hasMoreElements()) {
+ String m1 = (String) members.nextElement();
+ if (m1.equals(memberName))
+ return true;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Modifies an existing user in local scope.
+ * <P>
+ *
+ * Request/Response Syntax:
+ * http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring
+ * role information (anything under users/groups)
+ * </ul>
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @exception ServletException a servlet error has occurred
+ * @exception IOException an input/output error has occurred
+ * @exception EBaseException an error has occurred
+ */
+ private synchronized void modifyUser(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ //get id first
+ String id = super.getParameter(req, Constants.RS_ID);
+
+ if (id == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_NULL_RS_ID"),
+ null, resp);
+ return;
+ }
+
+ IUser user = mMgr.createUser(id);
+ String fname = super.getParameter(req, Constants.PR_USER_FULLNAME);
+
+ if ((fname == null) || (fname.length() == 0)) {
+ String msg =
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_MOD_FAILED", "full name");
+
+ log(ILogger.LL_FAILURE, msg);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR, msg, null, resp);
+ return;
+ } else
+ user.setFullName(fname);
+
+ String email = super.getParameter(req, Constants.PR_USER_EMAIL);
+
+ if (email != null) {
+ user.setEmail(email);
+ }
+ String pword = super.getParameter(req, Constants.PR_USER_PASSWORD);
+
+ if ((pword != null) && (!pword.equals(""))) {
+ IPasswordCheck passwdCheck = CMS.getPasswordChecker();
+
+ if (!passwdCheck.isGoodPassword(pword)) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ throw new EUsrGrpException(passwdCheck.getReason(pword));
+
+ //UsrGrpResources.BAD_PASSWD);
+ }
+
+ user.setPassword(pword);
+ }
+ String phone = super.getParameter(req, Constants.PR_USER_PHONE);
+
+ if (phone != null) {
+ user.setPhone(phone);
+ }
+
+ String userState = super.getParameter(req, Constants.PR_USER_STATE);
+ if (userState != null) {
+ user.setState(userState);
+ }
+
+ try {
+ mMgr.modifyUser(user);
+ NameValuePairs params = new NameValuePairs();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(SUCCESS, null, params, resp);
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ sendResponse(ERROR,
+ CMS.getUserMessage(getLocale(req), "CMS_USRGRP_USER_MOD_FAILED"), null, resp);
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (IOException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams(req));
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ // } catch( ServletException eAudit3 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditParams( req ) );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit3;
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_USRGRP,
+ level, "UsrGrpAdminServlet: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
new file mode 100644
index 000000000..e4008ab8d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
@@ -0,0 +1,2235 @@
+// --- 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.servlet.base;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.certsrv.base.SessionContext;
+import java.io.*;
+import java.util.*;
+import java.util.Locale;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Date;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletException;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.util.DerValue;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.ObjectIdentifier;
+
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.ssl.SSLSecurityStatus;
+import org.w3c.dom.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequest;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+import java.net.SocketException;
+
+
+/**
+ * This is the base class of all CS servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSServlet extends HttpServlet {
+ // servlet init params
+ // xxxx todo:Should enforce init param value checking!
+ public final static String SUCCESS = "0";
+ public final static String FAILURE = "1";
+ public final static String AUTH_FAILURE = "2";
+
+ public final static String PROP_ID = "ID";
+ public final static String PROP_AUTHORITY = "authority";
+ public final static String PROP_AUTHMGR = "AuthMgr";
+ public final static String PROP_CLIENTAUTH = "GetClientCert";
+ public final static String PROP_RESOURCEID = "resourceID";
+
+ public final static String AUTHZ_SRC_LDAP = "ldap";
+ public final static String AUTHZ_SRC_TYPE = "sourceType";
+ public final static String AUTHZ_CONFIG_STORE = "authz";
+ public final static String AUTHZ_SRC_XML = "web.xml";
+ public final static String PROP_AUTHZ_MGR = "AuthzMgr";
+ public final static String PROP_ACL = "ACLinfo";
+ public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz";
+ public final static String AUTHZ_MGR_LDAP = "DirAclAuthz";
+ private final static String FAILED = "1";
+ private final static String HDR_LANG = "accept-language";
+
+ // final error message - if error and exception templates don't work
+ // send out this text string directly to output.
+
+ public final static String PROP_FINAL_ERROR_MSG = "finalErrorMsg";
+ public final static String ERROR_MSG_TOKEN = "$ERROR_MSG";
+ public final static String FINAL_ERROR_MSG =
+ "<HTML>\n" +
+ "<BODY BGCOLOR=white>\n" +
+ "<P>\n" +
+ "The Certificate System has encountered " +
+ "an unrecoverable error.\n" +
+ "<P>\n" +
+ "Error Message:<BR>\n" +
+ "<I>$ERROR_MSG</I>\n" +
+ "<P>\n" +
+ "Please contact your local administrator for assistance.\n" +
+ "</BODY>\n" +
+ "</HTML>\n";
+
+ // properties from configuration.
+
+ protected final static String
+ PROP_UNAUTHORIZED_TEMPLATE = "unauthorizedTemplate";
+ protected final static String
+ UNAUTHORIZED_TEMPLATE = "/GenUnauthorized.template";
+ protected final static String
+ PROP_SUCCESS_TEMPLATE = "successTemplate";
+ protected final static String
+ SUCCESS_TEMPLATE = "/GenSuccess.template";
+ protected final static String
+ PROP_PENDING_TEMPLATE = "pendingTemplate";
+ protected final static String
+ PENDING_TEMPLATE = "/GenPending.template";
+ protected final static String
+ PROP_SVC_PENDING_TEMPLATE = "svcpendingTemplate";
+ protected final static String
+ SVC_PENDING_TEMPLATE = "/GenSvcPending.template";
+ protected final static String
+ PROP_REJECTED_TEMPLATE = "rejectedTemplate";
+ protected final static String
+ REJECTED_TEMPLATE = "/GenRejected.template";
+ protected final static String
+ PROP_ERROR_TEMPLATE = "errorTemplate";
+ protected final static String
+ ERROR_TEMPLATE = "/GenError.template";
+ protected final static String
+ PROP_EXCEPTION_TEMPLATE = "unexpectedErrorTemplate";
+ protected final static String
+ EXCEPTION_TEMPLATE = "/GenUnexpectedError.template";
+
+ private final static String
+ PROP_UNAUTHOR_TEMPLATE_FILLER = "unauthorizedTemplateFiller";
+ protected final static String
+ PROP_SUCCESS_TEMPLATE_FILLER = "successTemplateFiller";
+ private final static String
+ PROP_ERROR_TEMPLATE_FILLER = "errorTemplateFiller";
+ private final static String
+ PROP_PENDING_TEMPLATE_FILLER = "pendingTemplateFiller";
+ private final static String
+ PROP_SVC_PENDING_TEMPLATE_FILLER = "svcpendingTemplateFiller";
+ private final static String
+ PROP_REJECTED_TEMPLATE_FILLER = "rejectedTemplateFiller";
+ private final static String
+ PROP_EXCEPTION_TEMPLATE_FILLER = "exceptionTemplateFiller";
+
+ protected final static String RA_AGENT_GROUP = "Registration Manager Agents";
+ protected final static String CA_AGENT_GROUP = "Certificate Manager Agents";
+ protected final static String KRA_AGENT_GROUP = "Data Recovery Manager Agents";
+ protected final static String OCSP_AGENT_GROUP = "Online Certificate Status Manager Agents";
+ protected final static String TRUSTED_RA_GROUP = "Trusted Managers";
+ protected final static String ADMIN_GROUP = "Administrators";
+
+ // default http params NOT to save in request.(config values added to list )
+ private static final String
+ PROP_DONT_SAVE_HTTP_PARAMS = "dontSaveHttpParams";
+ private static final String[]
+ DONT_SAVE_HTTP_PARAMS = { "pwd", "password", "passwd",
+ "challengePassword", "confirmChallengePassword" };
+
+ // default http headers to save in request. (config values added to list)
+ private static final String
+ PROP_SAVE_HTTP_HEADERS = "saveHttpHeaders";
+ private static final String[]
+ SAVE_HTTP_HEADERS = { "accept-language", "user-agent", };
+
+ // request prefixes to distinguish from other request attributes.
+ public static final String
+ PFX_HTTP_HEADER = "HTTP_HEADER";
+ public static final String
+ PFX_HTTP_PARAM = "HTTP_PARAM";
+ public static final String
+ PFX_AUTH_TOKEN = "AUTH_TOKEN";
+
+ /* input http params */
+ protected final static String AUTHMGR_PARAM = "authenticator";
+
+ /* fixed credential passed to auth managers */
+ protected final static String CERT_AUTH_CRED = "sslClientCert";
+
+ public static final String CERT_ATTR =
+ "javax.servlet.request.X509Certificate";
+
+ // members.
+
+ protected boolean mRenderResult = true;
+ protected String mFinalErrorMsg = FINAL_ERROR_MSG;
+ protected Hashtable mTemplates = new Hashtable();
+
+ protected ServletConfig mServletConfig = null;
+ protected ServletContext mServletContext = null;
+ private CMSFileLoader mFileLoader = null;
+
+ protected Vector mDontSaveHttpParams = new Vector();
+ protected Vector mSaveHttpHeaders = new Vector();
+
+ protected String mId = null;
+ protected IConfigStore mConfig = null;
+
+ // the authority, RA, CA, KRA this servlet is serving.
+ protected IAuthority mAuthority = null;
+ protected IRequestQueue mRequestQueue = null;
+
+ // system logger.
+ protected ILogger mLogger = CMS.getLogger();
+ protected int mLogCategory = ILogger.S_OTHER;
+ private MessageDigest mSHADigest = null;
+
+ protected String mGetClientCert = "false";
+ protected String mAuthMgr = null;
+ protected IAuthzSubsystem mAuthz = null;
+
+ protected String mAclMethod = null;
+ protected String mAuthzResourceName = null;
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ protected String mOutputTemplatePath = null;
+ private IUGSubsystem mUG = (IUGSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTH_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTH_SUCCESS_3";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4";
+ private final static String LOGGING_SIGNED_AUDIT_ROLE_ASSUME =
+ "LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3";
+
+ public CMSServlet() {
+ }
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ httpReqHash.put(name, req.getParameter(name));
+ }
+ return httpReqHash;
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ mId = sc.getInitParameter(PROP_ID);
+
+ try {
+ mAclMethod = Utils.initializeAuthz(sc, mAuthz, mId);
+ } catch (ServletException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ throw e;
+ }
+
+ mConfig = CMS.getConfigStore().getSubStore(CMSGateway.PROP_CMSGATEWAY);
+ mServletConfig = sc;
+ mServletContext = sc.getServletContext();
+ mFileLoader = new CMSFileLoader();
+
+ mGetClientCert = sc.getInitParameter(PROP_CLIENTAUTH);
+ mAuthMgr = sc.getInitParameter(PROP_AUTHMGR);
+ mAuthzResourceName = sc.getInitParameter(PROP_RESOURCEID);
+ mOutputTemplatePath = sc.getInitParameter("templatePath");
+
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+ if (mAuthority != null)
+ mRequestQueue = mAuthority.getRequestQueue();
+
+ // set default templates.
+ setDefaultTemplates(sc);
+
+ // for logging to the right authority category.
+ if (mAuthority == null) {
+ mLogCategory = ILogger.S_OTHER;
+ } else {
+ if (mAuthority instanceof ICertificateAuthority)
+ mLogCategory = ILogger.S_CA;
+ else if (mAuthority instanceof IRegistrationAuthority)
+ mLogCategory = ILogger.S_RA;
+ else if (mAuthority instanceof IKeyRecoveryAuthority)
+ mLogCategory = ILogger.S_KRA;
+ else
+ mLogCategory = ILogger.S_OTHER;
+ }
+
+ try {
+ // get final error message.
+ // used when templates can't even be loaded.
+ String eMsg =
+ sc.getInitParameter(PROP_FINAL_ERROR_MSG);
+
+ if (eMsg != null)
+ mFinalErrorMsg = eMsg;
+
+ // get any configured templates.
+ Enumeration templs = mTemplates.elements();
+
+ while (templs.hasMoreElements()) {
+ CMSLoadTemplate templ = (CMSLoadTemplate) templs.nextElement();
+
+ if (templ == null || templ.mPropName == null) {
+ continue;
+ }
+ String tName =
+ sc.getInitParameter(templ.mPropName);
+
+ if (tName != null)
+ templ.mTemplateName = tName;
+ String fillerName =
+ sc.getInitParameter(templ.mFillerPropName);
+
+ if (fillerName != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillerName);
+
+ if (filler != null)
+ templ.mFiller = filler;
+ }
+ }
+
+ // get http params NOT to store in a IRequest and
+ // get http headers TO store in a IRequest.
+ getDontSaveHttpParams(sc);
+ getSaveHttpHeaders(sc);
+ } catch (Exception e) {
+ // should never occur since we provide defaults above.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CONF_TEMP_PARAMS",
+ e.toString()));
+ throw new ServletException(e.toString());
+ }
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CONF_TEMP_PARAMS",
+ e.toString()));
+ throw new ServletException(e.toString());
+ }
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public String getAuthMgr() {
+ return mAuthMgr;
+ }
+
+ public boolean isClientCertRequired() {
+ if (mGetClientCert != null && mGetClientCert.equals("true"))
+ return true;
+ else
+ return false;
+ }
+
+ public void outputHttpParameters(HttpServletRequest httpReq)
+ {
+ CMS.debug("CMSServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = (String)paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("CMSServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("CMSServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+ public void service(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException, IOException {
+
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CS server is not ready to serve.");
+
+ try {
+ if (CMS.getConfigStore().getBoolean("useThreadNaming", false)) {
+ String currentName = Thread.currentThread().getName();
+
+ Thread.currentThread().setName(currentName + "-" + httpReq.getServletPath());
+ }
+ } catch (Exception e) {
+ }
+
+ httpReq.setCharacterEncoding("UTF-8");
+
+ if (CMS.debugOn()) {
+ outputHttpParameters(httpReq);
+ }
+ CMS.debug("CMSServlet: " + mId + " start to service.");
+ String className = this.getClass().getName();
+
+ // get a cms request
+ CMSRequest cmsRequest = newCMSRequest();
+
+ // set argblock
+ cmsRequest.setHttpParams(CMS.createArgBlock("http-request-params",toHashtable(httpReq)));
+
+ // set http request
+ cmsRequest.setHttpReq(httpReq);
+
+ // set http response
+ cmsRequest.setHttpResp(httpResp);
+
+ // set servlet config.
+ cmsRequest.setServletConfig(mServletConfig);
+
+ // set servlet context.
+ cmsRequest.setServletContext(mServletContext);
+
+ IArgBlock httpArgs = cmsRequest.getHttpParams();
+
+ // authenticator value from http overrides the value in web.xml.
+ String authMgr_http = httpArgs.getValueAsString(AUTHMGR_PARAM, null);
+
+ if (authMgr_http != null) {
+ mAuthMgr = authMgr_http;
+ } else {
+ mAuthMgr = mServletConfig.getInitParameter(PROP_AUTHMGR);
+ }
+
+ // process request.
+ ICommandQueue iCommandQueue = CMS.getCommandQueue();
+
+ try {
+ if (iCommandQueue.registerProcess((Object) cmsRequest, (Object) this) == false) {
+ cmsRequest.setStatus(CMSRequest.ERROR);
+ renderResult(cmsRequest);
+ SessionContext.releaseContext();
+ return;
+ }
+ long startTime = CMS.getCurrentDate().getTime();
+ process(cmsRequest);
+ renderResult(cmsRequest);
+ Date endDate = CMS.getCurrentDate();
+ long endTime = endDate.getTime();
+ if (CMS.debugOn()) {
+ CMS.debug(CMS.DEBUG_INFORM, "CMSServlet: curDate=" + endDate + " id=" + mId + " time=" + (endTime - startTime));
+ }
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ } catch (EBaseException e) {
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ // ByteArrayOutputStream os = new ByteArrayOutputStream(); for debugging only
+ // PrintStream ps = new PrintStream(os);
+ //e.printStackTrace(ps);
+ log(e.toString());
+ renderException(cmsRequest, e);
+ } catch (Exception ex) {
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(os);
+
+ ex.printStackTrace(ps);
+ log(os.toString());
+ renderFinalError(cmsRequest, ex);
+ }
+
+ // destroy SessionContext
+ SessionContext.releaseContext();
+
+ return;
+ }
+
+ /**
+ * Create a new CMSRequest object. This should be overriden by servlets
+ * implementing different types of request
+ * @return a new CMSRequest object
+ */
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * process an HTTP request. Servlets must override this with their
+ * own implementation
+ * @throws EBaseException if the servlet was unable to satisfactorily
+ * process the request
+ */
+ protected void process(CMSRequest cmsRequest)
+ throws EBaseException
+ {
+ }
+
+
+ /**
+ * Output a template.
+ * If an error occurs while outputing the template the exception template
+ * is used to display the error.
+ *
+ * @param cmsReq the CS request
+ */
+ protected void renderResult(CMSRequest cmsReq)
+ throws IOException {
+
+ if (!mRenderResult)
+ return;
+ Integer status = cmsReq.getStatus();
+
+ CMSLoadTemplate ltempl = (CMSLoadTemplate) mTemplates.get(status);
+
+ if (ltempl == null || ltempl.mTemplateName == null) {
+ // result is previously outputed.
+ return;
+ }
+ ICMSTemplateFiller filler = ltempl.mFiller;
+
+ renderTemplate(cmsReq, ltempl.mTemplateName, filler);
+ }
+
+ private static final String PRESERVED = "preserved";
+ public static final String TEMPLATE_NAME = "templateName";
+
+ protected void outputArgBlockAsXML(XMLObject xmlObj, Node parent,
+ String argBlockName, IArgBlock argBlock)
+ {
+ Node argBlockContainer = xmlObj.createContainer(parent, argBlockName);
+
+ if (argBlock != null) {
+ Enumeration names = argBlock.getElements();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ String val = argBlock.get(name).toString();
+ val = val.trim();
+ xmlObj.addItemToContainer(argBlockContainer, name, val);
+ }
+ }
+ }
+
+ protected void outputXML(HttpServletResponse httpResp, CMSTemplateParams params)
+ {
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("xml");
+ outputArgBlockAsXML(xmlObj, root, "header", params.getHeader());
+ outputArgBlockAsXML(xmlObj, root, "fixed", params.getFixed());
+
+ Enumeration records = params.queryRecords();
+ Node recordsNode = xmlObj.createContainer(root, "records");
+ if (records != null) {
+ while (records.hasMoreElements()) {
+ IArgBlock record = (IArgBlock) records.nextElement();
+ outputArgBlockAsXML(xmlObj, recordsNode, "record", record);
+ }
+ }
+
+ byte[] cb = xmlObj.toByteArray();
+ OutputStream os = httpResp.getOutputStream();
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(cb.length);
+ os.write(cb);
+ os.flush();
+ } catch (Exception e) {
+ CMS.debug("failed in outputing XML " + e);
+ }
+ }
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {
+ try {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+
+ Locale[] locale = new Locale[1];
+ CMSTemplate template =
+ getTemplate(templateName, cmsReq.getHttpReq(), locale);
+ CMSTemplateParams templateParams = null;
+
+ if (filler != null) {
+ templateParams = filler.getTemplateParams(
+ cmsReq, mAuthority, locale[0], null);
+ }
+
+ // just output arg blocks as XML
+ CMS.debug("CMSServlet.java: renderTemplate");
+ String xmlOutput = cmsReq.getHttpReq().getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ CMS.debug("CMSServlet.java: xml parameter detected, returning xml");
+ outputXML(cmsReq.getHttpResp(), templateParams);
+ return;
+ }
+
+ if (httpParams != null) {
+ String httpTemplateName =
+ httpParams.getValueAsString(
+ TEMPLATE_NAME, null);
+
+ if (httpTemplateName != null) {
+ templateName = httpTemplateName;
+ }
+ }
+
+ if (templateParams == null)
+ templateParams = new CMSTemplateParams(null, null);
+
+ // #359630
+ // inject preserved http parameter into the template
+ if (httpParams != null) {
+ String preserved = httpParams.getValueAsString(
+ PRESERVED, null);
+
+ if (preserved != null) {
+ IArgBlock fixed = templateParams.getFixed();
+
+ if (fixed != null) {
+ fixed.set(PRESERVED, preserved);
+ }
+ }
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ template.renderOutput(bos, templateParams);
+ cmsReq.getHttpResp().setContentType("text/html");
+ cmsReq.getHttpResp().setContentLength(bos.size());
+ bos.writeTo(cmsReq.getHttpResp().getOutputStream());
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_TEMPLATE", templateName, e.toString()));
+ renderException(cmsReq,
+ new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ return;
+ }
+ }
+
+ /**
+ * Output exception (unexpected error) template
+ * This is different from other templates in that if an exception occurs
+ * while rendering the exception a message is printed out directly.
+ * If the message gets an error an IOException is thrown.
+ * In others if an exception occurs while rendering the template the
+ * exception template (this) is called.
+ * <p>
+ * @param cmsReq the CS request to pass to template filler if any.
+ * @param e the unexpected exception
+ */
+ protected void renderException(CMSRequest cmsReq, EBaseException e)
+ throws IOException {
+ try {
+ Locale[] locale = new Locale[1];
+ CMSLoadTemplate loadTempl =
+ (CMSLoadTemplate) mTemplates.get(CMSRequest.EXCEPTION);
+ CMSTemplate template = getTemplate(loadTempl.mTemplateName,
+ cmsReq.getHttpReq(), locale);
+ ICMSTemplateFiller filler = loadTempl.mFiller;
+ CMSTemplateParams templateParams = null;
+
+ // When an exception occurs the exit is non-local which probably
+ // will leave the requestStatus value set to something other
+ // than CMSRequest.EXCEPTION, so force the requestStatus to
+ // EXCEPTION since it must be that if we're here.
+ cmsReq.setStatus(CMSRequest.EXCEPTION);
+
+ if (filler != null) {
+ templateParams = filler.getTemplateParams(
+ cmsReq, mAuthority, locale[0], e);
+ }
+ if (templateParams == null) {
+ templateParams = new CMSTemplateParams(null, CMS.createArgBlock());
+ }
+ if (e != null) {
+ templateParams.getFixed().set(
+ ICMSTemplateFiller.EXCEPTION, e.toString(locale[0]));
+ }
+
+ // just output arg blocks as XML
+ CMS.debug("CMSServlet.java: renderTemplate");
+ String xmlOutput = cmsReq.getHttpReq().getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ CMS.debug("CMSServlet.java: xml parameter detected, returning xml");
+ outputXML(cmsReq.getHttpResp(), templateParams);
+ return;
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ template.renderOutput(bos, templateParams);
+ cmsReq.getHttpResp().setContentType("text/html");
+ cmsReq.getHttpResp().setContentLength(bos.size());
+ bos.writeTo(cmsReq.getHttpResp().getOutputStream());
+ } catch (Exception ex) {
+ renderFinalError(cmsReq, ex);
+ }
+ }
+
+ public void renderFinalError(CMSRequest cmsReq, Exception ex)
+ throws IOException {
+ // this template is the last resort for all other unexpected
+ // errors in other templates so we can only output text.
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ // replace $ERRORMSG with exception message if included.
+ String finalErrMsg = mFinalErrorMsg;
+ int tokenIdx = mFinalErrorMsg.indexOf(ERROR_MSG_TOKEN);
+
+ if (tokenIdx != -1) {
+ finalErrMsg =
+ mFinalErrorMsg.substring(0, tokenIdx) +
+ ex.toString() +
+ mFinalErrorMsg.substring(
+ tokenIdx + ERROR_MSG_TOKEN.length());
+ }
+ out.println(finalErrMsg);
+ return;
+ }
+
+ /**
+ * Invalidates a SSL Session. So client auth will happen again.
+ */
+ protected static void invalidateSSLSession(HttpServletRequest httpReq) {
+ SSLSocket s = null;
+
+ /*
+ try {
+ s = (SSLSocket) ((HTTPRequest) httpReq).getConnection().getSocket();
+ } catch (ClassCastException e) {
+ CMS.getLogger().log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_SSL_NO_INVALIDATE"));
+ // ignore.
+ return;
+ }
+ try {
+ s.invalidateSession();
+ s.resetHandshake();
+ }catch (SocketException se) {
+ }
+ */
+ return;
+ }
+
+ /**
+ * construct a authentication credentials to pass into authentication
+ * manager.
+ */
+ public static AuthCredentials getAuthCreds(
+ IAuthManager authMgr, IArgBlock argBlock, X509Certificate clientCert)
+ throws EBaseException {
+ // get credentials from http parameters.
+ String[] reqCreds = authMgr.getRequiredCreds();
+ AuthCredentials creds = new AuthCredentials();
+
+ for (int i = 0; i < reqCreds.length; i++) {
+ String reqCred = reqCreds[i];
+
+ if (reqCred.equals(IAuthManager.CRED_SSL_CLIENT_CERT)) {
+ // cert could be null;
+ creds.set(reqCred, new X509Certificate[] { clientCert}
+ );
+ } else {
+ String value = argBlock.getValueAsString(reqCred);
+
+ creds.set(reqCred, value); // value could be null;
+ }
+ }
+ // Inserted by bskim
+ creds.setArgBlock(argBlock);
+ // Insert end
+ return creds;
+ }
+
+ /**
+ * get ssl client authenticated certificate
+ */
+ protected X509Certificate
+ getSSLClientCertificate(HttpServletRequest httpReq)
+ throws EBaseException {
+
+ X509Certificate cert = null;
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_INFO,
+ CMS.getLogMessage("CMSGW_GETTING_SSL_CLIENT_CERT"));
+
+ // iws60 support Java Servlet Spec V2.2, attribute
+ // javax.servlet.request.X509Certificate now contains array
+ // of X509Certificates instead of one X509Certificate object
+ X509Certificate[] allCerts = (X509Certificate[]) httpReq.getAttribute(CERT_ATTR);
+
+ if (allCerts == null || allCerts.length == 0) {
+ throw new EBaseException("You did not provide a valid certificate for this operation");
+ }
+
+ cert = allCerts[0];
+
+ if (cert == null) {
+ // just don't have a cert.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL"));
+ return null;
+ }
+
+ // convert to sun's x509 cert interface.
+ try {
+ byte[] certEncoded = cert.getEncoded();
+
+ cert = new X509CertImpl(certEncoded);
+ } catch (CertificateEncodingException e) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_ENCODE", e.getMessage()));
+ return null;
+ } catch (CertificateException e) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_DECODE", e.getMessage()));
+ return null;
+ }
+ return cert;
+ }
+
+ /**
+ * get a template based on result status.
+ */
+ protected CMSTemplate getTemplate(
+ String templateName, HttpServletRequest httpReq, Locale[] locale)
+ throws EBaseException, IOException {
+ // this converts to system dependent file seperator char.
+ if (mServletConfig == null) {
+ CMS.debug( "CMSServlet:getTemplate() - mServletConfig is null!" );
+ return null;
+ }
+ if (mServletConfig.getServletContext() == null) {
+ }
+ if (templateName == null) {
+ }
+ String realpath =
+ mServletConfig.getServletContext().getRealPath("/" + templateName);
+
+ if (realpath == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_FIND_TEMPLATE", templateName));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ File realpathFile = new File(realpath);
+ File templateFile =
+ getLangFile(httpReq, realpathFile, locale);
+ String charSet = httpReq.getCharacterEncoding();
+
+ if (charSet == null) {
+ charSet = "UTF8";
+ }
+ CMSTemplate template =
+ (CMSTemplate) mFileLoader.getCMSFile(templateFile, charSet);
+
+ return template;
+ }
+
+ /**
+ * log according to authority category.
+ */
+ protected void log(int event, int level, String msg) {
+ mLogger.log(event, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ /**
+ * get http parameters not to save from configuration.
+ */
+ protected void getDontSaveHttpParams(ServletConfig sc) {
+ String dontSaveParams = null;
+
+ try {
+ for (int i = 0; i < DONT_SAVE_HTTP_PARAMS.length; i++) {
+ mDontSaveHttpParams.addElement(DONT_SAVE_HTTP_PARAMS[i]);
+ }
+ dontSaveParams = sc.getInitParameter(
+ PROP_DONT_SAVE_HTTP_PARAMS);
+ if (dontSaveParams != null) {
+ StringTokenizer params =
+ new StringTokenizer(dontSaveParams, ",");
+
+ while (params.hasMoreTokens()) {
+ String param = params.nextToken();
+
+ mDontSaveHttpParams.addElement(param);
+ }
+ }
+ } catch (Exception e) {
+ // should never happen
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_NO_CONFIG_VALUE", PROP_DONT_SAVE_HTTP_PARAMS, e.toString()));
+ // default just in case.
+ for (int i = 0; i < DONT_SAVE_HTTP_PARAMS.length; i++) {
+ mDontSaveHttpParams.addElement(DONT_SAVE_HTTP_PARAMS[i]);
+ }
+ return;
+ }
+ }
+
+ /**
+ * get http headers to save from configuration.
+ */
+ protected void getSaveHttpHeaders(ServletConfig sc) {
+ try {
+ // init save http headers. default will always be saved.
+ for (int i = 0; i < SAVE_HTTP_HEADERS.length; i++) {
+ mSaveHttpHeaders.addElement(SAVE_HTTP_HEADERS[i]);
+ }
+
+ // now get from config file if there's more.
+ String saveHeaders =
+ sc.getInitParameter(PROP_SAVE_HTTP_HEADERS);
+
+ if (saveHeaders != null) {
+ StringTokenizer headers =
+ new StringTokenizer(saveHeaders, ",");
+
+ while (headers.hasMoreTokens()) {
+ String hdr = headers.nextToken();
+
+ mSaveHttpHeaders.addElement(hdr);
+ }
+ }
+ } catch (Exception e) {
+ // should never happen
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_NO_CONFIG_VALUE", PROP_SAVE_HTTP_HEADERS, e.toString()));
+ return;
+ }
+ }
+
+ /**
+ * save http headers in a IRequest.
+ */
+ protected void saveHttpHeaders(
+ HttpServletRequest httpReq, IRequest req)
+ throws EBaseException {
+ Hashtable headers = new Hashtable();
+ Enumeration hdrs = mSaveHttpHeaders.elements();
+
+ while (hdrs.hasMoreElements()) {
+ String hdr = (String) hdrs.nextElement();
+ String val = httpReq.getHeader(hdr);
+
+ if (val != null) {
+ headers.put(hdr, val);
+ }
+ }
+ req.setExtData(IRequest.HTTP_HEADERS, headers);
+ }
+
+ /**
+ * save http headers in a IRequest.
+ */
+ protected void saveHttpParams(
+ IArgBlock httpParams, IRequest req) {
+ Hashtable saveParams = new Hashtable();
+
+ Enumeration names = httpParams.elements();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ Enumeration params = mDontSaveHttpParams.elements();
+ boolean dosave = true;
+
+ while (params.hasMoreElements()) {
+ String param = (String) params.nextElement();
+
+ if (name.equalsIgnoreCase(param)) {
+ dosave = false;
+ break;
+ }
+ }
+ if (dosave) {
+ // kmccarth
+ // fear not - service() calls toHashtable() which only
+ // retrieves string values.
+ // TODO - when we can use JDK5 features we should typecast
+ // the params until they get here
+ saveParams.put(name, httpParams.get(name));
+ }
+ }
+ req.setExtData(IRequest.HTTP_PARAMS, saveParams);
+ }
+
+ /**
+ * handy routine for getting a cert record given a serial number.
+ */
+ protected ICertRecord getCertRecord(BigInteger serialNo) {
+ if (mAuthority == null ||
+ !(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_NON_CERT_AUTH"));
+ return null;
+ }
+ ICertificateRepository certdb =
+ (ICertificateRepository) ((ICertificateAuthority) mAuthority).getCertificateRepository();
+
+ if (certdb == null) {
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_CERT_DB_NULL", mAuthority.toString()));
+ return null;
+ }
+ ICertRecord certRecord = null;
+
+ try {
+ certRecord = certdb.readCertificateRecord(serialNo);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CERT_REC", serialNo.toString(16), e.toString()));
+ return null;
+ }
+ return certRecord;
+ }
+
+ /**
+ * handy routine for validating if a cert is from this CA.
+ * mAuthority must be a CA.
+ */
+ protected boolean isCertFromCA(X509Certificate cert) {
+ BigInteger serialno = cert.getSerialNumber();
+ X509CertImpl certInDB = (X509CertImpl) getX509Certificate(serialno);
+
+ if (certInDB == null || !certInDB.equals(cert))
+ return false;
+ return true;
+ }
+
+ /**
+ * handy routine for checking if a list of certs is from this CA.
+ * mAuthortiy must be a CA.
+ */
+ protected boolean areCertsFromCA(X509Certificate[] certs) {
+ for (int i = certs.length - 1; i >= 0; i--) {
+ if (!isCertFromCA(certs[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * handy routine for getting a certificate from the certificate
+ * repository. mAuthority must be a CA.
+ */
+ protected X509Certificate getX509Certificate(BigInteger serialNo) {
+ if (mAuthority == null ||
+ !(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_CERT_AUTH"));
+ return null;
+ }
+ ICertificateRepository certdb =
+ (ICertificateRepository) ((ICertificateAuthority) mAuthority).getCertificateRepository();
+
+ if (certdb == null) {
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_CERT_DB_NULL", mAuthority.toString()));
+ return null;
+ }
+ X509Certificate cert = null;
+
+ try {
+ cert = certdb.getX509Certificate(serialNo);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CERT_REC", serialNo.toString(16), e.toString()));
+ return null;
+ }
+ return cert;
+ }
+
+ /**
+ * instantiate a new filler from a class name,
+ * @return null if can't be instantiated, new instance otherwise.
+ */
+ protected ICMSTemplateFiller newFillerObject(String fillerClass) {
+ ICMSTemplateFiller filler = null;
+
+ try {
+ filler = (ICMSTemplateFiller)
+ Class.forName(fillerClass).newInstance();
+ } catch (Exception e) {
+ if ((e instanceof RuntimeException)) {
+ throw (RuntimeException) e;
+ } else {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_CANT_LOAD_FILLER", fillerClass, e.toString()));
+ return null;
+ }
+ }
+ return filler;
+ }
+
+ /**
+ * set default templates.
+ * subclasses can override, and should override at least the success
+ * template
+ */
+ protected void setDefaultTemplates(ServletConfig sc) {
+ // Subclasses should override these for diff templates and params in
+ // their constructors.
+ // Set a template name to null to not use these standard ones.
+ // When template name is set to null nothing will be displayed.
+ // Servlet is assumed to have rendered its own output.
+ // The only exception is the unexpected error template where the
+ // default one will always be used if template name is null.
+ String successTemplate = null;
+ String errorTemplate = null;
+ String unauthorizedTemplate = null;
+ String pendingTemplate = null;
+ String svcpendingTemplate = null;
+ String rejectedTemplate = null;
+ String unexpectedErrorTemplate = null;
+
+ String gateway = sc.getInitParameter("interface");
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+ if (authority == null) {
+ authority = sc.getInitParameter("authorityId");
+ }
+
+ try {
+ successTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (successTemplate == null) {
+ successTemplate = SUCCESS_TEMPLATE;
+ if (gateway != null)
+ //successTemplate = "/"+gateway+successTemplate;
+ successTemplate = "/"+gateway+successTemplate;
+ }
+
+ errorTemplate = sc.getInitParameter(
+ PROP_ERROR_TEMPLATE);
+ if (errorTemplate == null) {
+ errorTemplate = ERROR_TEMPLATE;
+ if (gateway != null)
+ //errorTemplate = "/"+gateway+errorTemplate;
+ errorTemplate = "/"+gateway+errorTemplate;
+ }
+
+ unauthorizedTemplate = sc.getInitParameter(
+ PROP_UNAUTHORIZED_TEMPLATE);
+ if (unauthorizedTemplate == null) {
+ unauthorizedTemplate = UNAUTHORIZED_TEMPLATE;
+ if (gateway != null)
+ //unauthorizedTemplate = "/"+gateway+unauthorizedTemplate;
+ unauthorizedTemplate = "/"+gateway+unauthorizedTemplate;
+ }
+
+ pendingTemplate = sc.getInitParameter(
+ PROP_PENDING_TEMPLATE);
+ if (pendingTemplate == null) {
+ pendingTemplate = PENDING_TEMPLATE;
+ if (gateway != null)
+ //pendingTemplate = "/"+gateway+pendingTemplate;
+ pendingTemplate = "/"+gateway+pendingTemplate;
+ }
+
+ svcpendingTemplate = sc.getInitParameter(
+ PROP_SVC_PENDING_TEMPLATE);
+ if (svcpendingTemplate == null) {
+ svcpendingTemplate = SVC_PENDING_TEMPLATE;
+ if (gateway != null)
+ //svcpendingTemplate = "/"+gateway+svcpendingTemplate;
+ svcpendingTemplate = "/"+gateway+svcpendingTemplate;
+ }
+
+ rejectedTemplate = sc.getInitParameter(
+ PROP_REJECTED_TEMPLATE);
+ if (rejectedTemplate == null) {
+ rejectedTemplate = REJECTED_TEMPLATE;
+ if (gateway != null)
+ //rejectedTemplate = "/"+gateway+rejectedTemplate;
+ rejectedTemplate = "/"+gateway+rejectedTemplate;
+ }
+
+ unexpectedErrorTemplate = sc.getInitParameter(
+ PROP_EXCEPTION_TEMPLATE);
+ if (unexpectedErrorTemplate == null) {
+ unexpectedErrorTemplate = EXCEPTION_TEMPLATE;
+ if (gateway != null)
+ //unexpectedErrorTemplate = "/"+gateway+unexpectedErrorTemplate;
+ unexpectedErrorTemplate = "/"+gateway+unexpectedErrorTemplate;
+ }
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
+ mId));
+ }
+
+ mTemplates.put(
+ CMSRequest.UNAUTHORIZED,
+ new CMSLoadTemplate(
+ PROP_UNAUTHORIZED_TEMPLATE, PROP_UNAUTHOR_TEMPLATE_FILLER,
+ unauthorizedTemplate, null));
+ mTemplates.put(
+ CMSRequest.SUCCESS,
+ new CMSLoadTemplate(
+ PROP_SUCCESS_TEMPLATE, PROP_SUCCESS_TEMPLATE_FILLER,
+ successTemplate, new GenSuccessTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.PENDING,
+ new CMSLoadTemplate(
+ PROP_PENDING_TEMPLATE, PROP_PENDING_TEMPLATE_FILLER,
+ pendingTemplate, new GenPendingTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.SVC_PENDING,
+ new CMSLoadTemplate(
+ PROP_SVC_PENDING_TEMPLATE, PROP_SVC_PENDING_TEMPLATE_FILLER,
+ svcpendingTemplate, new GenSvcPendingTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.REJECTED,
+ new CMSLoadTemplate(
+ PROP_REJECTED_TEMPLATE, PROP_REJECTED_TEMPLATE_FILLER,
+ rejectedTemplate, new GenRejectedTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.ERROR,
+ new CMSLoadTemplate(
+ PROP_ERROR_TEMPLATE, PROP_ERROR_TEMPLATE_FILLER,
+ errorTemplate, new GenErrorTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.EXCEPTION,
+ new CMSLoadTemplate(
+ PROP_EXCEPTION_TEMPLATE, PROP_EXCEPTION_TEMPLATE_FILLER,
+ unexpectedErrorTemplate, new GenUnexpectedErrorTemplateFiller()));
+ }
+
+ /**
+ * handy routine to check if client is navigator based on user-agent.
+ */
+ public static boolean clientIsNav(HttpServletRequest httpReq) {
+ String useragent = httpReq.getHeader("user-agent");
+
+ if (useragent.startsWith("Mozilla") &&
+ useragent.indexOf("MSIE") == -1)
+ return true;
+ return false;
+ }
+
+ /**
+ * handy routine to check if client is msie based on user-agent.
+ */
+ public static boolean clientIsMSIE(HttpServletRequest httpReq) {
+ String useragent = httpReq.getHeader("user-agent");
+
+ if (useragent != null && useragent.indexOf("MSIE") != -1)
+ return true;
+ return false;
+ }
+
+ /**
+ * handy routine to check if client is cartman based on hidden http input
+ * set using cartman JS. (no other way to tell)
+ */
+ private static String CMMF_RESPONSE = "cmmfResponse";
+ public static boolean doCMMFResponse(IArgBlock httpParams) {
+ if (httpParams.getValueAsBoolean(CMMF_RESPONSE, false))
+ return true;
+ else
+ return false;
+ }
+
+ private static final String IMPORT_CERT = "importCert";
+ private static final String IMPORT_CHAIN = "importCAChain";
+ private static final String IMPORT_CERT_MIME_TYPE = "importCertMimeType";
+ // default mime type
+ private static final String
+ NS_X509_USER_CERT = "application/x-x509-user-cert";
+ private static final String
+ NS_X509_EMAIL_CERT = "application/x-x509-email-cert";
+
+ // CMC mime types
+ public static final String
+ SIMPLE_ENROLLMENT_REQUEST = "application/pkcs10";
+ public static final String
+ SIMPLE_ENROLLMENT_RESPONSE = "application/pkcs7-mime";
+ public static final String
+ FULL_ENROLLMENT_REQUEST = "application/pkcs7-mime";
+ public static final String
+ FULL_ENROLLMENT_RESPONSE = "application/pkcs7-mime";
+
+ /**
+ * handy routine to check if client want full enrollment response
+ */
+ public static String FULL_RESPONSE = "fullResponse";
+ public static boolean doFullResponse(IArgBlock httpParams) {
+ if (httpParams.getValueAsBoolean(FULL_RESPONSE, false))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * @return false if import cert directly set to false.
+ * @return true if import cert directly is true and import cert.
+ */
+ protected boolean checkImportCertToNav(
+ HttpServletResponse httpResp, IArgBlock httpParams, X509CertImpl cert)
+ throws EBaseException {
+ if (!httpParams.getValueAsBoolean(IMPORT_CERT, false)) {
+ return false;
+ }
+ boolean importCAChain =
+ httpParams.getValueAsBoolean(IMPORT_CHAIN, true);
+ // XXX Temporary workaround because of problem with passing Mime type
+ boolean emailCert =
+ httpParams.getValueAsBoolean("emailCert", false);
+ String importMimeType = (emailCert) ?
+ httpParams.getValueAsString(IMPORT_CERT_MIME_TYPE, NS_X509_EMAIL_CERT) :
+ httpParams.getValueAsString(IMPORT_CERT_MIME_TYPE, NS_X509_USER_CERT);
+
+ // String importMimeType =
+ // httpParams.getValueAsString(
+ // IMPORT_CERT_MIME_TYPE, NS_X509_USER_CERT);
+ importCertToNav(httpResp, cert, importMimeType, importCAChain);
+ return true;
+ }
+
+ /**
+ * handy routine to import cert to old navigator in nav mime type.
+ */
+ public void importCertToNav(
+ HttpServletResponse httpResp, X509CertImpl cert,
+ String contentType, boolean importCAChain)
+ throws EBaseException {
+ ServletOutputStream out = null;
+ byte[] encoding = null;
+
+ CMS.debug("CMSServlet: importCertToNav " +
+ "contentType=" + contentType + " " +
+ "importCAChain=" + importCAChain);
+ try {
+ out = httpResp.getOutputStream();
+ // CA chain.
+ if (importCAChain) {
+ CertificateChain caChain = null;
+ X509Certificate[] caCerts = null;
+ PKCS7 p7 = null;
+
+ caChain = ((ICertAuthority) mAuthority).getCACertChain();
+ caCerts = caChain.getChain();
+
+ // set user + CA cert chain in pkcs7
+ X509CertImpl[] userChain =
+ new X509CertImpl[caCerts.length + 1];
+
+ userChain[0] = cert;
+ int m = 1, n = 0;
+
+ for (; n < caCerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) caCerts[n];
+
+ /*
+ System.out.println(
+ m+"th Cert "+userChain[m].toString());
+ */
+ }
+ p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos, false);
+ encoding = bos.toByteArray();
+ CMS.debug("CMServlet: return P7 " + CMS.BtoA(encoding));
+ } else {
+ encoding = cert.getEncoded();
+ CMS.debug("CMServlet: return Certificate " + CMS.BtoA(encoding));
+ }
+ httpResp.setContentType(contentType);
+ out.write(encoding);
+ } catch (IOException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_RET_CERT_IMPORT_ERR", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_RETURNING_CERT"));
+ } catch (CertificateEncodingException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_ENCODED_IMP_CERT", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ }
+
+ protected static void saveAuthToken(IAuthToken token, IRequest req) {
+ if (token != null && req != null)
+ req.setExtData(IRequest.AUTH_TOKEN, token);
+
+ // # 56230 - expose auth token parameters to the policy predicate
+ if (token != null && req != null) {
+ Enumeration e = token.getElements();
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ String[] x1 = token.getInStringArray(n);
+ if (x1 != null) {
+ for (int i = 0; i < x1.length; i++) {
+ CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n +
+ "(" + i + ")=" + x1[i]);
+ req.setExtData(IRequest.AUTH_TOKEN + "-" + n + "(" + i + ")",
+ x1[i]);
+ }
+ } else {
+ String x = token.getInString(n);
+ if (x != null) {
+ CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n + "=" + x);
+ req.setExtData(IRequest.AUTH_TOKEN + "-" + n, x);
+ }
+ }
+ } // while
+ } // if
+ }
+
+ protected IAuthToken getAuthToken(IRequest req) {
+ return req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+ }
+
+ protected static boolean connectionIsSSL(HttpServletRequest httpReq) {
+ return httpReq.isSecure();
+ }
+
+ /**
+ * handy routine for getting agent's relative path
+ */
+ protected String getRelPath(IAuthority authority) {
+ if (authority instanceof ICertificateAuthority)
+ return "ca/";
+ else if (authority instanceof IRegistrationAuthority)
+ return "ra/";
+ else if (authority instanceof IKeyRecoveryAuthority)
+ return "kra/";
+ else
+ return "/";
+ }
+
+ /**
+ * A system certificate such as the CA signing certificate
+ * should not be allowed to delete.
+ * The main purpose is to avoid revoking the self signed
+ * CA certificate accidentially.
+ */
+ protected boolean isSystemCertificate(BigInteger serialNo) {
+ if (!(mAuthority instanceof ICertificateAuthority)) {
+ return false;
+ }
+ X509Certificate caCert =
+ ((ICertificateAuthority)mAuthority).getCACert();
+ if (caCert != null) {
+ /* only check this if we are self-signed */
+ if (caCert.getSubjectDN().equals(caCert.getIssuerDN())) {
+ if (caCert.getSerialNumber().equals(serialNo)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * make a CRL entry from a serial number and revocation reason.
+ * @return a RevokedCertImpl that can be entered in a CRL.
+ */
+ protected RevokedCertImpl formCRLEntry(
+ BigInteger serialNo, RevocationReason reason)
+ throws EBaseException {
+ CRLReasonExtension reasonExt = new CRLReasonExtension(reason);
+ CRLExtensions crlentryexts = new CRLExtensions();
+
+ try {
+ crlentryexts.set(CRLReasonExtension.NAME, reasonExt);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CRL_REASON", reason.toString(), e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_CRLREASON"));
+ }
+ RevokedCertImpl crlentry =
+ new RevokedCertImpl(serialNo, CMS.getCurrentDate(), crlentryexts);
+
+ return crlentry;
+ }
+
+ /**
+ * check if a certificate (serial number) is revoked on a CA.
+ * @return true if cert is marked revoked in the CA's database.
+ * @return false if cert is not marked revoked.
+ */
+ protected boolean certIsRevoked(BigInteger serialNum)
+ throws EBaseException {
+ ICertRecord certRecord = getCertRecord(serialNum);
+
+ if (certRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_BAD_CERT_SER_NUM", String.valueOf(serialNum)));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_INVALID_CERT"));
+ }
+ if (certRecord.getStatus().equals(ICertRecord.STATUS_REVOKED))
+ return true;
+ return false;
+ }
+
+ public static String generateSalt() {
+ Random rnd = new Random();
+ String salt = new Integer( rnd.nextInt() ).toString();
+ return salt;
+ }
+
+ protected String hashPassword(String pwd) {
+ String salt = generateSalt();
+ byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest);
+
+ return "{SHA}" + salt + ";" + b64E;
+ }
+
+ /**
+ * @param req http servlet request
+ * @param realpathFile the file to get.
+ * @param locale array of at least one to be filled with locale found.
+ */
+ public static File getLangFile(
+ HttpServletRequest req, File realpathFile, Locale[] locale)
+ throws IOException {
+ File file = null;
+ String acceptLang = req.getHeader("accept-language");
+
+ if (acceptLang != null && !acceptLang.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(acceptLang, ",");
+ int numLangs = tokenizer.countTokens();
+
+ if (numLangs > 0) {
+ // languages are searched in order.
+ String parent = realpathFile.getParent();
+
+ if (parent == null) {
+ parent = "." + File.separatorChar;
+ }
+ String name = realpathFile.getName();
+
+ if (name == null) { // filename should never be null.
+ throw new IOException("file has no name");
+ }
+ int i;
+
+ for (i = 0; i < numLangs; i++) {
+ String lang = null;
+ String token = tokenizer.nextToken();
+
+ int semicolon = token.indexOf(';');
+
+ if (semicolon == -1) {
+ lang = token.trim();
+ } else {
+ if (semicolon < 2)
+ continue; // protocol error.
+ lang = token.substring(0, semicolon).trim();
+ }
+ // if browser locale is the same as default locale,
+ // use the default form. (is this the right thing to do ?)
+ Locale l = getLocale(lang);
+
+ if (Locale.getDefault().equals(l)) {
+ locale[0] = l;
+ file = realpathFile;
+ break;
+ }
+
+ String langfilepath =
+ parent + File.separatorChar +
+ lang + File.separatorChar + name;
+
+ file = new File(langfilepath);
+ if (file.exists()) {
+ locale[0] = getLocale(lang);
+ break;
+ }
+ }
+ // if no file for lang was found use default
+ if (i == numLangs) {
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ }
+ } else {
+ // use default if accept-language is not availabe
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ return file;
+ }
+
+ public static Locale getLocale(String lang) {
+ int dash = lang.indexOf('-');
+
+ if (dash == -1)
+ return new Locale(lang, "");
+ else
+ return new Locale(lang.substring(0, dash), lang.substring(dash + 1));
+ }
+
+ public IAuthToken authenticate(CMSRequest req)
+ throws EBaseException {
+ return authenticate(req, mAuthMgr);
+ }
+
+ public IAuthToken authenticate(HttpServletRequest httpReq)
+ throws EBaseException {
+ return authenticate(httpReq, mAuthMgr);
+ }
+
+ public IAuthToken authenticate(CMSRequest req, String authMgrName)
+ throws EBaseException {
+ IAuthToken authToken = authenticate(req.getHttpReq(),
+ authMgrName);
+
+ saveAuthToken(authToken, req.getIRequest());
+ return authToken;
+ }
+
+ /**
+ * Authentication
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_FAIL used when authentication
+ * fails (in case of SSL-client auth, only webserver env can pick up the
+ * SSL violation; CS authMgr can pick up cert mis-match, so this event
+ * is used)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_SUCCESS used when authentication
+ * succeeded
+ * </ul>
+ * @exception EBaseException an error has occurred
+ */
+ public IAuthToken authenticate(HttpServletRequest httpReq, String authMgrName)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = ILogger.UNIDENTIFIED;
+ String auditAuthMgrID = ILogger.UNIDENTIFIED;
+ String auditUID = ILogger.UNIDENTIFIED;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String getClientCert = mGetClientCert;
+
+ IArgBlock httpArgs = CMS.createArgBlock(toHashtable(httpReq));
+ SessionContext ctx = SessionContext.getContext();
+ String ip = httpReq.getRemoteAddr();
+ CMS.debug("IP: " + ip);
+
+ if (ip != null) {
+ ctx.put(SessionContext.IPADDRESS, ip);
+ }
+ if (authMgrName != null) {
+ CMS.debug("AuthMgrName: " + authMgrName);
+ ctx.put(SessionContext.AUTH_MANAGER_ID, authMgrName);
+ }
+ // put locale into session context
+ ctx.put(SessionContext.LOCALE, getLocale(httpReq));
+
+ //
+ // check ssl client authentication if specified.
+ //
+ X509Certificate clientCert = null;
+
+ if (getClientCert != null && getClientCert.equals("true")) {
+ CMS.debug("CMSServlet: retrieving SSL certificate");
+ clientCert = getSSLClientCertificate(httpReq);
+ }
+
+ //
+ // check authentication by auth manager if any.
+ //
+ if (authMgrName == null) {
+
+ // Fixed Blackflag Bug #613900: Since this code block does
+ // NOT actually constitute an authentication failure, but
+ // rather the case in which a given servlet has been correctly
+ // configured to NOT require an authentication manager, the
+ // audit message called LOGGING_SIGNED_AUDIT_AUTH_FAIL has
+ // been removed.
+
+ CMS.debug("CMSServlet: no authMgrName");
+ return null;
+ } else {
+ // save the "Subject DN" of this certificate in case it
+ // must be audited as an authentication failure
+ if (clientCert == null) {
+ CMS.debug("CMSServlet: no client certificate found");
+ } else {
+ String certUID = clientCert.getSubjectDN().getName();
+ CMS.debug("CMSServlet: certUID=" + certUID);
+
+ if (certUID != null) {
+ certUID = certUID.trim();
+
+ if (!(certUID.equals(""))) {
+ // reset the "auditUID"
+ auditUID = certUID;
+ }
+ }
+ }
+
+ // reset the "auditAuthMgrID"
+ auditAuthMgrID = authMgrName;
+ }
+ AuthToken authToken = CMSGateway.checkAuthManager(httpReq,
+ httpArgs,
+ clientCert,
+ authMgrName);
+ if (authToken == null) {
+ return null;
+ }
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+
+ CMS.debug("CMSServlet: userid=" + userid);
+
+ if (userid != null) {
+ ctx.put(SessionContext.USER_ID, userid);
+ }
+
+ // reset the "auditSubjectID"
+ auditSubjectID = auditSubjectID();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditAuthMgrID);
+
+ audit(auditMessage);
+
+ return authToken;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditAuthMgrID,
+ auditUID);
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String exp) throws EBaseException {
+ AuthzToken authzToken = mAuthz.authorize(authzMgrName, authToken,
+ exp);
+ return authzToken;
+ }
+
+ /**
+ * Authorize must occur after Authenticate
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_FAIL used when authorization
+ * has failed
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS used when authorization
+ * is successful
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_ROLE_ASSUME used when user assumes a
+ * role (in current CS that's when one accesses a role port)
+ * </ul>
+ * @param authzMgrName string representing the name of the authorization
+ * manager
+ * @param authToken the authentication token
+ * @param resource a string representing the ACL resource id as defined in
+ * the ACL resource list
+ * @param operation a string representing one of the operations as defined
+ * within the ACL statement (e. g. - "read" for an ACL statement containing
+ * "(read,write)")
+ * @exception EBaseException an error has occurred
+ * @return the authorization token
+ */
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String resource, String operation)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditGroupID = auditGroupID();
+ String auditID = auditSubjectID;
+ String auditACLResource = resource;
+ String auditOperation = operation;
+
+
+ SessionContext auditContext = SessionContext.getExistingContext();
+ String authManagerId = null;
+
+ if(auditContext != null) {
+ authManagerId = (String) auditContext.get(SessionContext.AUTH_MANAGER_ID);
+
+ if(authManagerId != null && authManagerId.equals("TokenAuth")) {
+ if (auditSubjectID.equals(ILogger.NONROLEUSER) ||
+ auditSubjectID.equals(ILogger.UNIDENTIFIED)) {
+ CMS.debug("CMSServlet: in authorize... TokenAuth auditSubjectID unavailable, changing to auditGroupID");
+ auditID = auditGroupID;
+ }
+ }
+ }
+
+ // "normalize" the "auditACLResource" value
+ if (auditACLResource != null) {
+ auditACLResource = auditACLResource.trim();
+ }
+
+ // "normalize" the "auditOperation" value
+ if (auditOperation != null) {
+ auditOperation = auditOperation.trim();
+ }
+
+ if (authzMgrName == null) {
+ // Fixed Blackflag Bug #613900: Since this code block does
+ // NOT actually constitute an authorization failure, but
+ // rather the case in which a given servlet has been correctly
+ // configured to NOT require an authorization manager, the
+ // audit message called LOGGING_SIGNED_AUDIT_AUTHZ_FAIL and
+ // the audit message called LOGGING_SIGNED_AUDIT_ROLE_ASSUME
+ // (marked as a failure) have been removed.
+
+ return null;
+ }
+
+ try {
+ AuthzToken authzTok = mAuthz.authorize(authzMgrName,
+ authToken,
+ resource,
+ operation);
+
+ if (authzTok != null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditID,
+ ILogger.SUCCESS,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+ }
+
+ return authzTok;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ } catch (Exception eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ }
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ CMS.debug("CMSServlet: in auditSubjectID");
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ CMS.debug("CMSServlet: auditSubjectID auditContext " + auditContext);
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ CMS.debug("CMSServlet auditSubjectID: subjectID: " + subjectID);
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+
+ /**
+ * Signed Audit Log Group ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "gid" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditGroupID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ CMS.debug("CMSServlet: in auditGroupID");
+ String groupID = null;
+
+ // Initialize groupID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ CMS.debug("CMSServlet: auditGroupID auditContext " + auditContext);
+ if (auditContext != null) {
+ groupID = (String)
+ auditContext.get(SessionContext.GROUP_ID);
+
+ CMS.debug("CMSServlet auditGroupID: groupID: " + groupID);
+ if (groupID != null) {
+ groupID = groupID.trim();
+ } else {
+ groupID = ILogger.NONROLEUSER;
+ }
+ } else {
+ groupID = ILogger.UNIDENTIFIED;
+ }
+
+ return groupID;
+ }
+
+ /**
+ * Signed Audit Groups
+ *
+ * This method is called to extract all "groups" associated
+ * with the "auditSubjectID()".
+ * <P>
+ *
+ * @param id string containing the signed audit log message SubjectID
+ * @return a delimited string of groups associated
+ * with the "auditSubjectID()"
+ */
+ private String auditGroups(String SubjectID) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if ((SubjectID == null) ||
+ (SubjectID.equals(ILogger.UNIDENTIFIED))) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ Enumeration groups = null;
+
+ try {
+ groups = mUG.findGroups("*");
+ } catch (Exception e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ StringBuffer membersString = new StringBuffer();
+
+ while (groups.hasMoreElements()) {
+ IGroup group = (IGroup) groups.nextElement();
+
+ if (group.isMember(SubjectID) == true) {
+ if (membersString.length()!= 0) {
+ membersString.append(", ");
+ }
+
+ membersString.append(group.getGroupID());
+ }
+ }
+
+ if (membersString.length()!=0) {
+ return membersString.toString();
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader(HDR_LANG);
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected void outputResult(HttpServletResponse httpResp,
+ String contentType, byte[] content) {
+ try {
+ OutputStream os = httpResp.getOutputStream();
+
+ httpResp.setContentType(contentType);
+ httpResp.setContentLength(content.length);
+ os.write(content);
+ os.flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+ return;
+ }
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String errorString) {
+ outputError(httpResp, FAILURE, errorString, null);
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String errorString, String requestId) {
+ outputError(httpResp, FAILURE, errorString, null);
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String status, String errorString, String requestId) {
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+ xmlObj.addItemToContainer(root, "Status", status);
+ xmlObj.addItemToContainer(root, "Error", errorString);
+ if (requestId != null) {
+ xmlObj.addItemToContainer(root, "RequestId", requestId);
+ }
+ byte[] cb = xmlObj.toByteArray();
+
+ OutputStream os = httpResp.getOutputStream();
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(cb.length);
+ os.write(cb);
+ os.flush();
+ return;
+ } catch (Exception ee) {
+ CMS.debug("Failed to send XML output to the server.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", ee.toString()));
+ }
+ }
+
+ protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape)
+ {
+ StringBuffer result = new StringBuffer();
+
+ // Do we need to escape any characters
+ for (int i = 0; i < v.length(); i++) {
+ int c = v.charAt(i);
+ if (c == ',' || c == '=' || c == '+' || c == '<' ||
+ c == '>' || c == '#' || c == ';' || c == '\r' ||
+ c == '\n' || c == '\\' || c == '"') {
+ result.append('\\');
+ if (doubleEscape) result.append('\\');
+ }
+ if (c == '\r') {
+ result.append("0D");
+ } else if (c == '\n') {
+ result.append("0A");
+ } else {
+ result.append((char)c);
+ }
+ }
+ return result;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java
new file mode 100644
index 000000000..5a450251e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java
@@ -0,0 +1,111 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmsutil.util.Utils;
+
+
+/**
+ * This servlet is started by the web server at startup, and
+ * it starts the CMS framework.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSStartServlet extends HttpServlet {
+ public final static String PROP_CMS_CFG = "cfgPath";
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ String path = config.getInitParameter(PROP_CMS_CFG);
+
+ File f = new File(path);
+ String old_path = "";
+ if (!f.exists()) {
+ int index = path.lastIndexOf("CS.cfg");
+ if (index != -1) {
+ old_path = path.substring(0, index)+"CMS.cfg";
+ }
+ File f1 = new File(old_path);
+ if (f1.exists()) {
+ // The following block of code moves "CMS.cfg" to "CS.cfg".
+ try {
+ if( Utils.isNT() ) {
+ // NT is very picky on the path
+ Utils.exec( "copy " +
+ f1.getAbsolutePath().replace( '/', '\\' ) +
+ " " +
+ f.getAbsolutePath().replace( '/', '\\' ) );
+ } else {
+ // Create a copy of the original file which
+ // preserves the original file permissions.
+ Utils.exec( "cp -p " + f1.getAbsolutePath() + " " +
+ f.getAbsolutePath() );
+ }
+
+ // Remove the original file if and only if
+ // the backup copy was successful.
+ if( f.exists() ) {
+ f1.delete();
+
+ // Make certain that the new file has
+ // the correct permissions.
+ if( !Utils.isNT() ) {
+ Utils.exec( "chmod 00660 " + f.getAbsolutePath() );
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+ }
+ try {
+ CMS.start(path);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ res.setContentType("text/html");
+
+ PrintWriter out = res.getWriter();
+
+ out.print("<html>");
+ out.print("<head><title>CMS is started!</title></head>");
+ out.print("<body>");
+ out.print("<h1>CMS is started!</h1>");
+ out.print("</body></html>");
+ }
+
+ public String getServletInfo() {
+ return "CMS startup servlet";
+ }
+
+ public void destroy() {
+ CMS.shutdown();
+ super.destroy();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java
new file mode 100644
index 000000000..706c406cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java
@@ -0,0 +1,92 @@
+// --- 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.servlet.base;
+
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.common.*;
+
+
+/**
+ * This is the servlet that displays the html page for the corresponding input id.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayHtmlServlet extends CMSServlet {
+ public final static String PROP_TEMPLATE = "template";
+ public final static String PROP_HTML_PATH = "htmlPath";
+
+ private String mHTMLPath = null;
+
+ public DisplayHtmlServlet() {
+ super();
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mHTMLPath = sc.getInitParameter(PROP_HTML_PATH);
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("DisplayHtmlServlet about to service ");
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ try {
+ String realpath =
+ mServletConfig.getServletContext().getRealPath("/" + mHTMLPath);
+
+ if (realpath == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_FIND_TEMPLATE", mHTMLPath));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")) ;
+ }
+ File file = new File(realpath);
+ long flen = file.length();
+ byte[] bin = new byte[(int)flen];
+ FileInputStream ins = new FileInputStream(file);
+
+ int len = 0;
+ if (ins.available() > 0) {
+ len = ins.read(bin);
+ }
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(bin, 0, len);
+ bos.writeTo(cmsReq.getHttpResp().getOutputStream());
+ ins.close();
+ bos.close();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_TEMPLATE", mHTMLPath, e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java
new file mode 100644
index 000000000..59d307084
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java
@@ -0,0 +1,330 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+import java.io.*;
+import java.util.*;
+import java.lang.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.dbs.*;
+import org.mozilla.jss.ssl.SSLSocket;
+
+
+/**
+ * Return some javascript to the request which contains the list of
+ * dynamic data in the CMS system.
+ * <p>
+ * This allows the requestor (browser) to make decisions about what
+ * to present in the UI, depending on how CMS is configured
+ *
+ * @version $Revision$, $Date$
+ */
+public class DynamicVariablesServlet extends CMSServlet {
+ public final static String PROP_ACCESS = "ServletAccess";
+ public final static String PROP_AUTHMGR = "AuthMgr";
+ public final static String PROP_CLIENTAUTH = "GetClientCert";
+
+ public final static String PROP_AUTHORITY = "authority";
+ public final static String PROP_CLONING = "cloning";
+
+ private final static String INFO = "dynamicVariables";
+
+ private static final String PROP_DYNVAR = "dynamicVariables";
+ private static final String PROP_CRLURL = "cloneMasterCrlUrl";
+ private static final String VAR_SERVERDATE_STRING = "serverdate()";
+ private static final Integer VAR_SERVERDATE = Integer.valueOf(1);
+
+ private static final String VAR_SUBSYSTEMNAME_STRING = "subsystemname()";
+ private static final Integer VAR_SUBSYSTEMNAME = Integer.valueOf(2);
+ private String VAR_SUBSYSTEMNAME_VALUE = null;
+
+ private static final String VAR_HTTP_STRING = "http()";
+ private static final Integer VAR_HTTP = Integer.valueOf(3);
+ private String VAR_HTTP_VALUE = null;
+
+ private static final String VAR_AUTHMGRS_STRING = "authmgrs()";
+ private static final Integer VAR_AUTHMGRS = Integer.valueOf(4);
+ private String VAR_AUTHMGRS_VALUE = null;
+
+ private static final String VAR_CLA_CRL_URL_STRING = "clacrlurl()";
+ private static final Integer VAR_CLA_CRL_URL = Integer.valueOf(6);
+ private String VAR_CLA_CRL_URL_VALUE = null;
+
+ private String mAuthMgrCacheString = "";
+ private long mAuthMgrCacheTime = 0;
+ private final int AUTHMGRCACHE = 10; //number of seconds to cache list of
+ // authmanagers for
+ private Hashtable dynvars = null;
+ private String mGetClientCert = "false";
+ private String mAuthMgr = null;
+
+ private ServletConfig mServletCfg = null;
+ private ServletContext mServletCtx = null;
+ private static String mCrlurl = "";
+ static {
+ IConfigStore config = CMS.getConfigStore().getSubStore(PROP_CLONING);
+
+ try {
+ mCrlurl =
+ config.getString(PROP_CRLURL, "");
+ } catch (EBaseException e) {
+ }
+ }
+
+ public DynamicVariablesServlet() {
+ super();
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Reads the following variables from the servlet config:
+ * <ul>
+ * <li><strong>AuthMgr</strong> - the authentication manager to use to authenticate the request
+ * <li><strong>GetClientCert</strong> - whether to request client auth for this request
+ * <li><strong>authority</strong> - the authority (ca, ra, drm) to return to the client
+ * <li><strong>dynamicVariables</strong> - a string of the form:
+ * serverdate=serverdate(),subsystemname=subsystemname(),
+ * http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl()
+ * </ul>
+ * The dynamicVariables string is parsed by splitting on commas.
+ * When services, the HTTP request provides a piece of javascript
+ * code as follows.
+ * <p>
+ * Each sub expression "lhs=rhs()" forms a javascript statement of the form
+ * <i>lhs=xxx;</i> Where lhs is xxx is the result of 'evaluating' the
+ * rhs. The possible values for the rhs() function are:
+ * <ul>
+ * <li><strong>serverdate()</strong> - the timestamp of the server (used to ensure that the client
+ * clock is set correctly)
+ * <li><strong>subsystemname()</strong>
+ * <li><strong>http()</strong> - "true" or "false" - is this an http connection (as opposed to https)
+ * <li>authmgrs() - a comma separated list of authentication managers
+ * <li>clacrlurl() - the URL to get the CRL from, in the case of a Clone CA. This is
+ * defined in the CMS configuration parameter 'cloning.cloneMasterCrlUrl'
+ * </ul>
+ * @see javax.servlet.Servlet#init(ServletConfig)
+ */
+
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthMgr = sc.getInitParameter(PROP_AUTHMGR);
+ mGetClientCert = sc.getInitParameter(PROP_CLIENTAUTH);
+ mServletCfg = sc;
+
+ mServletCtx = sc.getServletContext();
+
+ VAR_SUBSYSTEMNAME_VALUE = sc.getInitParameter(PROP_AUTHORITY);
+
+ try {
+ String dynvarconfig = sc.getInitParameter(PROP_DYNVAR);
+ StringTokenizer s = new StringTokenizer(dynvarconfig, ",");
+
+ dynvars = new Hashtable();
+
+ while (s.hasMoreTokens()) {
+ String token = s.nextToken();
+
+ int i = token.indexOf('=');
+ String varname = token.substring(0, i);
+ String varvalue = token.substring(i + 1);
+
+ Integer varcode = null;
+
+ if (varvalue.equalsIgnoreCase(VAR_SERVERDATE_STRING)) {
+ varcode = VAR_SERVERDATE;
+ } else if (varvalue.equalsIgnoreCase(VAR_SUBSYSTEMNAME_STRING)) {
+ varcode = VAR_SUBSYSTEMNAME;
+ } else if (varvalue.equalsIgnoreCase(VAR_HTTP_STRING)) {
+ varcode = VAR_HTTP;
+ } else if (varvalue.equalsIgnoreCase(VAR_AUTHMGRS_STRING)) {
+ varcode = VAR_AUTHMGRS;
+ } else if (varvalue.equalsIgnoreCase(VAR_CLA_CRL_URL_STRING)) {
+ varcode = VAR_CLA_CRL_URL;
+ } else {
+ throw new ServletException("bad configuration parameter in " + PROP_DYNVAR);
+ }
+ if (varcode != null) {
+ dynvars.put(varcode, (Object) varname);
+ }
+ }
+ } catch (Exception e) {
+ dynvars = null;
+ }
+ }
+
+ public void service(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException, IOException {
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CMS server is not ready to serve.");
+
+ if (mAuthMgr != null) {
+ try {
+ IAuthToken token = authenticate(httpReq);
+ } catch (EBaseException e) {
+ mServletCtx.log(CMS.getLogMessage("CMSGW_FILE_NO_ACCESS", e.toString()));
+ httpResp.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ }
+
+ httpResp.setContentType("application/x-javascript");
+ httpResp.setHeader("Pragma", "no-cache");
+
+ try {
+ ServletOutputStream os = httpResp.getOutputStream();
+
+ if (os != null) {
+ if (dynvars != null) {
+ Enumeration k = dynvars.keys();
+
+ while (k.hasMoreElements()) {
+ String toBeWritten;
+ Integer varcode = (Integer) k.nextElement();
+
+ if (varcode.equals(VAR_SERVERDATE)) {
+ toBeWritten = dynvars.get(varcode) +
+ "=" +
+ getServerDate() +
+ ";\n";
+
+ os.print(toBeWritten);
+ }
+
+ if (varcode.equals(VAR_SUBSYSTEMNAME)) {
+ if (getSubsystemName() != null) {
+ toBeWritten = dynvars.get(varcode) +
+ "=" + "\"" +
+ getSubsystemName() + "\"" +
+ ";\n";
+ os.print(toBeWritten);
+ }
+ }
+
+ if (varcode.equals(VAR_HTTP)) {
+ if (getHttp(httpReq) != null) {
+ toBeWritten = dynvars.get(varcode) +
+ "=" + "\"" +
+ getHttp(httpReq) + "\"" +
+ ";\n";
+ os.print(toBeWritten);
+ }
+ }
+
+ if (varcode.equals(VAR_CLA_CRL_URL)) {
+ if (getImportCrlUrl() != null) {
+ toBeWritten = dynvars.get(varcode) +
+ "=" + "\"" +
+ getImportCrlUrl() + "\"" +
+ ";\n";
+ os.print(toBeWritten);
+ }
+ }
+
+ if (varcode.equals(VAR_AUTHMGRS)) {
+ toBeWritten = "";
+ IAuthSubsystem as = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ Enumeration ame = as.getAuthManagers();
+
+ Date d = CMS.getCurrentDate();
+ long now = d.getTime();
+
+ if (now > (mAuthMgrCacheTime + 1000 * AUTHMGRCACHE)) {
+ int i = 0;
+
+ StringBuffer sb = new StringBuffer();
+ while (ame.hasMoreElements()) {
+ IAuthManager am = (IAuthManager) ame.nextElement();
+ String amName = am.getImplName();
+
+ AuthMgrPlugin ap = as.getAuthManagerPluginImpl(amName);
+
+ if (ap.isVisible()) {
+ sb.append("authmanager[");
+ sb.append(i);
+ sb.append("]=\"");
+ sb.append(amName);
+ sb.append("\";\n");
+ i++;
+ }
+ }
+ toBeWritten = sb.toString();
+ mAuthMgrCacheString = toBeWritten;
+ mAuthMgrCacheTime = now;
+ } else {
+ toBeWritten = mAuthMgrCacheString;
+ }
+ if (toBeWritten.length() != 0) {
+ os.print("authmanager = new Array();\n");
+ os.print(toBeWritten);
+ }
+ }
+
+ }
+ }
+ os.close();
+ }
+
+ } catch (IOException e) {
+ throw new ServletException("couldn't get outputstream");
+ }
+ }
+
+ private String getServerDate() {
+ Date d = new Date();
+ String now = Long.toString(d.getTime());
+
+ return now;
+ }
+
+ private String getSubsystemName() {
+ return VAR_SUBSYSTEMNAME_VALUE;
+ }
+
+ private String getHttp(HttpServletRequest httpReq) {
+ if (httpReq.isSecure())
+ return "false";
+ else
+ return "true";
+ }
+
+ private String getImportCrlUrl() {
+ return mCrlurl;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/GetStats.java b/pki/base/common/src/com/netscape/cms/servlet/base/GetStats.java
new file mode 100644
index 000000000..d16ce7598
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/GetStats.java
@@ -0,0 +1,177 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.util.*;
+
+
+/**
+ * Retrieve information.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetStats extends CMSServlet {
+ private final static String TPL_FILE = "getStats.template";
+ private String mFormPath = null;
+
+ public GetStats() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template
+ * file "getOCSPInfo.template" to render the result page.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ StatsEvent st = statsSub.getMainStatsEvent();
+
+ String op = httpReq.getParameter("op");
+ if (op != null && op.equals("clear")) {
+ statsSub.resetCounters();
+ }
+
+ header.addStringValue("startTime", statsSub.getStartTime().toString());
+ header.addStringValue("curTime", (new Date()).toString());
+ parse(argSet, st, 0);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ public String getSep(int level)
+ {
+ StringBuffer s = new StringBuffer();
+ for (int i = 0; i < level; i++) {
+ s.append("-");
+ }
+ return s.toString();
+ }
+
+ public void parse(CMSTemplateParams argSet, StatsEvent st, int level) {
+ Enumeration names = st.getSubEventNames();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ StatsEvent subSt = st.getSubEvent(name);
+
+ IArgBlock rarg = CMS.createArgBlock();
+ rarg.addStringValue("name", getSep(level) + " " + subSt.getName());
+ rarg.addLongValue("noOfOp", subSt.getNoOfOperations());
+ rarg.addLongValue("timeTaken", subSt.getTimeTaken());
+ rarg.addLongValue("max", subSt.getMax());
+ rarg.addLongValue("min", subSt.getMin());
+ rarg.addLongValue("percentage", subSt.getPercentage());
+ rarg.addLongValue("avg", subSt.getAvg());
+ rarg.addLongValue("stddev", subSt.getStdDev());
+ argSet.addRepeatRecord(rarg);
+
+ parse(argSet, subSt, level+1);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java
new file mode 100644
index 000000000..04dfd9210
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java
@@ -0,0 +1,118 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * This is the servlet that builds the index page in
+ * various ports.
+ *
+ * @version $Revision$, $Date$
+ */
+public class IndexServlet extends CMSServlet {
+ public final static String PROP_TEMPLATE = "template";
+
+ private final static String INFO = "indexServlet";
+
+ // input parameters
+
+ // output parameters
+ private final static String OUT_TYPE = "type";
+ private final static String OUT_ID = "id";
+ private final static String OUT_TOTAL_COUNT = "totalCount";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private String mTemplateName = null;
+
+ public IndexServlet() {
+ super();
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplateName = sc.getInitParameter(PROP_TEMPLATE);
+
+ /*
+ mTemplates.put(CMSRequest.SUCCESS,
+ new CMSLoadTemplate(
+ PROP_SUCCESS_TEMPLATE, PROP_SUCCESS_TEMPLATE_FILLER,
+ mTemplateName, new IndexTemplateFiller()));
+ */
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ public CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ if (CMSGateway.getEnableAdminEnroll() &&
+ mAuthority != null &&
+ mAuthority instanceof ICertificateAuthority) {
+ try {
+ cmsReq.getHttpResp().sendRedirect("/ca/adminEnroll.html");
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_REDIRECT_ADMIN_ENROLL", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_REDIRECTING_ADMINENROLL1",
+ e.toString()));
+ }
+ return;
+ } else {
+ try {
+ renderTemplate(
+ cmsReq, mTemplateName, new IndexTemplateFiller());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_RENDER_TEMPLATE", mTemplateName, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSG_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java
new file mode 100644
index 000000000..7443b0144
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java
@@ -0,0 +1,93 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.http.*;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+
+/**
+ * This servlet returns port information.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PortsServlet extends CMSServlet {
+
+ private final static String INFO = "ports";
+
+ public PortsServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override these to output directly ourselves.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mTemplates.remove(CMSRequest.ERROR);
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ // process query if authentication is successful
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ String secure = req.getParameter("secure");
+ String port = null;
+
+ if (secure.equals("true"))
+ port = CMS.getEESSLPort();
+ else
+ port = CMS.getEENonSSLPort();
+
+ try {
+ XMLObject xmlObj = null;
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "Port", port);
+ byte[] cb = xmlObj.toByteArray();
+ outputResult(resp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {
+ // do nothing, ie, it will not return the default javascript.
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java
new file mode 100644
index 000000000..3b4315266
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java
@@ -0,0 +1,246 @@
+/* CMS_SDK_LICENSE_TEXT */
+
+package com.netscape.cms.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * This is a servlet that proxies request to another servlet.
+ *
+ * SERVLET REDIRECTION
+ * Specify the URL of a servlet to forward the request to
+ * destServlet: /ee/ca/newservlet
+ *
+ * PARAMETER MAPPING
+ * In the servlet configuration (as an init-param in web.xml) you
+ * can optionally specify a value for the parameter 'parameterMap'
+ * which contains a list of HTTP parameters which should be
+ * translated to new names.
+ *
+ * parameterMap: name1->newname1,name2->newname2
+ *
+ * Optionally, names can be set to static values:
+ *
+ * parameterMap: name1->name2=value
+ *
+ * Examples:
+ * Consider the following HTTP input parameters:
+ * vehicle:car make:ford model:explorer
+ *
+ * The following config strings will have this effect:
+ * parameterMap: make->manufacturer,model->name=expedition,->suv=true
+ * output: vehicle:car manufactuer:ford model:expedition suv:true
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProxyServlet extends HttpServlet {
+
+ private String mDest = null;
+ private String mDestContext = null;
+ private String mSrcContext = null;
+ private String mAppendPathInfo = null;
+ private Vector mMatchStrings = new Vector();
+ private String mDestServletOnNoMatch = null;
+ private String mAppendPathInfoOnNoMatch = null;
+ private Map mParamMap = new HashMap();
+ private Map mParamValue = new HashMap();
+
+ public ProxyServlet() {
+ }
+
+ private void parseParamTable(String s) {
+ if (s == null) return;
+
+ String[] params = s.split(",");
+ for (int i=0;i<params.length;i++) {
+ String p = params[i];
+ if (p != null) {
+ String[] paramNames = p.split("->");
+ if (paramNames.length != 2) {
+ }
+ String from = paramNames[0];
+ String to = paramNames[1];
+ if (from != null && to != null) {
+ String[] splitTo = to.split("=");
+ String toName = splitTo[0];
+ if (from.length() >0) {
+ mParamMap.put(from,toName);
+ }
+ if (splitTo.length == 2) {
+ String toValue = splitTo[1];
+ String toValues[] = new String[1];
+ toValues[0] = toValue;
+ mParamValue.put(toName,toValues);
+ }
+ }
+ }
+ }
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ String mMatchStrs = sc.getInitParameter("matchURIStrings");
+ if (mMatchStrs != null && (!mMatchStrs.equals(""))) {
+ StringTokenizer st = new StringTokenizer(mMatchStrs, ",");
+ while (st.hasMoreTokens()) {
+ mMatchStrings.addElement(st.nextToken());
+ }
+ }
+ mDestServletOnNoMatch = sc.getInitParameter("destServletOnNoMatch");
+ mDestContext = sc.getInitParameter("destContext");
+ mDest = sc.getInitParameter("destServlet");
+ mSrcContext = sc.getInitParameter("srcContext");
+ mAppendPathInfo = sc.getInitParameter("appendPathInfo");
+ mAppendPathInfoOnNoMatch = sc.getInitParameter("appendPathInfoOnNoMatch");
+ String map = sc.getInitParameter("parameterMap");
+ if (map != null) {
+ parseParamTable(map);
+ }
+ }
+
+ public void service(HttpServletRequest req, HttpServletResponse res) throws
+ IOException, ServletException
+ {
+ RequestDispatcher dispatcher = null;
+ String dest = mDest;
+ String uri = req.getRequestURI();
+
+ // check if match strings are specified. If it is, we need
+ // to deal with the alternate dest
+ if (mMatchStrings.size() != 0) {
+ boolean matched = false;
+ for (int i = 0; i < mMatchStrings.size(); i++) {
+ String t = (String)mMatchStrings.elementAt(i);
+ if (uri.indexOf(t) != -1) {
+ matched = true;
+ }
+ }
+ if (!matched) {
+ dest = mDestServletOnNoMatch;
+ // append Path info for OCSP request in Get method
+ if (mAppendPathInfoOnNoMatch != null &&
+ !mAppendPathInfoOnNoMatch.equals("")) {
+ dest = dest + uri.replace(mAppendPathInfoOnNoMatch, "");
+ }
+ }
+ }
+ if (dest == null || dest.equals("")) {
+ // mapping everything
+ dest = uri;
+ dest = dest.replaceFirst(mSrcContext, "");
+ }
+ if (mAppendPathInfo != null && !mAppendPathInfo.equals("")) {
+ dest = dest + uri.replace(mAppendPathInfo, "");
+ }
+ if (mDestContext != null && !mDestContext.equals("")) {
+ dispatcher = getServletContext().getContext(mDestContext).getRequestDispatcher(dest);
+ } else {
+ dispatcher = req.getRequestDispatcher(dest);
+ }
+
+ // If a parameter map was specified
+ if (mParamMap != null && !mParamMap.isEmpty()) {
+ // Make a new wrapper with the new parameters
+ ProxyWrapper r = new ProxyWrapper(req);
+ r.setParameterMapAndValue(mParamMap,mParamValue);
+ req = r;
+ }
+
+ dispatcher.forward(req, res);
+ }
+}
+
+class ProxyWrapper extends HttpServletRequestWrapper
+{
+ private Map mMap = null;
+ private Map mValueMap = null;
+
+ public ProxyWrapper(HttpServletRequest req)
+ {
+ super(req);
+ }
+
+ public void setParameterMapAndValue(Map m,Map v)
+ {
+ if (m != null) mMap = m;
+ if (v != null) mValueMap = v;
+ }
+
+ public Map getParameterMap()
+ {
+ try {
+ // If we haven't specified any parameter mapping, just
+ // use the regular implementation
+ if (mMap == null) return super.getParameterMap();
+ else {
+ // Make a new Map for us to put stuff in
+ Map n = new HashMap();
+ // get the HTTP parameters the user supplied.
+ Map m = super.getParameterMap();
+ Set s = m.entrySet();
+ Iterator i = s.iterator();
+ while (i.hasNext()) {
+ Map.Entry me = (Map.Entry) i.next();
+ String name = (String) me.getKey();
+ String[] values = (String[])(me.getValue());
+ String newname = null;
+ if (name != null) {
+ newname = (String) mMap.get(name);
+ }
+
+ // No mapping specified, just use existing name/value
+ if (newname == null || mValueMap == null) {
+ n.put(name,values);
+ } else { // new name specified
+ Object o = mValueMap.get(newname);
+ // check if new (static) value specified
+ if (o==null) {
+ n.put(newname,values);
+ } else {
+ String newvalues[] = (String[])mValueMap.get(newname);
+ n.put(newname,newvalues);
+ }
+ }
+ }
+ // Now, deal with static values set in the config
+ // which weren't set in the HTTP request
+ Set s2 = mValueMap.entrySet();
+ Iterator i2 = s2.iterator();
+ // Cycle through all the static values
+ while (i2.hasNext()) {
+ Map.Entry me2 = (Map.Entry) i2.next();
+ String name2 = (String) me2.getKey();
+ if (n.get(name2) == null) {
+ String[] values2 = (String[])me2.getValue();
+ // If the parameter is not set in the map
+ // Set it now
+ n.put(name2,values2);
+ }
+ }
+
+ return n;
+ }
+ } catch (NullPointerException npe) {
+ CMS.debug(npe);
+ return null;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java
new file mode 100644
index 000000000..ac6889c09
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java
@@ -0,0 +1,287 @@
+// --- 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.servlet.base;
+
+
+import com.netscape.cms.servlet.common.*;
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.request.*;
+
+/**
+ * Displays detailed information about java VM internals, including
+ * current JVM memory usage, and detailed information about each
+ * thread.
+ * <p>
+ * Also allows user to trigger a new garbage collection
+ *
+ * @version $Revision$, $Date$
+ */
+public class SystemInfoServlet extends HttpServlet {
+
+ public SystemInfoServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ }
+
+ /**
+ * service the request, returning HTML to the client.
+ * This method has different behaviour depending on the
+ * value of the 'op' HTTP parameter.
+ * <UL>
+ * <LI>op = <i>undefined</i> - display a menu with links to the other functionality of this servlet
+ * <li>op = gc - tell the JVM that we want to do a garbage collection and to run finalizers
+ * (@see java.lang.Runtime.getRuntime#gc() )
+ * <li>op = general - display information about memory, and other JVM informatino
+ * <li>op = thread - display details about each thread.
+ * </UL>
+ * @see javax.servlet.http.HttpServlet#service(HttpServletRequest, HttpServletResponse)
+ */
+ public void service(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ boolean collect = false;
+ String op = request.getParameter("op");
+
+ response.setContentType("text/html");
+ if (op == null) {
+ mainMenu(request, response);
+ } else if (op.equals("gc")) {
+ gc(request, response);
+ } else if (op.equals("general")) {
+ general(request, response);
+ } else if (op.equals("thread")) {
+ thread(request, response);
+ }
+ }
+
+ private void mainMenu(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ response.getWriter().println("<HTML>");
+ response.getWriter().println("<H1>");
+ response.getWriter().println("<a href=" + request.getServletPath() + ">");
+ response.getWriter().println("Main");
+ response.getWriter().println("</a>");
+ response.getWriter().println("</H1>");
+ response.getWriter().println("<p>");
+ response.getWriter().println("<table>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<li>");
+ response.getWriter().println("<a href=" + request.getServletPath() + "?op=general>");
+ response.getWriter().println("General");
+ response.getWriter().println("</a>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<li>");
+ response.getWriter().println("<a href=" + request.getServletPath() + "?op=gc>");
+ response.getWriter().println("Garbage Collection");
+ response.getWriter().println("</a>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<li>");
+ response.getWriter().println("<a href=" + request.getServletPath() + "?op=thread>");
+ response.getWriter().println("Thread Listing");
+ response.getWriter().println("</a>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("</table>");
+ response.getWriter().println("</HTML>");
+ }
+
+ private void gc(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ java.lang.Runtime.getRuntime().gc();
+ java.lang.Runtime.getRuntime().runFinalization();
+ response.getWriter().println("<HTML>");
+ response.getWriter().println("<H1>");
+ response.getWriter().println("<a href=" + request.getServletPath() + ">");
+ response.getWriter().println("Main");
+ response.getWriter().println("</a>");
+ response.getWriter().println(" : ");
+ response.getWriter().println("Garbage Collection");
+ response.getWriter().println("</H1>");
+ response.getWriter().println("<p>");
+ response.getWriter().println("The garbage collector has been executed.");
+ response.getWriter().println("</HTML>");
+ }
+
+ private void general(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ response.getWriter().println("<HTML>");
+ response.getWriter().println("<H1>");
+ response.getWriter().println("<a href=" + request.getServletPath() + ">");
+ response.getWriter().println("Main");
+ response.getWriter().println("</a>");
+ response.getWriter().println(" : ");
+ response.getWriter().println("General");
+ response.getWriter().println("</H1>");
+ response.getWriter().println("<p>");
+ response.getWriter().println("<table>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Server Started Time:");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(new Date(CMS.getStartupTime()));
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Current Time:");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(new Date());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Available Processors:");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(Runtime.getRuntime().availableProcessors());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Active Threads:");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(Thread.activeCount());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Max Memory (in Bytes):");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(Runtime.getRuntime().maxMemory());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Total Memory (in Bytes):");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(Runtime.getRuntime().totalMemory());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Free Memory (in Bytes):");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(Runtime.getRuntime().freeMemory());
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("Free Memory / Total Memory:");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory() + "%");
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ response.getWriter().println("</table>");
+ response.getWriter().println("</HTML>");
+ }
+
+ private void thread(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+ response.getWriter().println("</table>");
+ response.getWriter().println("<HTML>");
+ response.getWriter().println("<H1>");
+ response.getWriter().println("<a href=" + request.getServletPath() + ">");
+ response.getWriter().println("Main");
+ response.getWriter().println("</a>");
+ response.getWriter().println(" : ");
+ response.getWriter().println("Thread Listing");
+ response.getWriter().println("</H1>");
+ response.getWriter().println("<p>");
+ response.getWriter().println("<table width=100% border=1>");
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<b>");
+ response.getWriter().println("#");
+ response.getWriter().println("</b>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<b>");
+ response.getWriter().println("Name");
+ response.getWriter().println("</b>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<b>");
+ response.getWriter().println("Priority");
+ response.getWriter().println("</b>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println("<b>");
+ response.getWriter().println("isDaemon");
+ response.getWriter().println("</b>");
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ int active = Thread.activeCount();
+ Thread threads[] = new Thread[active];
+ int c = Thread.enumerate(threads);
+
+ for (int i = 0; i < c; i++) {
+ response.getWriter().println("<tr>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(i);
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(threads[i].getName());
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ response.getWriter().println(threads[i].getPriority());
+ response.getWriter().println("</td>");
+ response.getWriter().println("<td>");
+ if (threads[i].isDaemon()) {
+ response.getWriter().println("true");
+ } else {
+ response.getWriter().println("false");
+ }
+ response.getWriter().println("</td>");
+ response.getWriter().println("</tr>");
+ }
+ response.getWriter().println("</table>");
+ response.getWriter().println("</HTML>");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/UserInfo.java b/pki/base/common/src/com/netscape/cms/servlet/base/UserInfo.java
new file mode 100644
index 000000000..02ab5b521
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/UserInfo.java
@@ -0,0 +1,91 @@
+// --- 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.servlet.base;
+
+
+/**
+ * This class represents information about the client e.g. version,
+ * langauge, vendor.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UserInfo {
+ public final static String MSIE = "MSIE";
+ public final static String MOZILLA = "Mozilla";
+
+ /**
+ * Constructs a user information object.
+ */
+ public UserInfo() {
+ }
+
+ /**
+ * Returns the user language.
+ *
+ * @param s user language info from the browser
+ * @return user language
+ */
+ public static String getUserLanguage(String s) {
+ // Does this contain a country code?
+ int pos = s.indexOf("-");
+
+ if (pos != -1) {
+ // Yes it does
+ return s.substring(0, pos);
+ }
+ return s;
+ }
+
+ /**
+ * Returns the user country.
+ *
+ * @param s user language info from the browser
+ * @return user country
+ */
+ public static String getUserCountry(String s) {
+ // Does this contain a country code?
+ int pos = s.indexOf("-");
+
+ if (pos != -1) {
+ // Yes it does
+ return s.substring(pos + 1);
+ }
+ return "";
+ }
+
+ /**
+ * Returns the users agent.
+ *
+ * @param s user language info from the browser
+ * @return user agent
+ */
+ public static String getUserAgent(String s) {
+ // Check for MSIE
+ if (s.indexOf(MSIE) != -1) {
+ return MSIE;
+ }
+
+ // Check for Netscape i.e. Mozilla
+ if (s.indexOf(MOZILLA) != -1) {
+ return MOZILLA;
+ }
+
+ // Don't know agent. Return empty string.
+ return "";
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
new file mode 100644
index 000000000..9ed435c07
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
@@ -0,0 +1,1141 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Locale;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.request.*;
+
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Revoke a certificate with a CMC-formatted revocation request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCRevReqServlet extends CMSServlet {
+ public final static String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ // revocation templates.
+ private final static String TPL_FILE = "revocationResult.template";
+ public static final String CRED_CMC = "cmcRequest";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String mRequestID = null;
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ // http params
+ public static final String SERIAL_NO = TOKEN_CERT_SERIAL;
+ public static final String REASON_CODE = "reasonCode";
+ public static final String CHALLENGE_PHRASE = "challengePhrase";
+
+ // request attributes
+ public static final String SERIALNO_ARRAY = "serialNoArray";
+
+ public CMCRevReqServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+
+ super.init(sc);
+
+ String authorityId = mAuthority.getId();
+
+ mFormPath = "/" + authorityId + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * <ul>
+ * <li>http.param cmcRequest the base-64 encoded CMC request
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+
+ String cmcAgentSerialNumber = null;
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("**** mFormPath = "+mFormPath);
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+
+ String cmc = (String) httpParams.get(CRED_CMC);
+ if (cmc == null) {
+ throw new EMissingCredential(
+ CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CMC));
+ }
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName, "revoke");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ //IAuthToken authToken = getAuthToken(cmsReq);
+ //Object subject = authToken.get(CMCAuth.TOKEN_CERT_SERIAL);
+ //Object uid = authToken.get("uid");
+ //===========================
+ String authMgr = AuditFormat.NOAUTH;
+ BigInteger[] serialNoArray = null;
+
+ if (authToken != null) {
+ serialNoArray = authToken.getInBigIntegerArray(TOKEN_CERT_SERIAL);
+ }
+
+ Integer reasonCode = Integer.valueOf(0);
+ if (authToken != null) {
+ reasonCode = authToken.getInInteger(REASON_CODE);
+ }
+ RevocationReason reason = RevocationReason.fromInt(reasonCode.intValue());
+
+ String comments = "";
+ Date invalidityDate = null;
+ String revokeAll = null;
+ int verifiedRecordCount = 0;
+ int totalRecordCount = 0;
+
+ if (serialNoArray != null) {
+ totalRecordCount = serialNoArray.length;
+ verifiedRecordCount = serialNoArray.length;
+ }
+
+ X509CertImpl[] certs = null;
+
+ //for audit log.
+ String initiative = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals("CMCAuth")) {
+ // request is from agent
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ if ((serialNoArray != null) && (serialNoArray.length > 0)) {
+ if (mAuthority instanceof ICertificateAuthority) {
+ certs = new X509CertImpl[serialNoArray.length];
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ certs[i] = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificate(serialNoArray[i]);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest getCertsChallengeReq = null;
+
+ getCertsChallengeReq = mQueue.newRequest(
+ GETCERTS_FOR_CHALLENGE_REQUEST);
+ getCertsChallengeReq.setExtData(SERIALNO_ARRAY, serialNoArray);
+ mQueue.processRequest(getCertsChallengeReq);
+ RequestStatus status = getCertsChallengeReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ certs = getCertsChallengeReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ header.addStringValue("request", getCertsChallengeReq.getRequestId().toString());
+ mRequestID = getCertsChallengeReq.getRequestId().toString();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_GET_CERT_CHALL_PWRD"));
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", serialNoArray.length);
+ header.addIntegerValue("verifiedRecordCount", serialNoArray.length);
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ serialNoArray[i], 16);
+ rarg.addStringValue("subject",
+ certs[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certs[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certs[i].getNotAfter().getTime() / 1000);
+ //argSet.addRepeatRecord(rarg);
+ }
+
+ revokeAll = "(|(certRecordId=" + serialNoArray[0].toString() + "))";
+ cmcAgentSerialNumber= authToken.getInString(IAuthManager.CRED_SSL_CLIENT_CERT);
+ process(argSet, header, reasonCode.intValue(), invalidityDate, initiative, req, resp,
+ verifiedRecordCount, revokeAll, totalRecordCount,
+ comments, locale[0],cmcAgentSerialNumber);
+
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if ((serialNoArray== null) || (serialNoArray.length == 0)) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ EBaseException ee = new EBaseException("No matched certificate is found");
+
+ cmsReq.setError(ee);
+ } else if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * get cert to revoke from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_REVOKE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_REVOKE"));
+ }
+
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * Revoke the specified certificate
+ */
+ private BigInteger getCertFromAuthMgr(
+ AuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+ /**
+ * get cert to revoke from ssl
+ */
+ private BigInteger getCertFromSSL(
+ HttpServletRequest req, X509CertImpl[] certContainer)
+ throws EBaseException {
+ X509Certificate cert = getSSLClientCertificate(req);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_SSL"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_SSL"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION", ""));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ certContainer[0] = (X509CertImpl) cert;
+
+ return serialno;
+ }
+
+ /**
+ * Process cert status change request using the Certificate Management
+ * protocol using CMS (CMC)
+ * <P>
+ *
+ * (Certificate Request - an "EE" cert status change request)
+ * <P>
+ *
+ * (Certificate Request Processed - an "EE" cert status change request)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when
+ * a cert status change request (e. g. - "revocation") is made (before
+ * approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+ * used when a certificate status is changed (revoked, expired, on-hold,
+ * off-hold)
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param reason revocation reason (0 - Unspecified, 1 - Key compromised,
+ * 2 - CA key compromised; should not be used, 3 - Affiliation changed,
+ * 4 - Certificate superceded, 5 - Cessation of operation, or
+ * 6 - Certificate is on hold)
+ * @param invalidityDate certificate validity date
+ * @param initiative string containing the audit format
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param verifiedRecordCount number of verified records
+ * @param revokeAll string containing information on all of the
+ * certificates to be revoked
+ * @param totalRecordCount total number of records (verified and unverified)
+ * @param comments string containing certificate comments
+ * @param locale the system locale
+ * @exception EBaseException an error has occurred
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int reason, Date invalidityDate,
+ String initiative,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ int verifiedRecordCount,
+ String revokeAll,
+ int totalRecordCount,
+ String comments,
+ Locale locale,String cmcAgentSerialNumber)
+ throws EBaseException {
+ String eeSerialNumber = null;
+ if(cmcAgentSerialNumber!=null) {
+ eeSerialNumber = cmcAgentSerialNumber;
+ }else{
+ X509CertImpl sslCert = ( X509CertImpl ) getSSLClientCertificate( req );
+ if( sslCert != null ) {
+ eeSerialNumber = sslCert.getSerialNumber().toString();
+ }
+ }
+
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID( req );
+ String auditSerialNumber = auditSerialNumber( eeSerialNumber );
+ String auditRequestType = auditRequestType( reason );
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf( reason );
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate " +
+ cert.getSerialNumber().toString() +
+ " is already revoked.");
+ } else {
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = null;
+
+ if (mRequestID != null && mRequestID.length() > 0)
+ reqIdStr = mRequestID;
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() &&
+ legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.size() > 0) {
+ IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr));
+ X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ for (int i = 0; i < certs.length; i++) {
+ boolean addToList = false;
+
+ for (int j = 0; j < serialNumbers.size(); j++) {
+ if (certs[i].getSerialNumber().toString().equals(
+ (String) serialNumbers.elementAt(j))) {
+ addToList = true;
+ break;
+ }
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ certs[i].getSerialNumber(), 16);
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } else {
+ String b64eCert = req.getParameter("b64eCertificate");
+
+ if (b64eCert != null) {
+ byte[] certBytes = com.netscape.osutil.OSUtil.AtoB(b64eCert);
+ X509CertImpl cert = new X509CertImpl(certBytes);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ revReq.setExtData(IRequest.REVOKED_REASON, reason);
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+
+ // change audit processing from "REQUEST" to "REQUEST_PROCESSED"
+ // to distinguish which type of signed audit log message to save
+ // as a failure outcome in case an exception occurs
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+
+ if (stat == RequestStatus.COMPLETE) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ header.addStringValue("revoked", "yes");
+
+ Integer updateCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ header.addStringValue("updateCRL", "yes");
+ if (updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("updateCRLSuccess", "yes");
+ } else {
+ header.addStringValue("updateCRLSuccess", "no");
+ String crlError =
+ revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null)
+ header.addStringValue("updateCRLError",
+ crlError);
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("publishCRLSuccess", "yes");
+ } else {
+ header.addStringValue("publishCRLSuccess", "no");
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null)
+ header.addStringValue("publishCRLError",
+ publError);
+ }
+ }
+ }
+ if (mAuthority instanceof ICertificateAuthority) {
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = revReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (updateResult.equals(IRequest.RES_SUCCESS)) {
+ CMS.debug("CMCRevReqServlet: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("CMCRevReqServlet: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(updateErrorStr);
+
+ if (error != null)
+ header.addStringValue(updateErrorStr,
+ error);
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ revReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (publishResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue(publishStatusStr, "yes");
+ } else {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ header.addStringValue(publishStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(publishErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ publishErrorStr, error);
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ revReq.getExtDataInIntegerArray("ldapPublishStatus");
+ int certsToUpdate = 0;
+ int certsUpdated = 0;
+
+ if (ldapPublishStatus != null) {
+ certsToUpdate = ldapPublishStatus.length;
+ for (int i = 0; i < certsToUpdate; i++) {
+ if (ldapPublishStatus[i] == IRequest.RES_SUCCESS) {
+ certsUpdated++;
+ }
+ }
+ }
+ header.addIntegerValue("certsUpdated", certsUpdated);
+ header.addIntegerValue("certsToUpdate", certsToUpdate);
+
+ // add crl publishing status.
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ header.addStringValue("crlPublishError",
+ publError);
+ }
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+ header.addStringValue("error", null);
+
+ } else if (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("revoked", "pending");
+ // audit log the pending
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "pending",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ } else {
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ StringBuffer errorStr = new StringBuffer();
+
+ if (errors != null && errors.size() > 0) {
+ for (int ii = 0; ii < errors.size(); ii++) {
+ errorStr.append(errors.elementAt(ii));;
+ }
+ }
+ header.addStringValue("error", errorStr.toString());
+ header.addStringValue("revoked", "no");
+ // audit log the error
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (CertificateException e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ } catch (Exception e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ e.printStackTrace();
+ }
+
+ return;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
new file mode 100644
index 000000000..d3e7a5a32
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
@@ -0,0 +1,701 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Locale;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Takes the certificate info (serial number) and optional challenge phrase, creates a
+ * revocation request and submits it to the authority subsystem for processing
+ *
+ * @version $Revision$, $Date$
+ */
+public class ChallengeRevocationServlet1 extends CMSServlet {
+ public final static String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ // revocation templates.
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String mRequestID = null;
+
+ // http params
+ public static final String SERIAL_NO = TOKEN_CERT_SERIAL;
+ public static final String REASON_CODE = "reasonCode";
+ public static final String CHALLENGE_PHRASE = "challengePhrase";
+
+ // request attributes
+ public static final String SERIALNO_ARRAY = "serialNoArray";
+
+ public ChallengeRevocationServlet1() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the file
+ * revocationResult.template for the response
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ String authorityId = mAuthority.getId();
+
+ mFormPath = "/" + authorityId + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param REASON_CODE the revocation reason
+ * <li>http.param b64eCertificate the base-64 encoded certificate to revoke
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ // for audit log
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ BigInteger[] serialNoArray = null;
+
+ if (authToken != null) {
+ serialNoArray = authToken.getInBigIntegerArray(SERIAL_NO);
+ }
+ // set revocation reason, default to unspecified if not set.
+ int reasonCode =
+ httpParams.getValueAsInt(REASON_CODE, 0);
+ // header.addIntegerValue("reason", reasonCode);
+ RevocationReason reason = RevocationReason.fromInt(reasonCode);
+
+ String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS);
+ Date invalidityDate = null;
+ String revokeAll = null;
+ int totalRecordCount = (serialNoArray != null)? serialNoArray.length:0;
+ int verifiedRecordCount = (serialNoArray != null)? serialNoArray.length:0;
+
+ X509CertImpl[] certs = null;
+
+ //for audit log.
+ String initiative = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ // request is from agent
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "revoke");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (serialNoArray != null && serialNoArray.length > 0) {
+ if (mAuthority instanceof ICertificateAuthority) {
+ certs = new X509CertImpl[serialNoArray.length];
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ certs[i] = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificate(serialNoArray[i]);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest getCertsChallengeReq = null;
+
+ getCertsChallengeReq = mQueue.newRequest(
+ GETCERTS_FOR_CHALLENGE_REQUEST);
+ getCertsChallengeReq.setExtData(SERIALNO_ARRAY, serialNoArray);
+ mQueue.processRequest(getCertsChallengeReq);
+ RequestStatus status = getCertsChallengeReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ certs = getCertsChallengeReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ header.addStringValue("request", getCertsChallengeReq.getRequestId().toString());
+ mRequestID = getCertsChallengeReq.getRequestId().toString();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_GET_CERT_CHALL_PWRD"));
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", serialNoArray.length);
+ header.addIntegerValue("verifiedRecordCount", serialNoArray.length);
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ serialNoArray[i], 16);
+ rarg.addStringValue("subject",
+ certs[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certs[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certs[i].getNotAfter().getTime() / 1000);
+ //argSet.addRepeatRecord(rarg);
+ }
+
+ revokeAll = "(|(certRecordId=" + serialNoArray[0].toString() + "))";
+ process(argSet, header, reasonCode, invalidityDate, initiative, req, resp,
+ verifiedRecordCount, revokeAll, totalRecordCount,
+ comments, locale[0]);
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if( serialNoArray == null ) {
+ CMS.debug( "ChallengeRevcationServlet1::process() - " +
+ " serialNoArray is null!" );
+ EBaseException ee = new EBaseException( "No matched certificate is found" );
+
+ cmsReq.setError(ee);
+ return;
+ }
+
+ if (serialNoArray.length == 0) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ EBaseException ee = new EBaseException("No matched certificate is found");
+
+ cmsReq.setError(ee);
+ } else if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int reason, Date invalidityDate,
+ String initiative,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ int verifiedRecordCount,
+ String revokeAll,
+ int totalRecordCount,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate " +
+ cert.getSerialNumber().toString() +
+ " is already revoked.");
+ } else {
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = null;
+
+ if (mRequestID != null && mRequestID.length() > 0)
+ reqIdStr = mRequestID;
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() &&
+ legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.size() > 0) {
+ IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr));
+ X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ for (int i = 0; i < certs.length; i++) {
+ boolean addToList = false;
+
+ for (int j = 0; j < serialNumbers.size(); j++) {
+ if (certs[i].getSerialNumber().toString().equals(
+ (String) serialNumbers.elementAt(j))) {
+ addToList = true;
+ break;
+ }
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ certs[i].getSerialNumber(), 16);
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } else {
+ String b64eCert = req.getParameter("b64eCertificate");
+
+ if (b64eCert != null) {
+ byte[] certBytes = com.netscape.osutil.OSUtil.AtoB(b64eCert);
+ X509CertImpl cert = new X509CertImpl(certBytes);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+
+ mQueue.processRequest(revReq);
+ RequestStatus stat = revReq.getRequestStatus();
+
+ if (stat == RequestStatus.COMPLETE) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ header.addStringValue("revoked", "yes");
+
+ Integer updateCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ header.addStringValue("updateCRL", "yes");
+ if (updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("updateCRLSuccess", "yes");
+ } else {
+ header.addStringValue("updateCRLSuccess", "no");
+ String crlError =
+ revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null)
+ header.addStringValue("updateCRLError",
+ crlError);
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("publishCRLSuccess", "yes");
+ } else {
+ header.addStringValue("publishCRLSuccess", "no");
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null)
+ header.addStringValue("publishCRLError",
+ publError);
+ }
+ }
+ }
+ if (mAuthority instanceof ICertificateAuthority) {
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = revReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (updateResult.equals(IRequest.RES_SUCCESS)) {
+ CMS.debug("ChallengeRevcationServlet1: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("ChallengeRevcationServlet1: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(updateErrorStr);
+
+ if (error != null)
+ header.addStringValue(updateErrorStr,
+ error);
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ revReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (publishResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue(publishStatusStr, "yes");
+ } else {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ header.addStringValue(publishStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(publishErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ publishErrorStr, error);
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ revReq.getExtDataInIntegerArray("ldapPublishStatus");
+ int certsToUpdate = 0;
+ int certsUpdated = 0;
+
+ if (ldapPublishStatus != null) {
+ certsToUpdate = ldapPublishStatus.length;
+ for (int i = 0; i < certsToUpdate; i++) {
+ if (ldapPublishStatus[i] == IRequest.RES_SUCCESS) {
+ certsUpdated++;
+ }
+ }
+ }
+ header.addIntegerValue("certsUpdated", certsUpdated);
+ header.addIntegerValue("certsToUpdate", certsToUpdate);
+
+ // add crl publishing status.
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ header.addStringValue("crlPublishError",
+ publError);
+ }
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+ header.addStringValue("error", null);
+
+ } else if (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("revoked", "pending");
+ // audit log the pending
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "pending",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ } else {
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ StringBuffer errorStr = new StringBuffer();
+
+ if (errors != null && errors.size() > 0) {
+ for (int ii = 0; ii < errors.size(); ii++) {
+ errorStr.append(errors.elementAt(ii));
+ }
+ }
+ header.addStringValue("error", errorStr.toString());
+ header.addStringValue("revoked", "no");
+ // audit log the error
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java b/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java
new file mode 100644
index 000000000..59ee9a4ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java
@@ -0,0 +1,160 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Redirect a request to the Master. This servlet is used in
+ * a clone when a requested service (such as CRL) is not available.
+ * It redirects the user to the master.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CloneRedirect extends CMSServlet {
+
+ private final static String PROP_REDIRECT_URL = "masterURL";
+ private final static String TPL_FILE = "cloneRedirect.template";
+
+ private String mNewUrl = null;
+ private String mFormPath = null;
+
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs CloneRedirect servlet.
+ */
+ public CloneRedirect() {
+ super();
+
+ }
+
+ /**
+ * Initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ IConfigStore authConfig = mCA.getConfigStore();
+
+ if (authConfig != null) {
+ try {
+ mNewUrl = authConfig.getString(PROP_REDIRECT_URL,
+ "*** master URL unavailable, check your configuration ***");
+ } catch (EBaseException e) {
+ // do nothing
+ }
+ }
+ }
+
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output with our own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ CMS.debug("CloneRedirect: " + CMS.getLogMessage("ADMIN_SRVLT_ADD_MASTER_URL", mNewUrl));
+ header.addStringValue("masterURL", mNewUrl);
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Display information about redirecting to the master's URL info
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String signatureAlgorithm,
+ Locale locale)
+ throws EBaseException {
+
+ CMS.debug("CloneRedirect: " + CMS.getLogMessage("ADMIN_SRVLT_ADD_MASTER_URL", mNewUrl));
+ header.addStringValue("masterURL", mNewUrl);
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java
new file mode 100644
index 000000000..5e4309494
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java
@@ -0,0 +1,242 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * 'Face-to-face' certificate enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DirAuthServlet extends CMSServlet {
+ private final static String TPL_FILE = "/ra/hashEnrollmentSubmit.template";
+ private final static String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+ private String mFormPath = null;
+
+ public DirAuthServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = TPL_FILE;
+ } catch (Exception e) {
+ }
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+
+ /**
+ * Process the HTTP request. This servlet reads configuration information
+ * from the hashDirEnrollment configuration substore
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ boolean enable = mgr.isEnable(reqHost);
+
+ if (!enable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ String uid = args.getValueAsString("uid");
+ long pageid = mgr.getPageID();
+ String pageID = pageid + "";
+
+ mgr.addAuthToken(pageID, authToken);
+
+ header.addStringValue("pageID", pageID);
+ header.addStringValue("uid", uid);
+ header.addStringValue("fingerprint", mgr.hashFingerprint(reqHost, pageID, uid));
+ header.addStringValue("hostname", reqHost);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java
new file mode 100644
index 000000000..d75844d2a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java
@@ -0,0 +1,173 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * For Face-to-face enrollment, disable EE enrollment feature
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.cms.servlet.cert.EnableEnrollResult
+ */
+public class DisableEnrollResult extends CMSServlet {
+ private final static String TPL_FILE = "enableEnrollResult.template";
+ private String mFormPath = null;
+
+ public DisableEnrollResult() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken token = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "disable");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+
+ sslClientCert = getSSLClientCertificate(httpReq);
+ String dn = (String) sslClientCert.getSubjectDN().toString();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ String host = args.getValueAsString("hosts", null);
+ String name = mgr.getAgentName(host);
+
+ if (name == null) {
+ header.addStringValue("code", "2");
+ } else if (name.equals(dn)) {
+ mgr.disable(host);
+ header.addStringValue("code", "2");
+ } else {
+ header.addStringValue("code", "3");
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java
new file mode 100644
index 000000000..3a0c48a94
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java
@@ -0,0 +1,465 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Display detailed information about a certificate
+ *
+ * The template 'displayBySerial.template' is used to
+ * render the response for this servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerial extends CMSServlet {
+
+ private final static String INFO = "DisplayBySerial";
+ private final static String TPL_FILE1 = "displayBySerial.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mForm1Path = null;
+ private X509Certificate mCACerts[] = null;
+
+ /**
+ * Constructs DisplayBySerial servlet.
+ */
+ public DisplayBySerial() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ try {
+ mCACerts = ((ICertAuthority) mAuthority).getCACertChain().getChain();
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CA_CHAIN_NOT_AVAILABLE"));
+ }
+ // coming from ee
+ mForm1Path = "/" + mAuthority.getId() + "/" + TPL_FILE1;
+
+ if (mOutputTemplatePath != null)
+ mForm1Path = mOutputTemplatePath;
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is as follows:
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to display
+ * (or hex if serialNumber preceded by 0x)
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ BigInteger serialNumber = MINUS_ONE;
+ EBaseException error = null;
+ String certType[] = new String[1];
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ serialNumber = getSerialNumber(req);
+ ICertRecord rec = getCertRecord(serialNumber, certType);
+
+ if (certType[0].equalsIgnoreCase("x509")) {
+ form = getTemplate(mForm1Path, req, locale);
+ }
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", String.valueOf(serialNumber)));
+
+ error = new ECMSGWException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mForm1Path, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ } catch (EDBRecordNotFoundException e) {
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", "0x" + serialNumber.toString(16)));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ try {
+ if (serialNumber.compareTo(MINUS_ONE) > 0) {
+ process(argSet, header, serialNumber,
+ req, resp, locale[0]);
+ } else {
+ error = new ECMSGWException(
+ CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUMBER"));
+ }
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ }
+
+ /**
+ * Display information about a particular certificate
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger seq, HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ String certType[] = new String[1];
+
+ try {
+ ICertRecord rec = getCertRecord(seq, certType);
+
+ if (certType[0].equalsIgnoreCase("x509")) {
+ processX509(argSet, header, seq, req, resp, locale);
+ return;
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ }
+
+ return;
+ }
+
+ private void processX509(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger seq, HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ ICertRecord rec = (ICertRecord) mCertDB.readCertificateRecord(seq);
+ if (rec == null) {
+ CMS.debug("DisplayBySerial: failed to read record");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ X509CertImpl cert = rec.getCertificate();
+ if (cert == null) {
+ CMS.debug("DisplayBySerial: no certificate in record");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+
+ try {
+ X509CertInfo info = (X509CertInfo) cert.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ if (info == null) {
+ CMS.debug("DisplayBySerial: no info found");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
+
+ boolean emailCert = false;
+
+ if (extensions != null) {
+ for (int i = 0; i < extensions.size(); i++) {
+ Extension ext = (Extension) extensions.elementAt(i);
+
+ if (ext instanceof NSCertTypeExtension) {
+ NSCertTypeExtension type = (NSCertTypeExtension) ext;
+
+ if (((Boolean) type.get(NSCertTypeExtension.EMAIL)).booleanValue())
+ emailCert = true;
+ }
+ if (ext instanceof KeyUsageExtension) {
+ KeyUsageExtension usage =
+ (KeyUsageExtension) ext;
+
+ try {
+ if (((Boolean) usage.get(KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue() ||
+ ((Boolean) usage.get(KeyUsageExtension.DATA_ENCIPHERMENT)).booleanValue())
+ emailCert = true;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // bug356108:
+ // In case there is only DIGITAL_SIGNATURE,
+ // don't report error
+ }
+ }
+ }
+ }
+ header.addBooleanValue("emailCert", emailCert);
+
+ boolean noCertImport = true;
+ MetaInfo metaInfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+
+ if (metaInfo != null) {
+ String rid = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+
+ if (rid != null && mAuthority instanceof ICertificateAuthority) {
+ IRequest r = ((ICertificateAuthority) mAuthority).getRequestQueue().findRequest(new RequestId(rid));
+ String certType = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType != null && certType.equals(IRequest.CLIENT_CERT)) {
+ noCertImport = false;
+ }
+ }
+ }
+ header.addBooleanValue("noCertImport", noCertImport);
+
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_PARSING_EXTENS", e.toString()));
+ }
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enumx = crlExts.getElements();
+ int reason = 0;
+
+ while (enumx.hasMoreElements()) {
+ Extension ext = (Extension) enumx.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ }
+ }
+ header.addIntegerValue("revocationReason", reason);
+ }
+ }
+
+ ICertPrettyPrint certDetails = CMS.getCertPrettyPrint(cert);
+
+ header.addStringValue("certPrettyPrint",
+ certDetails.toString(locale));
+
+ /*
+ String scheme = req.getScheme();
+ if (scheme.equals("http") && connectionIsSSL(req))
+ scheme = "https";
+ String requestURI = req.getRequestURI();
+ int i = requestURI.indexOf('?');
+ String newRequestURI =
+ (i > -1)? requestURI.substring(0, i): requestURI;
+ header.addStringValue("serviceURL", scheme +"://"+
+ req.getServerName() + ":"+
+ req.getServerPort() + newRequestURI);
+ */
+ header.addStringValue("authorityid", mAuthority.getId());
+
+ String certFingerprints = "";
+
+ try {
+ certFingerprints = CMS.getFingerPrints(cert);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DIGESTING_CERT", e.toString()));
+ }
+ if (certFingerprints.length() > 0)
+ header.addStringValue("certFingerprint", certFingerprints);
+
+ byte[] ba = cert.getEncoded();
+ // Do base 64 encoding
+
+ header.addStringValue("certChainBase64", com.netscape.osutil.OSUtil.BtoA(ba));
+ header.addStringValue("serialNumber", seq.toString(16));
+
+ /*
+ String userAgent = req.getHeader("user-agent");
+ String agent =
+ (userAgent != null)? UserInfo.getUserAgent(userAgent): "";
+ */
+ // Now formulate a PKCS#7 blob
+ X509CertImpl[] certsInChain = new X509CertImpl[1];;
+ if (mCACerts != null) {
+ for (int i = 0; i < mCACerts.length; i++) {
+ if (cert.equals(mCACerts[i])) {
+ certsInChain = new
+ X509CertImpl[mCACerts.length];
+ break;
+ }
+ certsInChain = new X509CertImpl[mCACerts.length + 1];
+ }
+ }
+
+ // Set the EE cert
+ certsInChain[0] = cert;
+
+ // Set the Ca certificate chain
+ if (mCACerts != null) {
+ for (int i = 0; i < mCACerts.length; i++) {
+ if (!cert.equals(mCACerts[i]))
+ certsInChain[i + 1] = (X509CertImpl) mCACerts[i];
+ }
+ }
+
+ // Wrap the chain into a degenerate P7 object
+ String p7Str;
+
+ try {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ certsInChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos,false);
+ byte[] p7Bytes = bos.toByteArray();
+
+ p7Str = com.netscape.osutil.OSUtil.BtoA(p7Bytes);
+ header.addStringValue("pkcs7ChainBase64", p7Str);
+ } catch (Exception e) {
+ //p7Str = "PKCS#7 B64 Encoding error - " + e.toString()
+ //+ "; Please contact your administrator";
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7"));
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("MSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_ENCODE_CERT", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+
+ return;
+ }
+
+ private ICertRecord getCertRecord(BigInteger seq, String certtype[])
+ throws EBaseException {
+ ICertRecord rec = null;
+
+ try {
+ rec = (ICertRecord) mCertDB.readCertificateRecord(seq);
+ X509CertImpl x509cert = rec.getCertificate();
+
+ if (x509cert != null) {
+ certtype[0] = "x509";
+ return rec;
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ }
+
+ return rec;
+ }
+
+ private BigInteger getSerialNumber(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ if (serialNumString != null) {
+ serialNumString = serialNumString.trim();
+ if (serialNumString.startsWith("0x") || serialNumString.startsWith("0X")) {
+ return new BigInteger(serialNumString.substring(2), 16);
+ } else {
+ return new BigInteger(serialNumString);
+ }
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
new file mode 100644
index 000000000..9c7b022dd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
@@ -0,0 +1,469 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CRLException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Decode the CRL and display it to the requester.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayCRL extends CMSServlet {
+
+ private final static String INFO = "DisplayCRL";
+ private final static String TPL_FILE = "displayCRL.template";
+ //private final static String E_TPL_FILE = "error.template";
+ //private final static String OUT_ERROR = "errorDetails";
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs DisplayCRL servlet.
+ */
+ public DisplayCRL() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the 'displayCRL.template' file to
+ * to render the response to the client.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ }
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Process the HTTP request
+ * <ul>
+ * <li>http.param crlIssuingPoint number
+ * <li>http.param crlDisplayType entireCRL or crlHeader or base64Encoded or deltaCRL
+ * <li>http.param pageStart which page to start displaying from
+ * <li>http.param pageSize number of entries to show per page
+ * </ul>
+ * @param cmsReq the Request to service.
+
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE_1", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // Note error is covered in the same template as success.
+ EBaseException error = null;
+
+ String crlIssuingPointId = req.getParameter("crlIssuingPoint");
+
+ process(argSet, header, req, resp, crlIssuingPointId,
+ locale[0]);
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Display information about a particular CRL.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String crlIssuingPointId,
+ Locale locale) {
+ boolean updateStatus = true;
+ EBaseException error = null;
+ ICRLIssuingPoint crlIP = null;
+ X509CRLImpl crl = null;
+ boolean clonedCA = false;
+ boolean isCRLCacheEnabled = false;
+ String masterHost = null;
+ String masterPort = null;
+ Vector ipNames = null;
+ String ipId = crlIssuingPointId;
+ ICRLRepository crlRepository = mCA.getCRLRepository();
+
+ try {
+ masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+ clonedCA = true;
+ ipNames = crlRepository.getIssuingPointsNames();
+ }
+ } catch (EBaseException e) {
+ }
+
+ if (clonedCA) {
+ if (crlIssuingPointId != null) {
+ if (ipNames != null && ipNames.size() > 0) {
+ int i;
+ for (i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+ if (crlIssuingPointId.equals(ipName)) {
+ break;
+ }
+ }
+ if (i >= ipNames.size()) crlIssuingPointId = null;
+ } else {
+ crlIssuingPointId = null;
+ }
+ }
+ } else {
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ crlIP = ip;
+ isCRLCacheEnabled = ip.isCRLCacheEnabled();
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ }
+ if (crlIssuingPointId == null) {
+ header.addStringValue("error",
+ "Request to unspecified or non-existing CRL issuing point: "+ipId);
+ return;
+ }
+
+ ICRLIssuingPointRecord crlRecord = null;
+
+ String crlDisplayType = req.getParameter("crlDisplayType");
+
+ if (crlDisplayType == null) crlDisplayType = "cachedCRL";
+ header.addStringValue("crlDisplayType", crlDisplayType);
+
+ try {
+ crlRecord =
+ (ICRLIssuingPointRecord) mCA.getCRLRepository().readCRLIssuingPointRecord(crlIssuingPointId);
+ } catch (EBaseException e) {
+ header.addStringValue("error", e.toString(locale));
+ return;
+ }
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ return;
+ }
+
+ header.addStringValue("crlIssuingPoint", crlIssuingPointId);
+ if (crlDisplayType.equals("deltaCRL")) {
+ if (clonedCA) {
+ header.addStringValue("crlNumber", crlRecord.getDeltaCRLNumber().toString());
+ } else {
+ header.addStringValue("crlNumber", crlIP.getDeltaCRLNumber().toString());
+ }
+ } else {
+ if (clonedCA) {
+ header.addStringValue("crlNumber", crlRecord.getCRLNumber().toString());
+ } else {
+ header.addStringValue("crlNumber", crlIP.getCRLNumber().toString());
+ }
+ }
+ long lCRLSize = crlRecord.getCRLSize().longValue();
+ header.addLongValue("crlSize", lCRLSize);
+
+ if (crlIP != null) {
+ header.addStringValue("crlDescription", crlIP.getDescription());
+ }
+
+ if (!crlDisplayType.equals("cachedCRL")) {
+ byte[] crlbytes = crlRecord.getCRL();
+
+ if (crlbytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ return;
+ }
+
+ try {
+ if (crlDisplayType.equals("crlHeader")) {
+ crl = new X509CRLImpl(crlbytes, false);
+ } else {
+ crl = new X509CRLImpl(crlbytes);
+ }
+
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_CRL", e.toString()));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ }
+
+ if (crl != null || (isCRLCacheEnabled && crlDisplayType.equals("cachedCRL"))) {
+ if (crlDisplayType.equals("entireCRL") || crlDisplayType.equals("cachedCRL")) {
+ ICRLPrettyPrint crlDetails = null;
+ if (crlDisplayType.equals("entireCRL")) {
+ crlDetails = CMS.getCRLPrettyPrint(crl);
+ } else {
+ crlDetails = CMS.getCRLCachePrettyPrint(crlIP);
+ }
+
+ String pageStart = req.getParameter("pageStart");
+ String pageSize = req.getParameter("pageSize");
+
+ if (pageStart != null && pageSize != null) {
+ long lPageStart = new Long(pageStart).longValue();
+ long lPageSize = new Long(pageSize).longValue();
+
+ if (lPageStart < 1) lPageStart = 1;
+ // if (lPageStart + lPageSize - lCRLSize > 1)
+ // lPageStart = lCRLSize - lPageSize + 1;
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale,
+ lCRLSize, lPageStart, lPageSize));
+ header.addLongValue("pageStart", lPageStart);
+ header.addLongValue("pageSize", lPageSize);
+ } else {
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale));
+ }
+ } else if (crlDisplayType.equals("crlHeader")) {
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale, lCRLSize, 0, 0));
+ } else if (crlDisplayType.equals("base64Encoded")) {
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ if (i >= length) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else if (crlDisplayType.equals("deltaCRL")) {
+ if ((clonedCA && crlRecord.getDeltaCRLSize() != null &&
+ crlRecord.getDeltaCRLSize().longValue() > -1) ||
+ (crlIP != null && crlIP.isDeltaCRLEnabled())) {
+ byte[] deltaCRLBytes = crlRecord.getDeltaCRL();
+
+ if (deltaCRLBytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_NO_DELTA_CRL", crlIssuingPointId));
+ header.addStringValue("error", "Delta CRL is not available");
+ } else {
+ X509CRLImpl deltaCRL = null;
+
+ try {
+ deltaCRL = new X509CRLImpl(deltaCRLBytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_DELTA_CRL", e.toString()));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ if (deltaCRL != null) {
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ if ((clonedCA && crlNumber != null && deltaNumber != null &&
+ deltaNumber.compareTo(crlNumber) >= 0) ||
+ (crlIP != null && crlIP.isThisCurrentDeltaCRL(deltaCRL))) {
+
+ header.addIntegerValue("deltaCRLSize",
+ deltaCRL.getNumberOfRevokedCertificates());
+
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(deltaCRL);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale, 0, 0, 0));
+
+ try {
+ byte[] ba = deltaCRL.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ if (i >= length) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else {
+ header.addStringValue("error", "Current Delta CRL is not available.");
+ }
+ }
+ }
+ } else {
+ header.addStringValue("error", "Delta CRL is not enabled for " +
+ crlIssuingPointId +
+ " issuing point");
+ }
+ }
+
+ } else if (!isCRLCacheEnabled && crlDisplayType.equals("cachedCRL")) {
+ header.addStringValue("error", CMS.getUserMessage(locale, "CMS_GW_CRL_CACHE_IS_NOT_ENABLED", crlIssuingPointId));
+ header.addStringValue("crlPrettyPrint", CMS.getUserMessage(locale, "CMS_GW_CRL_CACHE_IS_NOT_ENABLED", crlIssuingPointId));
+ } else {
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ header.addStringValue("crlPrettyPrint",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
new file mode 100644
index 000000000..0062a4e7e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
@@ -0,0 +1,231 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Servlet to report the status, ie, the agent-initiated user
+ * enrollment is enabled or disabled.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayHashUserEnroll extends CMSServlet {
+ private final static String TPL_FILE = "/ra/hashDirUserEnroll.template";
+ private final static String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+ private String mFormPath = null;
+
+ public DisplayHashUserEnroll() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = TPL_FILE;
+ } catch (Exception e) {
+ }
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+ boolean isEnable = mgr.isEnable(reqHost);
+
+ if (!isEnable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
new file mode 100644
index 000000000..6c66f49e5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
@@ -0,0 +1,1156 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevoke extends CMSServlet {
+
+ private final static String INFO = "DoRevoke";
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private Nonces mNonces = null;
+ private int mTimeLimits = 30; /* in seconds */
+ private IUGSubsystem mUG = null;
+ private ICertUserLocator mUL = null;
+
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoRevoke() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template
+ * file "revocationResult.template" to render the result
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ mUL = mUG.getCertUserLocator();
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ if (((ICertificateAuthority) mAuthority).noncesEnabled()) {
+ mNonces = ((ICertificateAuthority) mAuthority).getNonces();
+ }
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ /* Server-Side time limit */
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ }
+
+ /**
+ * Serves HTTP request. The http parameters used by this request are as follows:
+ * <pre>
+ * serialNumber Serial number of certificate to revoke (in HEX)
+ * revocationReason Revocation reason (Described below)
+ * totalRecordCount [number]
+ * verifiedRecordCount [number]
+ * invalidityDate [number of seconds in Jan 1,1970]
+ *
+ * </pre>
+ * revocationReason can be one of these values:
+ * <pre>
+ * 0 = Unspecified (default)
+ * 1 = Key compromised
+ * 2 = CA key compromised
+ * 3 = Affiliation changed
+ * 4 = Certificate superseded
+ * 5 = Cessation of operation
+ * 6 = Certificate is on hold
+ * </pre>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ String revokeAll = null;
+ int totalRecordCount = -1;
+ int verifiedRecordCount = -1;
+ EBaseException error = null;
+ int reason = -1;
+ boolean authorized = true;
+ Date invalidityDate = null;
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ if (req.getParameter("revocationReason") != null) {
+ reason = Integer.parseInt(req.getParameter(
+ "revocationReason"));
+ }
+ if (req.getParameter("totalRecordCount") != null) {
+ totalRecordCount = Integer.parseInt(req.getParameter(
+ "totalRecordCount"));
+ }
+ if (req.getParameter("verifiedRecordCount") != null) {
+ verifiedRecordCount = Integer.parseInt(
+ req.getParameter(
+ "verifiedRecordCount"));
+ }
+ if (req.getParameter("invalidityDate") != null) {
+ long l = Long.parseLong(req.getParameter(
+ "invalidityDate"));
+
+ if (l > 0) {
+ invalidityDate = new Date(l);
+ }
+ }
+ revokeAll = req.getParameter("revokeAll");
+
+ if (mNonces != null) {
+ boolean nonceVerified = false;
+ boolean skipNonceVerification = false;
+
+ X509Certificate cert2 = getSSLClientCertificate(req);
+ if (cert2 != null) {
+ X509Certificate certChain[] = new X509Certificate[1];
+ certChain[0] = cert2;
+ IUser user = null;
+ try {
+ user = (IUser) mUL.locateUser(new Certificates(certChain));
+ } catch (Exception e) {
+ CMS.debug("DoRevoke: Failed to map certificate '"+
+ cert2.getSubjectDN().getName()+"' to user.");
+ }
+ if (mUG.isMemberOf(user, "Subsystem Group")) {
+ skipNonceVerification = true;
+ }
+ }
+
+ String nonceStr = req.getParameter("nonce");
+ if (nonceStr != null) {
+ long nonce = Long.parseLong(nonceStr.trim());
+ X509Certificate cert1 = mNonces.getCertificate(nonce);
+ if (cert1 == null) {
+ CMS.debug("DoRevoke: Unknown nonce");
+ } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) {
+ nonceVerified = true;
+ mNonces.removeNonce(nonce);
+ }
+ } else {
+ CMS.debug("DoRevoke: Missing nonce");
+ }
+ CMS.debug("DoRevoke: nonceVerified="+nonceVerified);
+ CMS.debug("DoRevoke: skipNonceVerification="+skipNonceVerification);
+ if ((!nonceVerified) && (!skipNonceVerification)) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+ }
+
+ String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS);
+ String eeSubjectDN = null;
+ String eeSerialNumber = null;
+
+ //for audit log.
+ String initiative = null;
+
+ String authMgr = AuditFormat.NOAUTH;
+
+ authToken = authenticate(req);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "revoke");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ // request is fromUser.
+ initiative = AuditFormat.FROMUSER;
+
+ String serialNumber = req.getParameter("serialNumber");
+ X509CertImpl sslCert = (X509CertImpl) getSSLClientCertificate(req);
+
+ if (serialNumber == null || sslCert == null ||
+ !(serialNumber.equals(sslCert.getSerialNumber().toString(16)))) {
+ authorized = false;
+ } else {
+ eeSubjectDN = sslCert.getSubjectDN().toString();
+ eeSerialNumber = sslCert.getSerialNumber().toString();
+ }
+ }
+
+ if (authorized) {
+ process(argSet, header, reason, invalidityDate, initiative,
+ req, resp, verifiedRecordCount, revokeAll,
+ totalRecordCount, eeSerialNumber, eeSubjectDN,
+ comments, locale[0]);
+ }
+
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ /*
+ catch (Exception e) {
+ noError = false;
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ errorlocale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null && authorized) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else if (!authorized) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Process cert status change request
+ * <P>
+ *
+ * (Certificate Request - either an "agent" cert status change request,
+ * or an "EE" cert status change request)
+ * <P>
+ *
+ * (Certificate Request Processed - either an "agent" cert status change
+ * request, or an "EE" cert status change request)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when
+ * a cert status change request (e. g. - "revocation") is made (before
+ * approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+ * used when a certificate status is changed (revoked, expired, on-hold,
+ * off-hold)
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param reason revocation reason (0 - Unspecified, 1 - Key compromised,
+ * 2 - CA key compromised; should not be used, 3 - Affiliation changed,
+ * 4 - Certificate superceded, 5 - Cessation of operation, or
+ * 6 - Certificate is on hold)
+ * @param invalidityDate certificate validity date
+ * @param initiative string containing the audit format
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param verifiedRecordCount number of verified records
+ * @param revokeAll string containing information on all of the
+ * certificates to be revoked
+ * @param totalRecordCount total number of records (verified and unverified)
+ * @param eeSerialNumber string containing the end-entity certificate
+ * serial number
+ * @param eeSubjectDN string containing the end-entity certificate subject
+ * distinguished name (DN)
+ * @param comments string containing certificate comments
+ * @param locale the system locale
+ * @exception EBaseException an error has occurred
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int reason, Date invalidityDate,
+ String initiative,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ int verifiedRecordCount,
+ String revokeAll,
+ int totalRecordCount,
+ String eeSerialNumber,
+ String eeSubjectDN,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(eeSerialNumber);
+ String auditRequestType = auditRequestType(reason);
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(reason);
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null)
+ continue;
+ X509CertImpl xcert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ // we do not want to revoke the CA certificate accidentially
+ if (xcert != null && isSystemCertificate(xcert.getSerialNumber())) {
+ CMS.debug("DoRevoke: skipped revocation request for system certificate " + xcert.getSerialNumber());
+ continue;
+ }
+
+ if (xcert != null) {
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+
+ if (eeSerialNumber != null &&
+ (eeSerialNumber.equals(xcert.getSerialNumber().toString())) &&
+ rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERTIFICATE_ALREADY_REVOKED_1", xcert.getSerialNumber().toString(16)));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED"));
+ } else if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate 0x" +
+ xcert.getSerialNumber().toString(16) +
+ " is already revoked.");
+ } else if (eeSubjectDN != null &&
+ (!eeSubjectDN.equals(xcert.getSubjectDN().toString()))) {
+ rarg.addStringValue("error", "Certificate 0x" +
+ xcert.getSerialNumber().toString(16) +
+ " belongs to different subject.");
+ } else {
+ oldCertsV.addElement(xcert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(xcert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = req.getParameter("requestId");
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ // xxxx decimal serial number?
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() && legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.size() > 0) {
+ IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr));
+ X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ boolean authorized = false;
+
+ for (int i = 0; i < certs.length; i++) {
+ boolean addToList = false;
+
+ for (int j = 0; j < serialNumbers.size();
+ j++) {
+ //xxxxx serial number in decimal?
+ if (certs[i].getSerialNumber().toString().equals((String) serialNumbers.elementAt(j)) &&
+ eeSubjectDN != null && eeSubjectDN.equals(certs[i].getSubjectDN().toString())) {
+ addToList = true;
+ break;
+ }
+ }
+ if (eeSerialNumber != null &&
+ eeSerialNumber.equals(certs[i].getSerialNumber().toString())) {
+ authorized = true;
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ certs[i].getSerialNumber().toString(16));
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ if (!authorized) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQ_AUTH_REVOKED_CERT"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED"));
+ }
+ } else {
+ String b64eCert = req.getParameter("b64eCertificate");
+
+ if (b64eCert != null) {
+ // BASE64Decoder decoder = new BASE64Decoder();
+ // byte[] certBytes = decoder.decodeBuffer(b64eCert);
+ byte[] certBytes = CMS.AtoB(b64eCert);
+ X509CertImpl cert = new X509CertImpl(certBytes);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ cert.getSerialNumber().toString(16));
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ if (count == 0) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REV_CERTS_ZERO"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_REVOCATION_ERROR_CERT_NOT_FOUND"));
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ //Certificate[] oldCerts = new Certificate[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ if(initiative.equals(AuditFormat.FROMUSER))
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_EE);
+ else
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+ revReq.setExtData(IRequest.REVOKED_REASON,
+ Integer.valueOf(reason));
+
+ // change audit processing from "REQUEST" to "REQUEST_PROCESSED"
+ // to distinguish which type of signed audit log message to save
+ // as a failure outcome in case an exception occurs
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+ String type = revReq.getRequestType();
+
+ // The SVC_PENDING check has been added for the Cloned CA request
+ // that is meant for the Master CA. From Clone's point of view
+ // the request is complete
+ if ((stat == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_CERT4CRL_REQUEST)) && (stat == RequestStatus.SVC_PENDING))) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString() + " time: " + (endTime - startTime)}
+ );
+ }
+ }
+ }
+
+ header.addStringValue("revoked", "yes");
+
+ Integer updateCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ header.addStringValue("updateCRL", "yes");
+ if (updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("updateCRLSuccess", "yes");
+ } else {
+ header.addStringValue("updateCRLSuccess", "no");
+ String crlError =
+ revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null)
+ header.addStringValue("updateCRLError",
+ crlError);
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("publishCRLSuccess", "yes");
+ } else {
+ header.addStringValue("publishCRLSuccess", "no");
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null)
+ header.addStringValue("publishCRLError",
+ publError);
+ }
+ }
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = revReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (updateResult.equals(IRequest.RES_SUCCESS)) {
+ CMS.debug("DoRevoke: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER", updateStatusStr));
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("DoRevoke: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(updateErrorStr);
+
+ if (error != null)
+ header.addStringValue(updateErrorStr,
+ error);
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ revReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (publishResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue(publishStatusStr, "yes");
+ } else {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ header.addStringValue(publishStatusStr, "no");
+ String error =
+ revReq.getExtDataInString(publishErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ publishErrorStr, error);
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ revReq.getExtDataInIntegerArray("ldapPublishStatus");
+ int certsToUpdate = 0;
+ int certsUpdated = 0;
+
+ if (ldapPublishStatus != null) {
+ certsToUpdate = ldapPublishStatus.length;
+ for (int i = 0; i < certsToUpdate; i++) {
+ if (ldapPublishStatus[i] == IRequest.RES_SUCCESS) {
+ certsUpdated++;
+ }
+ }
+ }
+ header.addIntegerValue("certsUpdated", certsUpdated);
+ header.addIntegerValue("certsToUpdate", certsToUpdate);
+
+ // add crl publishing status.
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ header.addStringValue("crlPublishError",
+ publError);
+ }
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+ header.addStringValue("error", null);
+
+ } else {
+ if (stat == RequestStatus.PENDING || stat == RequestStatus.REJECTED) {
+ header.addStringValue("revoked", stat.toString());
+ } else {
+ header.addStringValue("revoked", "no");
+ }
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ if (errors != null) {
+ StringBuffer errInfo = new StringBuffer();
+ for (int i = 0; i < errors.size(); i++) {
+ errInfo.append(errors.elementAt(i));
+ errInfo.append("\n");
+ }
+ header.addStringValue("error", errInfo.toString());
+
+ } else if (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ } else {
+ header.addStringValue("error", null);
+ }
+
+ // audit log the pending, revoked and rest
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (CertificateException e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ return;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
new file mode 100644
index 000000000..08756a5ba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
@@ -0,0 +1,911 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevokeTPS extends CMSServlet {
+
+ private final static String INFO = "DoRevoke";
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String errorString = "error=";
+ private String o_status = "status=0";
+ private int mTimeLimits = 30; /* in seconds */
+
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoRevokeTPS() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template
+ * file "revocationResult.template" to render the result
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ mRenderResult = false;
+
+ /* Server-Side time limit */
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ }
+
+ /**
+ * Serves HTTP request. The http parameters used by this request are as follows:
+ * <pre>
+ * serialNumber Serial number of certificate to revoke (in HEX)
+ * revocationReason Revocation reason (Described below)
+ * totalRecordCount [number]
+ * verifiedRecordCount [number]
+ * invalidityDate [number of seconds in Jan 1,1970]
+ *
+ * </pre>
+ * revocationReason can be one of these values:
+ * <pre>
+ * 0 = Unspecified (default)
+ * 1 = Key compromised
+ * 2 = CA key compromised
+ * 3 = Affiliation changed
+ * 4 = Certificate superseded
+ * 5 = Cessation of operation
+ * 6 = Certificate is on hold
+ * </pre>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ CMS.debug("DoRevokeTPS after authenticate");
+
+ String revokeAll = null;
+ int totalRecordCount = -1;
+ EBaseException error = null;
+ int reason = -1;
+ boolean authorized = true;
+ Date invalidityDate = null;
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ CMS.debug("DoRevokeTPS before getTemplate");
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ } catch (Exception e) {
+ CMS.debug("DoRevokeTPS getTemplate failed");
+ throw new EBaseException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ CMS.debug("DoRevokeTPS after getTemplate");
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ if (req.getParameter("revocationReason") != null) {
+ reason = Integer.parseInt(req.getParameter(
+ "revocationReason"));
+ }
+ if (req.getParameter("totalRecordCount") != null) {
+ totalRecordCount = Integer.parseInt(req.getParameter(
+ "totalRecordCount"));
+ }
+ if (req.getParameter("invalidityDate") != null) {
+ long l = Long.parseLong(req.getParameter(
+ "invalidityDate"));
+
+ if (l > 0) {
+ invalidityDate = new Date(l);
+ }
+ }
+ revokeAll = req.getParameter("revokeAll");
+ String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS);
+
+ //for audit log.
+ String initiative = null;
+
+ String authMgr = AuditFormat.NOAUTH;
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "revoke");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ CMS.debug("DoRevokeTPS: Missing authentication manager");
+ o_status = "status=1";
+ errorString = "errorString=Missing authentication manager.";
+ }
+
+ if (authorized) {
+ process(argSet, header, reason, invalidityDate, initiative, req,
+ resp, revokeAll, totalRecordCount, comments, locale[0]);
+ }
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (!authorized) {
+ o_status = "status=3";
+ errorString = "error=unauthorized";
+ } else if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error.toString();
+ }
+
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Process cert status change request
+ * <P>
+ *
+ * (Certificate Request - either an "agent" cert status change request,
+ * or an "EE" cert status change request)
+ * <P>
+ *
+ * (Certificate Request Processed - either an "agent" cert status change
+ * request, or an "EE" cert status change request)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when
+ * a cert status change request (e. g. - "revocation") is made (before
+ * approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+ * used when a certificate status is changed (revoked, expired, on-hold,
+ * off-hold)
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param reason revocation reason (0 - Unspecified, 1 - Key compromised,
+ * 2 - CA key compromised; should not be used, 3 - Affiliation changed,
+ * 4 - Certificate superceded, 5 - Cessation of operation, or
+ * 6 - Certificate is on hold)
+ * @param invalidityDate certificate validity date
+ * @param initiative string containing the audit format
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param revokeAll string containing information on all of the
+ * certificates to be revoked
+ * @param totalRecordCount total number of records (verified and unverified)
+ * @param comments string containing certificate comments
+ * @param locale the system locale
+ * @exception EBaseException an error has occurred
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int reason, Date invalidityDate,
+ String initiative,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll,
+ int totalRecordCount,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(null);
+ String auditRequestType = auditRequestType(reason);
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(reason);
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ boolean alreadyRevokedCertFound = false;
+ boolean badCertsRequested = false;
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null) {
+ badCertsRequested = true;
+ continue;
+ }
+ X509CertImpl xcert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ // we do not want to revoke the CA certificate accidentially
+ if (xcert != null && isSystemCertificate(xcert.getSerialNumber())) {
+ CMS.debug("DoRevokeTPS: skipped revocation request for system certificate " + xcert.getSerialNumber());
+ badCertsRequested = true;
+ continue;
+ }
+
+ if (xcert != null) {
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ alreadyRevokedCertFound = true;
+ CMS.debug("Certificate 0x"+xcert.getSerialNumber().toString(16) + " has been revoked.");
+ } else {
+ oldCertsV.addElement(xcert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(xcert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ CMS.debug("Certificate 0x"+xcert.getSerialNumber().toString(16)+" is going to be revoked.");
+ count++;
+ }
+ } else {
+ badCertsRequested = true;
+ }
+ }
+
+ if (count == 0) {
+ // Situation where no certs were reoked here, but some certs
+ // requested happened to be already revoked. Don't return error.
+ if (alreadyRevokedCertFound == true && badCertsRequested == false) {
+ CMS.debug("Only have previously revoked certs in the list.");
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ return;
+ }
+
+ errorString = "error=No certificates are revoked.";
+ o_status = "status=2";
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REV_CERTS_ZERO"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ if(initiative.equals(AuditFormat.FROMUSER)) {
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_EE);
+ } else {
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ }
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+ revReq.setExtData(IRequest.REVOKED_REASON,
+ Integer.valueOf(reason));
+
+ // change audit processing from "REQUEST" to "REQUEST_PROCESSED"
+ // to distinguish which type of signed audit log message to save
+ // as a failure outcome in case an exception occurs
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+ String type = revReq.getRequestType();
+
+ // The SVC_PENDING check has been added for the Cloned CA request
+ // that is meant for the Master CA. From Clone's point of view
+ // the request is complete
+ if ((stat == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_CERT4CRL_REQUEST)) && (stat == RequestStatus.SVC_PENDING))) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString() + " time: " + (endTime - startTime)}
+ );
+ }
+ }
+ }
+
+ header.addStringValue("revoked", "yes");
+
+ Integer updateCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ if (!updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+
+ o_status = "status=3";
+ if (revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR) != null) {
+ errorString = "error=Update CRL Error.";
+ // 3 means miscellaneous
+ }
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (!publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ o_status = "status=3";
+ if (publError != null) {
+ errorString = "error="+publError;
+ }
+ }
+ }
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = revReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (!updateResult.equals(IRequest.RES_SUCCESS)) {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("DoRevoke: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO",
+ updateStatusStr));
+ String error =
+ revReq.getExtDataInString(updateErrorStr);
+
+ o_status = "status=3";
+ if (error != null) {
+ errorString = "error="+error;
+ }
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ revReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (!publishResult.equals(IRequest.RES_SUCCESS)) {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ String error =
+ revReq.getExtDataInString(publishErrorStr);
+
+ o_status = "status=3";
+ if (error != null) {
+ errorString = "error=Publish CRL Status Error.";
+ }
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ revReq.getExtDataInIntegerArray("ldapPublishStatus");
+ int certsToUpdate = 0;
+ int certsUpdated = 0;
+
+ if (ldapPublishStatus != null) {
+ certsToUpdate = ldapPublishStatus.length;
+ for (int i = 0; i < certsToUpdate; i++) {
+ if (ldapPublishStatus[i] == IRequest.RES_SUCCESS) {
+ certsUpdated++;
+ }
+ }
+ }
+
+ // add crl publishing status.
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ errorString = "error="+publError;
+ o_status = "status=3";
+ }
+ } else if (mPublisherProcessor == null && mPublisherProcessor.ldapEnabled()) {
+ errorString = "error=LDAP publishing not enabled.";
+ o_status = "status=3";
+ }
+ } else {
+ if (stat == RequestStatus.PENDING || stat == RequestStatus.REJECTED) {
+ o_status = "status=2";
+ errorString = "error="+stat.toString();
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+ }
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ if (errors != null) {
+ StringBuffer errInfo = new StringBuffer();
+
+ for (int i = 0; i < errors.size(); i++) {
+ errInfo.append(errors.elementAt(i));
+ errInfo.append("\n");
+ }
+ o_status = "status=2";
+ errorString = "error=" + errInfo.toString();
+
+ } else if (stat == RequestStatus.PENDING) {
+ o_status = "status=2";
+ errorString = "error=Request pending";
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+ }
+
+ // audit log the pending, revoked and rest
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ return;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
new file mode 100644
index 000000000..2f125beb7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
@@ -0,0 +1,659 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.lang.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevoke extends CMSServlet {
+
+ private final static String INFO = "DoUnrevoke";
+ private final static String TPL_FILE = "unrevocationResult.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+
+ private final static String OFF_HOLD = "off-hold";
+ private final static int OFF_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoUnrevoke() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to unrevoke. The
+ * certificate must be revoked with a revovcation reason 'on hold' for this
+ * operation to succeed. The serial number may be expressed as a hex number by
+ * prefixing '0x' to the serialNumber string
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ BigInteger[] serialNumber;
+ EBaseException error = null;
+
+ CMSTemplate form = null;
+
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ serialNumber = getSerialNumbers(req);
+
+ //for audit log.
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ } else {
+ CMS.debug( "DoUnrevoke::process() - authToken is null!" );
+ return;
+ }
+ String agentID = authToken.getInString("userid");
+ String initiative = AuditFormat.FROMAGENT + " agentID: " + agentID
+ + " authenticated by " + authMgr;
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "unrevoke");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ process(argSet, header, serialNumber, req, resp, locale[0], initiative);
+
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUM_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+
+ /**
+ * Process X509 cert status change request
+ * <P>
+ *
+ * (Certificate Request - an "agent" cert status change request to take
+ * a certificate off-hold)
+ * <P>
+ *
+ * (Certificate Request Processed - an "agent" cert status change request
+ * to take a certificate off-hold)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when
+ * a cert status change request (e. g. - "revocation") is made (before
+ * approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+ * used when a certificate status is changed (taken off-hold)
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param serialNumbers the serial number of the certificate
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ * @param initiative string containing the audit format
+ * @exception EBaseException an error has occurred
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger[] serialNumbers,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale, String initiative)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(serialNumbers[0].toString());
+ String auditRequestType = OFF_HOLD;
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(OFF_HOLD_REASON);
+
+ try {
+ StringBuffer snList = new StringBuffer();
+
+ // certs are for old cloning and they should be removed as soon as possible
+ X509CertImpl[] certs = new X509CertImpl[serialNumbers.length];
+ for (int i = 0; i < serialNumbers.length; i++) {
+ certs[i] = (X509CertImpl)getX509Certificate(serialNumbers[i]);
+ if (snList.length() > 0) snList.append(", ");
+ snList.append("0x");
+ snList.append(serialNumbers[i].toString(16));
+ }
+ header.addStringValue("serialNumber", snList.toString());
+
+ IRequest unrevReq = mQueue.newRequest(IRequest.UNREVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ unrevReq.setExtData(IRequest.REQ_TYPE, IRequest.UNREVOCATION_REQUEST);
+ unrevReq.setExtData(IRequest.OLD_SERIALS, serialNumbers);
+ unrevReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ // change audit processing from "REQUEST" to "REQUEST_PROCESSED"
+ // to distinguish which type of signed audit log message to save
+ // as a failure outcome in case an exception occurs
+ auditRequest = false;
+
+ mQueue.processRequest(unrevReq);
+
+ // retrieve the request status
+ auditApprovalStatus = unrevReq.getRequestStatus().toString();
+
+ RequestStatus status = unrevReq.getRequestStatus();
+ String type = unrevReq.getRequestType();
+
+ if ((status == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) && (status == RequestStatus.SVC_PENDING))) {
+
+ Integer result = unrevReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && result.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("unrevoked", "yes");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ header.addStringValue("unrevoked", "no");
+ String error = unrevReq.getExtDataInString(IRequest.ERROR);
+
+ if (error != null) {
+ header.addStringValue("error", error);
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ error,
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+
+ /****************************************************/
+
+ /* IMPORTANT: In the event that the following */
+
+ /* "throw error;" statement is */
+
+ /* uncommented, uncomment the following */
+
+ /* signed audit log message, also!!! */
+
+ /****************************************************/
+
+ // // store a message in the signed audit log file
+ // // if and only if "auditApprovalStatus" is
+ // // "complete", "revoked", or "canceled"
+ // if( ( auditApprovalStatus.equals(
+ // RequestStatus.COMPLETE_STRING ) ) ||
+ // ( auditApprovalStatus.equals(
+ // RequestStatus.REJECTED_STRING ) ) ||
+ // ( auditApprovalStatus.equals(
+ // RequestStatus.CANCELED_STRING ) ) ) {
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditRequesterID,
+ // auditSerialNumber,
+ // auditRequestType,
+ // auditReasonNum,
+ // auditApprovalStatus );
+ //
+ // audit( auditMessage );
+ // }
+
+ // throw error;
+ }
+ }
+
+ Integer updateCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ header.addStringValue("updateCRL", "yes");
+ if (updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("updateCRLSuccess", "yes");
+ } else {
+ header.addStringValue("updateCRLSuccess", "no");
+ String crlError =
+ unrevReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null)
+ header.addStringValue("updateCRLError",
+ crlError);
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("publishCRLSuccess", "yes");
+ } else {
+ header.addStringValue("publishCRLSuccess", "no");
+ String publError =
+ unrevReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null)
+ header.addStringValue("publishCRLError",
+ publError);
+ }
+ }
+ }
+
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = unrevReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (updateResult.equals(IRequest.RES_SUCCESS)) {
+ CMS.debug("DoUnrevoke: adding header " +
+ updateStatusStr + " yes ");
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("DoUnrevoke: adding header " +
+ updateStatusStr + " no ");
+ header.addStringValue(updateStatusStr, "no");
+ String error =
+ unrevReq.getExtDataInString(updateErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ updateErrorStr, error);
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ unrevReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (publishResult.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue(publishStatusStr, "yes");
+ } else {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ header.addStringValue(publishStatusStr, "no");
+ String error =
+ unrevReq.getExtDataInString(publishErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ publishErrorStr, error);
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ unrevReq.getExtDataInIntegerArray("ldapPublishStatus");
+
+ if (ldapPublishStatus != null) {
+ if (ldapPublishStatus[0] == IRequest.RES_SUCCESS) {
+ header.addStringValue("dirUpdated", "yes");
+ } else {
+ header.addStringValue("dirUpdated", "no");
+ }
+ }
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+
+ } else if (status == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("unrevoked", "pending");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "pending",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ header.addStringValue("error", "Request Status.Error");
+ header.addStringValue("unrevoked", "no");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ status.toString(),
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (EBaseException eAudit1) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+ }
+
+ return;
+ }
+
+ private BigInteger[] getSerialNumbers(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ StringTokenizer snList = new StringTokenizer(serialNumString, " ");
+ Vector biList = new Vector();
+ while (snList.hasMoreTokens()) {
+ String snStr = snList.nextToken();
+ if (snStr != null) {
+ snStr = snStr.trim();
+ BigInteger bi;
+ if (snStr.startsWith("0x") || snStr.startsWith("0X")) {
+ bi = new BigInteger(snStr.substring(2), 16);
+ } else {
+ bi = new BigInteger(snStr);
+ }
+ if (bi.compareTo(BigInteger.ZERO) < 0) {
+ throw new NumberFormatException();
+ }
+ biList.addElement(bi);
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+ if (biList.size() < 1) {
+ throw new NumberFormatException();
+ }
+
+ BigInteger[] biNumbers = new BigInteger[biList.size()];
+ for (int i = 0; i < biList.size(); i++) {
+ biNumbers[i] = (BigInteger) biList.elementAt(i);
+ }
+
+ return biNumbers;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
new file mode 100644
index 000000000..8c290d0a7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
@@ -0,0 +1,613 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.lang.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevokeTPS extends CMSServlet {
+
+ private final static String INFO = "DoUnrevoke";
+ private final static String TPL_FILE = "unrevocationResult.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String errorString = "error=";
+ private String o_status = "status=0";
+
+ private final static String OFF_HOLD = "off-hold";
+ private final static int OFF_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoUnrevokeTPS() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mRenderResult = false;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to unrevoke. The
+ * certificate must be revoked with a revovcation reason 'on hold' for this
+ * operation to succeed. The serial number may be expressed as a hex number by
+ * prefixing '0x' to the serialNumber string
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ BigInteger[] serialNumbers;
+ EBaseException error = null;
+
+ CMSTemplate form = null;
+
+ Locale[] locale = new Locale[1];
+
+/*
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+*/
+
+ try {
+ serialNumbers = getSerialNumbers(req);
+
+ //for audit log.
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ } else {
+ CMS.debug( "DoUnrevokeTPS::process() - authToken is null!" );
+ return;
+ }
+ String agentID = authToken.getInString("userid");
+ String initiative = AuditFormat.FROMAGENT + " agentID: " + agentID
+ + " authenticated by " + authMgr;
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "unrevoke");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ o_status = "status=3";
+ errorString = "error=unauthorized";
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ return;
+ }
+
+ process(serialNumbers, req, resp, locale[0], initiative);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUM_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ } catch (IOException e) {
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ o_status = "status=0";
+ errorString = "error=";
+ } else {
+ o_status = "status=3";
+ errorString = "error="+error.toString();
+ }
+
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+
+ /**
+ * Process X509 cert status change request
+ * <P>
+ *
+ * (Certificate Request - an "agent" cert status change request to take
+ * a certificate off-hold)
+ * <P>
+ *
+ * (Certificate Request Processed - an "agent" cert status change request
+ * to take a certificate off-hold)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when
+ * a cert status change request (e. g. - "revocation") is made (before
+ * approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED
+ * used when a certificate status is changed (taken off-hold)
+ * </ul>
+ * @param serialNumbers the serial number of the certificate
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ * @param initiative string containing the audit format
+ * @exception EBaseException an error has occurred
+ */
+ private void process(BigInteger[] serialNumbers,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale, String initiative)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(serialNumbers[0].toString());
+ String auditRequestType = OFF_HOLD;
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(OFF_HOLD_REASON);
+
+ try {
+ String snList = "";
+
+ // certs are for old cloning and they should be removed as soon as possible
+ X509CertImpl[] certs = new X509CertImpl[serialNumbers.length];
+ for (int i = 0; i < serialNumbers.length; i++) {
+ certs[i] = (X509CertImpl)getX509Certificate(serialNumbers[i]);
+ if (snList.length() > 0) snList += ", ";
+ snList += "0x" + serialNumbers[i].toString(16);
+ }
+
+ IRequest unrevReq = mQueue.newRequest(IRequest.UNREVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ unrevReq.setExtData(IRequest.REQ_TYPE, IRequest.UNREVOCATION_REQUEST);
+ unrevReq.setExtData(IRequest.OLD_SERIALS, serialNumbers);
+ unrevReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ // change audit processing from "REQUEST" to "REQUEST_PROCESSED"
+ // to distinguish which type of signed audit log message to save
+ // as a failure outcome in case an exception occurs
+ auditRequest = false;
+
+ mQueue.processRequest(unrevReq);
+
+ // retrieve the request status
+ auditApprovalStatus = unrevReq.getRequestStatus().toString();
+
+ RequestStatus status = unrevReq.getRequestStatus();
+ String type = unrevReq.getRequestType();
+
+ if ((status == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) && (status == RequestStatus.SVC_PENDING))) {
+
+ Integer result = unrevReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && result.equals(IRequest.RES_SUCCESS)) {
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ String error = unrevReq.getExtDataInString(IRequest.ERROR);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ error,
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+ }
+
+ Integer updateCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ if (!updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String crlError =
+ unrevReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null) {
+ o_status = "status=3";
+ errorString = "error="+crlError;
+ }
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (!publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String publError =
+ unrevReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ o_status = "status=3";
+ errorString = "error="+publError;
+ }
+ }
+ }
+ }
+
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = unrevReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (!updateResult.equals(IRequest.RES_SUCCESS)) {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+ String error =
+ unrevReq.getExtDataInString(updateErrorStr);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ }
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ unrevReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (!publishResult.equals(IRequest.RES_SUCCESS)) {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ String error =
+ unrevReq.getExtDataInString(publishErrorStr);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ Integer[] ldapPublishStatus =
+ unrevReq.getExtDataInIntegerArray("ldapPublishStatus");
+
+ if (ldapPublishStatus != null) {
+ if (ldapPublishStatus[0] != IRequest.RES_SUCCESS) {
+ o_status = "status=3";
+ errorString = "error=Problem in publishing to LDAP";
+ }
+ }
+ } else if (mPublisherProcessor == null || (! mPublisherProcessor.ldapEnabled())) {
+ o_status = "status=3";
+ errorString = "error=LDAP Publisher not enabled";
+ }
+
+ } else if (status == RequestStatus.PENDING) {
+ o_status = "status=2";
+ errorString = "error="+status.toString();
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "pending",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ status.toString(),
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (EBaseException eAudit1) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+ }
+
+ return;
+ }
+
+ private BigInteger[] getSerialNumbers(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ StringTokenizer snList = new StringTokenizer(serialNumString, " ");
+ Vector biList = new Vector();
+ while (snList.hasMoreTokens()) {
+ String snStr = snList.nextToken();
+ if (snStr != null) {
+ snStr = snStr.trim();
+ BigInteger bi;
+ if (snStr.startsWith("0x") || snStr.startsWith("0X")) {
+ bi = new BigInteger(snStr.substring(2), 16);
+ } else {
+ bi = new BigInteger(snStr);
+ }
+ if (bi.compareTo(BigInteger.ZERO) < 0) {
+ throw new NumberFormatException();
+ }
+ biList.addElement(bi);
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+ if (biList.size() < 1) {
+ throw new NumberFormatException();
+ }
+
+ BigInteger[] biNumbers = new BigInteger[biList.size()];
+ for (int i = 0; i < biList.size(); i++) {
+ biNumbers[i] = (BigInteger) biList.elementAt(i);
+ }
+
+ return biNumbers;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java b/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java
new file mode 100644
index 000000000..a469e674e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java
@@ -0,0 +1,183 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * For Face-to-face enrollment, enable EE enrollment feature
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.cms.servlet.cert.DisableEnrollResult
+ */
+public class EnableEnrollResult extends CMSServlet {
+ private final static String TPL_FILE = "enableEnrollResult.template";
+ private String mFormPath = null;
+ private Random random = null;
+
+ public EnableEnrollResult() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ random = new Random();
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "enable");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+
+ sslClientCert = getSSLClientCertificate(httpReq);
+ String dn = (String) sslClientCert.getSubjectDN().toString();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String machine = configStore.getString("machineName");
+ String port = CMS.getEESSLPort();
+
+ header.addStringValue("machineName", machine);
+ header.addStringValue("port", port);
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ String host = args.getValueAsString("hostname", null);
+ boolean isEnable = mgr.isEnable(host);
+
+ if (isEnable) {
+ header.addStringValue("code", "1");
+ } else {
+ String timeout = args.getValueAsString("timeout", "600");
+
+ mgr.createEntry(host, dn, Long.parseLong(timeout) * 1000,
+ random.nextLong() + "", 0);
+ header.addStringValue("code", "0");
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
new file mode 100644
index 000000000..a0de7ebdd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
@@ -0,0 +1,1831 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+
+import java.io.*;
+
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
+
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.cms.servlet.processors.PKIProcessor;
+import com.netscape.cms.servlet.processors.CMCProcessor;
+import com.netscape.cms.servlet.processors.CRMFProcessor;
+import com.netscape.cms.servlet.processors.KeyGenProcessor;
+import com.netscape.cms.servlet.processors.PKCS10Processor;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.policy.IPolicyProcessor;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.math.*;
+
+
+/**
+ * Submit a Certificate Enrollment request
+ *
+ * @version $Revision$, $Date$
+ */
+public class EnrollServlet extends CMSServlet {
+ public final static String ADMIN_ENROLL_SERVLET_ID = "caadminEnroll";
+
+ // enrollment templates.
+ public static final String
+ ENROLL_SUCCESS_TEMPLATE = "EnrollSuccess.template";
+
+ // http params
+ public static final String OLD_CERT_TYPE = "csrCertType";
+ public static final String CERT_TYPE = "certType";
+ // same as in ConfigConstant.java
+ public static final String REQUEST_FORMAT = "reqFormat";
+ public static final String REQUEST_FORMAT_PKCS10 = "PKCS10";
+ public static final String REQUEST_FORMAT_CMC = "CMC";
+ public static final String REQUEST_CONTENT = "requestContent";
+ public static final String SUBJECT_KEYGEN_INFO = "subjectKeyGenInfo";
+ public static final String PKCS10_REQUEST = "pkcs10Request";
+ public static final String CMC_REQUEST = "cmcRequest";
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public static final String SUBJECT_NAME = "subject";
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String CHALLENGE_PASSWORD = "challengePhrase";
+
+ private static final String CERT_AUTH_DUAL = "dual";
+ private static final String CERT_AUTH_ENCRYPTION = "encryption";
+ private static final String CERT_AUTH_SINGLE = "single";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+
+ private boolean mAuthTokenOverride = true;
+ private String mEnrollSuccessTemplate = null;
+ private ICMSTemplateFiller
+ mEnrollSuccessFiller = new ImportCertsTemplateFiller();
+
+ ICertificateAuthority mCa = null;
+ ICertificateRepository mRepository = null;
+
+ private boolean enforcePop = false;
+
+ private String auditServiceID = ILogger.UNIDENTIFIED;
+ private final static String ADMIN_CA_ENROLLMENT_SERVLET =
+ "caadminEnroll";
+ private final static String AGENT_CA_BULK_ENROLLMENT_SERVLET =
+ "cabulkissuance";
+ private final static String AGENT_RA_BULK_ENROLLMENT_SERVLET =
+ "rabulkissuance";
+ private final static String EE_CA_CERT_BASED_ENROLLMENT_SERVLET =
+ "cacertbasedenrollment";
+ private final static String EE_CA_ENROLLMENT_SERVLET =
+ "caenrollment";
+ private final static String EE_RA_CERT_BASED_ENROLLMENT_SERVLET =
+ "racertbasedenrollment";
+ private final static String EE_RA_ENROLLMENT_SERVLET =
+ "raenrollment";
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String[]
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON = new String[] {
+
+ /* 0 */ "automated non-profile cert request rejection: "
+ + "unable to render OLD_CERT_TYPE response",
+
+ /* 1 */ "automated non-profile cert request rejection: "
+ + "unable to complete handleEnrollAuditLog() method",
+
+ /* 2 */ "automated non-profile cert request rejection: "
+ + "unable to render success template",
+
+ /* 3 */ "automated non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException"
+ };
+ private final static String
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST =
+ "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ private static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+ public EnrollServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.<p>
+ * the following parameters are read from the servlet config:
+ * <ul><li>CMSServlet.PROP_ID - ID for signed audit log messages
+ * <li>CMSServlet.PROP_SUCCESS_TEMPLATE - success template file
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ try {
+ super.init(sc);
+
+ CMS.debug("EnrollServlet: In Enroll Servlet init!");
+
+ try {
+ IConfigStore configStore = CMS.getConfigStore();
+ String PKI_Subsystem = configStore.getString( "subsystem.0.id",
+ null );
+
+ // CMS 6.1 began utilizing the "Certificate Profiles" framework
+ // instead of the legacy "Certificate Policies" framework.
+ //
+ // Beginning with CS 8.1, to meet the Common Criteria
+ // evaluation performed on this version of the product, it
+ // was determined that this legacy "Certificate Policies"
+ // framework would be deprecated and disabled by default
+ // (see Bugzilla Bug #472597).
+ //
+ // NOTE: The "Certificate Policies" framework ONLY applied to
+ // to CA, KRA, and legacy RA (pre-CMS 7.0) subsystems.
+ //
+ // Further, the "EnrollServlet.java" servlet is ONLY
+ // used by the CA for the following:
+ //
+ // SERVLET-NAME URL-PATTERN
+ // ====================================================
+ // caadminEnroll ca/admin/ca/adminEnroll.html
+ // cabulkissuance ca/agent/ca/bulkissuance.html
+ // cacertbasedenrollment ca/certbasedenrollment.html
+ // caenrollment ca/enrollment.html
+ //
+ // The "EnrollServlet.java" servlet is NOT used by
+ // the KRA.
+ //
+ if( PKI_Subsystem.trim().equalsIgnoreCase( "ca" ) ) {
+ String policyStatus = PKI_Subsystem.trim().toLowerCase()
+ + "." + "Policy"
+ + "." + IPolicyProcessor.PROP_ENABLE;
+
+ if( configStore.getBoolean( policyStatus, true ) == true ) {
+ // NOTE: If "<subsystem>.Policy.enable=<boolean>"
+ // is missing, then the referenced instance
+ // existed prior to this name=value pair
+ // existing in its 'CS.cfg' file, and thus
+ // we err on the side that the user may
+ // still need to use the policy framework.
+ CMS.debug( "EnrollServlet::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is ENABLED" );
+ } else {
+ // CS 8.1 Default: <subsystem>.Policy.enable=false
+ CMS.debug( "EnrollServlet::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is DISABLED" );
+ return;
+ }
+ }
+ } catch( EBaseException e ) {
+ throw new ServletException( "EnrollServlet::init - "
+ + "EBaseException: "
+ + "Unable to initialize "
+ + "Certificate Policy Framework "
+ + "(deprecated)" );
+ }
+
+ // override success template to allow direct import of keygen certs.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ try {
+ // determine the service ID for signed audit log messages
+ String id = sc.getInitParameter(CMSServlet.PROP_ID);
+
+ if (id != null) {
+ if (!(auditServiceID.equals(
+ ADMIN_CA_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ AGENT_CA_BULK_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ AGENT_RA_BULK_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_CA_CERT_BASED_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_CA_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_RA_CERT_BASED_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_RA_ENROLLMENT_SERVLET))) {
+ auditServiceID = ILogger.UNIDENTIFIED;
+ } else {
+ auditServiceID = id.trim();
+ }
+ }
+
+ mEnrollSuccessTemplate = sc.getInitParameter(
+ CMSServlet.PROP_SUCCESS_TEMPLATE);
+ if (mEnrollSuccessTemplate == null)
+ mEnrollSuccessTemplate = ENROLL_SUCCESS_TEMPLATE;
+ String fillername = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mEnrollSuccessFiller = filler;
+ }
+
+ // cfu
+ mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+
+ init_testbed_hack(mConfig);
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR",
+ e.toString(), mId));
+ }
+ } catch (ServletException eAudit1) {
+ // rethrow caught exception
+ throw eAudit1;
+ }
+ }
+
+
+ /**
+ * XXX (SHOULD CHANGE TO READ FROM Servletconfig)
+ * Getter method to see if Proof of Posession checking is enabled.
+ * this value is set in the CMS.cfg filem with the parameter
+ * "enrollment.enforcePop". It defaults to false
+ * @return true if user is required to Prove that they possess the
+ * private key corresponding to the public key in the certificate
+ * request they are submitting
+ */
+ public boolean getEnforcePop() {
+ return enforcePop;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <UL><LI>If the request is coming through the admin port, it is only
+ * allowed to continue if 'admin enrollment' is enabled in the CMS.cfg file
+ * <LI>If the CMS.cfg parameter useThreadNaming is true, the current thread is
+ * renamed with more information about the current request ID
+ * <LI>The request is preprocessed, then processed further in one
+ * of the cert request processor classes: KeyGenProcessor, PKCS10Processor,
+ * CMCProcessor, CRMFProcessor
+ * </UL>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ // SPECIAL CASE:
+ // if it is adminEnroll servlet,check if it's enabled
+ if (mId.equals(ADMIN_ENROLL_SERVLET_ID) &&
+ !CMSGateway.getEnableAdminEnroll()) {
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("ADMIN_SRVLT_ENROLL_ACCESS_AFTER_SETUP"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REDIRECTING_ADMINENROLL_ERROR", "Attempt to access adminEnroll after already setup."));
+ }
+
+ processX509(cmsReq);
+ }
+
+ private boolean getCertAuthEnrollStatus(IArgBlock httpParams) {
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+
+ String certAuthEnrollOn =
+ httpParams.getValueAsString("certauthEnroll", null);
+
+ if ((certAuthEnrollOn != null) && (certAuthEnrollOn.equals("on"))) {
+ certAuthEnroll = true;
+ CMS.debug("EnrollServlet: certAuthEnroll is on");
+ }
+
+ return certAuthEnroll;
+
+ }
+
+ private String getCertAuthEnrollType(IArgBlock httpParams, boolean certAuthEnroll)
+ throws EBaseException {
+
+ String certauthEnrollType = null;
+
+ if (certAuthEnroll == true) {
+ certauthEnrollType =
+ httpParams.getValueAsString("certauthEnrollType", null);
+ if (certauthEnrollType != null) {
+ if (certauthEnrollType.equals("dual")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is dual");
+ } else if (certauthEnrollType.equals("encryption")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is encryption");
+ } else if (certauthEnrollType.equals("single")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is single");
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERTAUTH_ENROLL_TYPE_1", certauthEnrollType));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERTAUTH_ENROLL_TYPE"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("MSGW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ }
+ }
+
+ return certauthEnrollType;
+
+ }
+
+ private boolean checkClientCertSigningOnly(X509Certificate sslClientCert)
+ throws EBaseException {
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+
+ return true;
+ }
+
+ private X509CertInfo[] handleCertAuthDual(X509CertInfo certInfo, IAuthToken authToken, X509Certificate sslClientCert,
+ ICertificateAuthority mCa, String certBasedOldSubjectDN,
+ BigInteger certBasedOldSerialNum)
+ throws EBaseException {
+
+ CMS.debug("EnrollServlet: In handleCertAuthDual!");
+
+ if (mCa == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_A_CA"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_A_CA"));
+ }
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+
+ try {
+
+ checkClientCertSigningOnly(sslClientCert);
+ } catch (ECMSGWException e) {
+
+ throw new ECMSGWException(e.toString());
+
+ }
+
+ X509Key key = null;
+
+ // for signing cert
+ key = (X509Key) sslClientCert.getPublicKey();
+ try {
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_IO", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ String filter =
+ "(&(x509cert.subject=" + certBasedOldSubjectDN + ")(!(x509cert.serialNumber=" + certBasedOldSerialNum + "))(certStatus=VALID))";
+ ICertRecordList list =
+ (ICertRecordList) mCa.getCertificateRepository().findCertRecordsInList(filter, null, 10);
+ int size = list.getSize();
+ Enumeration en = list.getCertRecords(0, size - 1);
+ boolean gotEncCert = false;
+
+ CMS.debug("EnrollServlet: signing cert filter " + filter);
+
+ if (!en.hasMoreElements()) {
+ CMS.debug("EnrollServlet: pairing encryption cert not found!");
+ return null;
+ // pairing encryption cert not found
+ } else {
+ X509CertInfo encCertInfo = CMS.getDefaultX509CertInfo();
+ X509CertInfo[] cInfoArray = new X509CertInfo[] {certInfo,
+ encCertInfo};
+ int i = 1;
+
+ boolean encCertFound = false;
+
+ while (en.hasMoreElements()) {
+ ICertRecord record = (ICertRecord) en.nextElement();
+ X509CertImpl cert = record.getCertificate();
+
+ // if not encryption cert only, try next one
+ if ((CMS.isEncryptionCert(cert) == false) ||
+ ((CMS.isEncryptionCert(cert) == true) &&
+ (CMS.isSigningCert(cert) == true))) {
+
+ CMS.debug("EnrollServlet: Not encryption only cert, will try next one.");
+ continue;
+ }
+
+ key = (X509Key) cert.getPublicKey();
+ CMS.debug("EnrollServlet: Found key for encryption cert.");
+ encCertFound = true;
+
+ try {
+ encCertInfo = (X509CertInfo)
+ cert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTINFO"));
+ }
+
+ try {
+ encCertInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ CMS.debug("EnrollServlet: About to fillCertInfoFromAuthToken!");
+ PKIProcessor.fillCertInfoFromAuthToken(encCertInfo, authToken);
+
+ cInfoArray[i++] = encCertInfo;
+ break;
+
+ }
+ if (encCertFound == false) {
+ CMS.debug("EnrollServlet: Leaving because Enc Cert not found.");
+ return null;
+ }
+
+ CMS.debug("EnrollServlet: returning cInfoArray of length " + cInfoArray.length);
+ return cInfoArray;
+ }
+
+ }
+
+ private boolean handleEnrollAuditLog(IRequest req, CMSRequest cmsReq, String authMgr, IAuthToken authToken,
+ X509CertInfo certInfo, long startTime)
+ throws EBaseException {
+ //for audit log
+
+ String initiative = null;
+ String agentID = null;
+
+ if (authToken == null) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // if service not complete return standard templates.
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus(); // set status acc. to IRequest status.
+ // audit log the status
+ try {
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT),
+ " violation: " +
+ wholeMsg.toString()}
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } else { // other imcomplete status
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT) + " time: " + (endTime - startTime), ""}
+ );
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+ return false;
+ }
+ // if service error use standard error templates.
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ // audit log the error
+ try {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ certInfo.get(X509CertInfo.SUBJECT), ""
+ }
+ );
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+
+ }
+ }
+ }
+ return false;
+
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Process X509 certificate enrollment request
+ * <P>
+ *
+ * (Certificate Request - either an "admin" cert request for an admin
+ * certificate, an "agent" cert request for "bulk enrollment", or
+ * an "EE" standard cert request)
+ * <P>
+ *
+ * (Certificate Request Processed - either an automated "admin" non-profile
+ * based CA admin cert acceptance, an automated "admin" non-profile based
+ * CA admin cert rejection, an automated "EE" non-profile based cert
+ * acceptance, or an automated "EE" non-profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST used when a
+ * non-profile cert request is made (before approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param cmsReq a certificate enrollment request
+ * @exception EBaseException an error has occurred
+ */
+ protected void processX509(CMSRequest cmsReq)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String id = null;
+
+ // define variables common to try-catch-blocks
+ long startTime = 0;
+ IArgBlock httpParams = null;
+ HttpServletRequest httpReq = null;
+ IAuthToken authToken = null;
+ AuthzToken authzToken = null;
+ IRequest req = null;
+ X509CertInfo certInfo = null;
+
+ IConfigStore configStore = CMS.getConfigStore();
+
+ /* XXX shouldn't we read this from ServletConfig at init time? */
+ enforcePop = configStore.getBoolean("enrollment.enforcePop", false);
+ CMS.debug("EnrollServlet: enforcePop " + enforcePop);
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ startTime = CMS.getCurrentDate().getTime();
+ httpParams = cmsReq.getHttpParams();
+ httpReq = cmsReq.getHttpReq();
+ if (mAuthMgr != null) {
+ authToken = authenticate(cmsReq);
+ }
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ // create enrollment request in request queue.
+ req = mRequestQueue.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ // retrieve the actual "auditRequesterID"
+ if (req != null) {
+ // overwrite "auditRequesterID" if and only if "id" != null
+ id = req.getRequestId().toString();
+ if (id != null) {
+ auditRequesterID = id.trim();
+ }
+ }
+
+ try {
+ if (CMS.getConfigStore().getBoolean("useThreadNaming", false)) {
+ String currentName = Thread.currentThread().getName();
+
+ Thread.currentThread().setName(currentName
+ + "-request-"
+ + req.getRequestId().toString()
+ + "-"
+ + (new Date()).getTime());
+ }
+ } catch (Exception e) {
+ }
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+ String certauthEnrollType = null;
+
+ certAuthEnroll = getCertAuthEnrollStatus(httpParams);
+
+ try {
+ if (certAuthEnroll == true) {
+ certauthEnrollType = getCertAuthEnrollType(httpParams,
+ certAuthEnroll);
+ }
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ CMS.debug("EnrollServlet: In EnrollServlet.processX509!");
+ CMS.debug("EnrollServlet: certAuthEnroll " + certAuthEnroll);
+ CMS.debug("EnrollServlet: certauthEnrollType " + certauthEnrollType);
+
+ String challengePassword = httpParams.getValueAsString(
+ "challengePassword", "");
+
+ cmsReq.setIRequest(req);
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+
+ X509Certificate sslClientCert = null;
+
+ // cert auth enroll
+ String certBasedOldSubjectDN = null;
+ BigInteger certBasedOldSerialNum = null;
+
+ // check if request was authenticated, if so set authtoken &
+ // certInfo. also if authenticated, take certInfo from authToken.
+ certInfo = null;
+ if (certAuthEnroll == true) {
+ sslClientCert = getSSLClientCertificate(httpReq);
+ if (sslClientCert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SSL_CLIENT_CERT"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SSL_CLIENT_CERT"));
+ }
+
+ certBasedOldSubjectDN = (String)
+ sslClientCert.getSubjectDN().toString();
+ certBasedOldSerialNum = (BigInteger)
+ sslClientCert.getSerialNumber();
+
+ CMS.debug("EnrollServlet: certBasedOldSubjectDN " + certBasedOldSubjectDN);
+ CMS.debug("EnrollServlet: certBasedOldSerialNum " + certBasedOldSerialNum);
+
+ // if the cert subject name is NOT MISSING, retrieve the
+ // actual "auditCertificateSubjectName" and "normalize" it
+ if (certBasedOldSubjectDN != null) {
+ // NOTE: This is ok even if the cert subject name
+ // is "" (empty)!
+ auditCertificateSubjectName = certBasedOldSubjectDN.trim();
+ }
+
+ try {
+ certInfo = (X509CertInfo)
+ ((X509CertImpl) sslClientCert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+ } else {
+ CMS.debug("EnrollServlet: No CertAuthEnroll.");
+ certInfo = CMS.getDefaultX509CertInfo();
+ }
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[] {certInfo};
+
+ X509CertInfo authCertInfo = null;
+ String authMgr = AuditFormat.NOAUTH;
+
+ // if authentication
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ // don't store agent token in request.
+ // agent currently used for bulk issuance.
+ // if (!authMgr.equals(AuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ log(ILogger.LL_INFO,
+ "Enrollment request was authenticated by " +
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME));
+
+ PKIProcessor.fillCertInfoFromAuthToken(certInfo,
+ authToken);
+ // save authtoken attrs to request directly
+ // (for policy use)
+ saveAuthToken(authToken, req);
+ // req.set(IRequest.AUTH_TOKEN, authToken);
+ // }
+ }
+
+ CMS.debug("EnrollServlet: Enroll authMgr " + authMgr);
+
+ if (certAuthEnroll == true) {
+ // log(ILogger.LL_DEBUG,
+ // "just gotten subjectDN and serialNumber " +
+ // "from ssl client cert");
+ if (authToken == null) {
+ // authToken is null, can't match to anyone; bail!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESS_ENROLL_NO_AUTH"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ return;
+ }
+ }
+
+ // fill certInfo from input types: keygen, cmc, pkcs10 or crmf
+ KeyGenInfo keyGenInfo = httpParams.getValueAsKeyGenInfo(
+ SUBJECT_KEYGEN_INFO, null);
+ PKCS10 pkcs10 = null;
+
+ String certType = null;
+
+ //
+ String test = httpParams.getValueAsString("certNickname", null);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ CMS.debug("EnrollServlet: certType " + certType);
+
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ CMS.debug("EnrollServlet: certType " + certType);
+ } else {
+ // some policies may rely on the fact that
+ // CERT_TYPE is set. So for 3.5.1 or eariler
+ // we need to set CERT_TYPE here.
+ req.setExtData(IRequest.HTTP_PARAMS, CERT_TYPE, certType);
+ }
+ if (certType.equals("client")) {
+ // coming from MSIE
+ String p10b64 = httpParams.getValueAsString(PKCS10_REQUEST,
+ null);
+
+ if (p10b64 != null) {
+ try {
+ byte[] bytes = CMS.AtoB(p10b64);
+
+ pkcs10 = new PKCS10(bytes);
+ } catch (Exception e) {
+ // ok, if the above fails, it could
+ // be a PKCS10 with header
+ pkcs10 = httpParams.getValueAsPKCS10(PKCS10_REQUEST,
+ false, null);
+ // e.printStackTrace();
+ }
+ }
+
+ //pkcs10 = httpParams.getValuePKCS10(PKCS10_REQUEST, null);
+
+ } else {
+ try {
+ // coming from server cut & paste blob.
+ pkcs10 = httpParams.getValueAsPKCS10(PKCS10_REQUEST,
+ false, null);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ String cmc = null;
+ String asciiBASE64Blob = httpParams.getValueAsString(CMC_REQUEST, null);
+
+ if(asciiBASE64Blob!=null)
+ {
+ int startIndex = asciiBASE64Blob.indexOf(HEADER);
+ int endIndex = asciiBASE64Blob.indexOf(TRAILER);
+ if (startIndex!= -1 && endIndex!=-1) {
+ startIndex = startIndex + HEADER.length();
+ cmc=asciiBASE64Blob.substring(startIndex, endIndex);
+ }else
+ cmc = asciiBASE64Blob;
+ CMS.debug("EnrollServlet: cmc " + cmc);
+ }
+
+ String crmf = httpParams.getValueAsString(CRMF_REQUEST, null);
+
+ CMS.debug("EnrollServlet: crmf " + crmf);
+
+ if (certAuthEnroll == true) {
+
+ PKIProcessor.fillCertInfoFromAuthToken(certInfo, authToken);
+
+ // for dual certs
+ if (certauthEnrollType.equals(CERT_AUTH_DUAL)) {
+
+ CMS.debug("EnrollServlet: Attempting CERT_AUTH_DUAL");
+ boolean gotEncCert = false;
+ X509CertInfo[] cInfoArray = null;
+
+ try {
+ cInfoArray = handleCertAuthDual(certInfo, authToken,
+ sslClientCert, mCa,
+ certBasedOldSubjectDN,
+ certBasedOldSerialNum);
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ if (cInfoArray != null && cInfoArray.length != 0) {
+ CMS.debug("EnrollServlet: cInfoArray Length " + cInfoArray.length);
+
+ certInfoArray = cInfoArray;
+ gotEncCert = true;
+ }
+
+ if (gotEncCert == false) {
+ // encryption cert not found, bail
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage(
+ "CMSGW_ENCRYPTION_CERT_NOT_FOUND"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCRYPTION_CERT_NOT_FOUND"));
+ }
+
+ } else if (certauthEnrollType.equals(CERT_AUTH_ENCRYPTION)) {
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+
+ try {
+
+ checkClientCertSigningOnly(sslClientCert);
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ /*
+ * either crmf or keyGenInfo
+ */
+ if (keyGenInfo != null) {
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq,
+ this);
+
+ keyGenProc.fillCertInfo(null, certInfo,
+ authToken, httpParams);
+
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug("EnrollServlet: sslClientCert issuerDN = " +
+ sslClientCert.getIssuerDN().toString());
+ } else if (crmf != null && crmf != "") {
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf,
+ authToken,
+ httpParams,
+ req);
+
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug("EnrollServlet: sslClientCert issuerDN = " +
+ sslClientCert.getIssuerDN().toString());
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+ } else if (certauthEnrollType.equals(CERT_AUTH_SINGLE)) {
+
+ // have to be buried here to handle the issuer
+
+ if (keyGenInfo != null) {
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq,
+ this);
+
+ keyGenProc.fillCertInfo(null, certInfo,
+ authToken, httpParams);
+ } else if (pkcs10 != null) {
+ PKCS10Processor pkcs10Proc = new PKCS10Processor(cmsReq,
+ this);
+
+ pkcs10Proc.fillCertInfo(pkcs10, certInfo,
+ authToken, httpParams);
+ } else if (cmc != null && cmc != "") {
+ CMCProcessor cmcProc = new CMCProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = cmcProc.fillCertInfoArray(cmc,
+ authToken,
+ httpParams,
+ req);
+ } else if (crmf != null && crmf != "") {
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf,
+ authToken,
+ httpParams,
+ req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ }
+
+ } else if (keyGenInfo != null) {
+
+ CMS.debug("EnrollServlet: Trying KeyGen with no cert auth.");
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq, this);
+
+ keyGenProc.fillCertInfo(null, certInfo, authToken, httpParams);
+ } else if (pkcs10 != null) {
+ CMS.debug("EnrollServlet: Trying PKCS10 with no cert auth.");
+ PKCS10Processor pkcs10Proc = new PKCS10Processor(cmsReq, this);
+
+ pkcs10Proc.fillCertInfo(pkcs10, certInfo, authToken, httpParams);
+ } else if (cmc != null) {
+ CMS.debug("EnrollServlet: Trying CMC with no cert auth.");
+ CMCProcessor cmcProc = new CMCProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = cmcProc.fillCertInfoArray(cmc, authToken,
+ httpParams, req);
+ } else if (crmf != null && crmf != "") {
+ CMS.debug("EnrollServlet: Trying CRMF with no cert auth.");
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf, authToken,
+ httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+
+ // if ca, fill in default signing alg here
+
+ try {
+ ICertificateAuthority caSub =
+ (ICertificateAuthority) CMS.getSubsystem("ca");
+ if (certInfoArray != null && caSub != null) {
+ for (int ix = 0; ix < certInfoArray.length; ix++) {
+ X509CertInfo ci = (X509CertInfo)certInfoArray[ix];
+ String defaultSig = caSub.getDefaultAlgorithm();
+ AlgorithmId algid = AlgorithmId.get(defaultSig);
+ ci.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(algid));
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("Failed to set signing alg to certinfo " + e.toString());
+ }
+
+ req.setExtData(IRequest.CERT_INFO, certInfoArray);
+
+
+ if (challengePassword != null && !challengePassword.equals("")) {
+ String pwd = hashPassword(challengePassword);
+
+ req.setExtData(CHALLENGE_PASSWORD, pwd);
+ }
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ X509CertImpl[] issuedCerts = null;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+ // process result.
+
+ // render OLD_CERT_TYPE's response differently, we
+ // do not want any javascript in HTML, and need to
+ // override the default render.
+ if (httpParams.getValueAsString(OLD_CERT_TYPE, null) != null) {
+ try {
+ renderServerEnrollResult(cmsReq);
+ cmsReq.setStatus(CMSRequest.SUCCESS); // no default render
+
+ issuedCerts =
+ cmsReq.getIRequest().getExtDataInCertArray(
+ IRequest.ISSUED_CERTS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed
+ // - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+ } catch (IOException ex) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[0]);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ boolean completed = handleEnrollAuditLog(req, cmsReq,
+ mAuthMgr, authToken,
+ certInfo, startTime);
+
+ if (completed == false) {
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[1]);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ // service success
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ issuedCerts = req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ String initiative = null;
+ String agentID;
+
+ if (authToken == null) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // audit log the success.
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[]
+ { req.getRequestId(),
+ initiative,
+ mAuthMgr,
+ "completed",
+ issuedCerts[0].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ issuedCerts[0].getSerialNumber().toString(16) +
+ " time: " +
+ (endTime - startTime) }
+ );
+
+ // handle initial admin enrollment if in adminEnroll mode.
+ checkAdminEnroll(cmsReq, issuedCerts);
+
+ // return cert as mime type binary if requested.
+ if (checkImportCertToNav(cmsReq.getHttpResp(),
+ httpParams, issuedCerts[0])) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ // use success template.
+ try {
+ cmsReq.setResult(issuedCerts);
+ renderTemplate(cmsReq, mEnrollSuccessTemplate,
+ mEnrollSuccessFiller);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_TEMP_REND_ERR",
+ mEnrollSuccessFiller.toString(),
+ e.toString()));
+
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[2]);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_RETURNING_RESULT_ERROR"));
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[3]);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ return;
+ }
+
+ /**
+ * check if this is first enroll from admin enroll.
+ * If so disable admin enroll from here on.
+ */
+ protected void checkAdminEnroll(CMSRequest cmsReq, X509CertImpl[] issuedCerts)
+ throws EBaseException {
+ // this is special case, get the admin certificate
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID)) {
+ addAdminAgent(cmsReq, issuedCerts);
+ CMSGateway.disableAdminEnroll();
+ }
+ }
+
+ protected void addAdminAgent(CMSRequest cmsReq, X509CertImpl[] issuedCerts)
+ throws EBaseException {
+ String userid = cmsReq.getHttpParams().getValueAsString("uid");
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ IUser adminuser = ug.createUser(userid);
+
+ adminuser.setX509Certificates(issuedCerts);
+ try {
+ ug.addUserCert(adminuser);
+ } catch (netscape.ldap.LDAPException e) {
+ CMS.debug(
+ "EnrollServlet: Cannot add admin's certificate to its entry in the " +
+ "user group database. Error " + e);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ADDING_ADMIN_CERT_ERROR", e.toString()));
+ }
+ IGroup agentGroup =
+ ug.getGroupFromName(CA_AGENT_GROUP);
+
+ if (agentGroup != null) {
+ // add user to the group if necessary
+ if (!agentGroup.isMember(userid)) {
+ agentGroup.addMemberName(userid);
+ ug.modifyGroup(agentGroup);
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT,
+ new Object[] {userid, userid, CA_AGENT_GROUP}
+ );
+
+ }
+ } else {
+ String msg = "Cannot add admin to the " +
+ CA_AGENT_GROUP +
+ " group: Group does not exist.";
+
+ CMS.debug("EnrollServlet: " + msg);
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_ADMIN_ERROR"));
+ }
+ }
+
+ protected void renderServerEnrollResult(CMSRequest cmsReq) throws
+ IOException {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = null;
+
+ out = httpResp.getOutputStream();
+
+ // get template based on request status
+ out.println("<HTML>");
+ out.println("<TITLE>");
+ out.println("Server Enrollment");
+ out.println("</TITLE>");
+ // out.println("<BODY BGCOLOR=white>");
+
+ if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ out.println("<H1>");
+ out.println("SUCCESS");
+ out.println("</H1>");
+ out.println("Your request is submitted and approved. Please cut and paste the certificate into your server."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("Certificate: ");
+ out.println("<P>");
+ out.println("<PRE>");
+ X509CertImpl certs[] =
+ cmsReq.getIRequest().getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ out.println(CMS.getEncodedCert(certs[0]));
+ out.println("</PRE>");
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ out.println("<!HTTP_OUTPUT X509_CERTIFICATE=" +
+ CMS.getEncodedCert(certs[0]) + ">");
+ } else if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.PENDING)) {
+ out.println("<H1>");
+ out.println("PENDING");
+ out.println("</H1>");
+ out.println("Your request is submitted. You can check on the status of your request with an authorized agent or local administrator by referring to the request ID."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ } else {
+ out.println("<H1>");
+ out.println("ERROR");
+ out.println("</H1>");
+ out.println("<!INFO>");
+ out.println("Please consult your local administrator for assistance."); // XXX - localize the message
+ out.println("<!/INFO>");
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Error: ");
+ out.println(cmsReq.getError()); // XXX - need to parse in Locale
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT ERROR=" +
+ cmsReq.getError() + ">");
+ }
+
+ /**
+ // include all the input data
+ ArgBlock args = cmsReq.getHttpParams();
+ Enumeration ele = args.getElements();
+ while (ele.hasMoreElements()) {
+ String eleT = (String)ele.nextElement();
+ out.println("<!HTTP_INPUT " + eleT + "=" +
+ args.get(eleT) + ">");
+ }
+ **/
+
+ out.println("</HTML>");
+ }
+
+ // XXX ALERT !!
+ // Remove the following and calls to them when we bundle a cartman
+ // later than alpha1.
+ // These are here to cover up problem in cartman where the
+ // key usage extension always ends up being digital signature only
+ // and for rsa-ex ends up having no bits set.
+
+ private boolean mIsTestBed = false;
+
+ private void init_testbed_hack(IConfigStore config)
+ throws EBaseException {
+ mIsTestBed = config.getBoolean("isTestBed", true);
+ }
+
+ private void do_testbed_hack(
+ int nummsgs, X509CertInfo[] certinfo, IArgBlock httpParams)
+ throws EBaseException {
+ if (!mIsTestBed)
+ return;
+
+ // get around bug in cartman - bits are off by one byte.
+ for (int i = 0; i < certinfo.length; i++) {
+ try {
+ X509CertInfo cert = certinfo[i];
+ CertificateExtensions exts = (CertificateExtensions)
+ cert.get(CertificateExtensions.NAME);
+
+ if (exts == null) {
+ // should not happen.
+ continue;
+ }
+ KeyUsageExtension ext = (KeyUsageExtension)
+ exts.get(KeyUsageExtension.NAME);
+
+ if (ext == null)
+ // should not happen
+ continue;
+ byte[] value = ext.getExtensionValue();
+
+ if (value[0] == 0x03 && value[1] == 0x02 && value[2] == 0x07) {
+ byte[] newvalue = new byte[value.length + 1];
+
+ newvalue[0] = 0x03;
+ newvalue[1] = 0x03;
+ newvalue[2] = 0x07;
+ newvalue[3] = value[3];
+ // force encryption certs to have digitial signature
+ // set too so smime can find the cert for encryption.
+ if (value[3] == 0x20) {
+
+ /*
+ newvalue[3] = 0x3f;
+ newvalue[4] = (byte)0x80;
+ */
+ if (httpParams.getValueAsBoolean(
+ "dual-use-hack", true)) {
+ newvalue[3] = (byte) 0xE0; // same as rsa-dual-use.
+ }
+ }
+ newvalue[4] = 0;
+ KeyUsageExtension newext =
+ new KeyUsageExtension(Boolean.valueOf(true),
+ (Object) newvalue);
+
+ exts.delete(KeyUsageExtension.NAME);
+ exts.set(KeyUsageExtension.NAME, newext);
+
+ }
+ } catch (IOException e) {
+ // should never happen
+ continue;
+ } catch (CertificateException e) {
+ // should never happen
+ continue;
+ }
+ }
+
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param x509cert an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(X509CertImpl x509cert) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ StringBuffer sb = new StringBuffer();
+ // extract all line separators from the "base64Data"
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ sb.append(base64Data.substring(i, i));
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java
new file mode 100644
index 000000000..196c56a9b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java
@@ -0,0 +1,292 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.crypto.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve certificate by serial number.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetBySerial extends CMSServlet {
+
+ private final static String INFO = "GetBySerial";
+
+ private final static String IMPORT_CERT_TEMPLATE = "ImportCert.template";
+ private String mImportTemplate = null;
+ private String mIETemplate = null;
+ private ICMSTemplateFiller mImportTemplateFiller = null;
+ IRequestQueue mReqQ = null;
+
+ public GetBySerial() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to import the cert to the users browser,
+ * if that is what the user requested
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ try {
+ mImportTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ mIETemplate = sc.getInitParameter("importCertTemplate");
+ if (mImportTemplate == null)
+ mImportTemplate = IMPORT_CERT_TEMPLATE;
+ } catch (Exception e) {
+ mImportTemplate = null;
+ }
+ mImportTemplateFiller = new ImportCertsTemplateFiller();
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ ICertificateAuthority mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+ if (mCa == null) {
+ return;
+ }
+
+ mReqQ = mCa.getRequestQueue();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber serial number of certificate in HEX
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ int serialNumber = -1;
+ boolean noError = true;
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+ IArgBlock args = cmsReq.getHttpParams();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "import");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String serial = args.getValueAsString("serialNumber", null);
+ String browser = args.getValueAsString("browser", null);
+ BigInteger serialNo = null;
+
+ try {
+ serialNo = new BigInteger(serial, 16);
+ } catch (NumberFormatException e) {
+ serialNo = null;
+ }
+ if (serial == null || serialNo == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUMBER"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_SERIAL_NUMBER")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ ICertRecord certRecord = (ICertRecord) getCertRecord(serialNo);
+ if (certRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", serialNo.toString(16)));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CERT_SERIAL_NOT_FOUND", "0x" + serialNo.toString(16))));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ // if RA, needs requestOwner to match
+ // first, find the user's group
+ if (authToken != null) {
+ String group = authToken.getInString("group");
+
+ if ((group != null) && (group != "")) {
+ CMS.debug("GetBySerial process: auth group="+group);
+ if (group.equals("Registration Manager Agents")) {
+ boolean groupMatched = false;
+ // find the cert record's orig. requestor's group
+ MetaInfo metai = certRecord.getMetaInfo();
+ if (metai != null) {
+ String reqId = (String) metai.get(ICertRecord.META_REQUEST_ID);
+ RequestId rid = new RequestId(reqId);
+ IRequest creq = mReqQ.findRequest(rid);
+ if (creq != null) {
+ String reqOwner = creq.getRequestOwner();
+ if (reqOwner != null) {
+ CMS.debug("GetBySerial process: req owner="+reqOwner);
+ if (reqOwner.equals(group))
+ groupMatched = true;
+ }
+ }
+ }
+ if (groupMatched == false) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", serialNo.toString(16)));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CERT_SERIAL_NOT_FOUND", "0x" + serialNo.toString(16))));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ }
+ }
+ }
+
+ X509CertImpl cert = certRecord.getCertificate();
+
+ String browser1 = req.getParameter("browser");
+ if (cert != null) {
+ // if there's a crmf request id, set that too.
+ if (browser != null && browser.equals("ie")) {
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ Locale[] locale = new Locale[1];
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) cacerts[n];
+ }
+
+ userChain[0] = cert;
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]), userChain, new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try {
+ p7.encodeSignedData(bos);
+ } catch (Exception eee) {
+ }
+
+ byte[] p7Bytes = bos.toByteArray();
+ String p7Str = CMS.BtoA(p7Bytes);
+
+ header.addStringValue("pkcs7", CryptoUtil.normalizeCertStr(p7Str));
+ try {
+ CMSTemplate form = getTemplate(mIETemplate, req, locale);
+ ServletOutputStream out = response.getOutputStream();
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ response.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ return;
+ } catch (Exception ee) {
+ CMS.debug("GetBySerial process: Exception="+ee.toString());
+ }
+ } //browser is IE
+
+ MetaInfo metai = certRecord.getMetaInfo();
+ String crmfReqId = null;
+
+ if (metai != null) {
+ crmfReqId = (String) metai.get(ICertRecord.META_CRMF_REQID);
+ if (crmfReqId != null)
+ cmsReq.setResult(IRequest.CRMF_REQID, crmfReqId);
+ }
+
+ if (crmfReqId == null && checkImportCertToNav(
+ cmsReq.getHttpResp(), cmsReq.getHttpParams(), cert)) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ // use import cert template to return cert.
+ X509CertImpl[] certs = new X509CertImpl[] { (X509CertImpl) cert };
+
+ cmsReq.setResult(certs);
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // XXX follow request in cert record to set certtype, which will
+ // import cert only if it's client. For now assume "client" if
+ // someone clicked to import this cert.
+ cmsReq.getHttpParams().set("certType", "client");
+
+ try {
+ renderTemplate(cmsReq, mImportTemplate, mImportTemplateFiller);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java
new file mode 100644
index 000000000..4093b989f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java
@@ -0,0 +1,405 @@
+// --- 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.servlet.cert;
+
+
+ import com.netscape.cms.servlet.common.*;
+ import com.netscape.cms.servlet.base.*;
+ import java.io.*;
+ import java.util.*;
+ import java.math.*;
+ import javax.servlet.*;
+ import java.security.cert.*;
+ import javax.servlet.http.*;
+ import netscape.ldap.*;
+ import netscape.security.x509.*;
+ import com.netscape.certsrv.base.*;
+ import com.netscape.certsrv.authority.*;
+ import com.netscape.certsrv.policy.*;
+ import com.netscape.certsrv.request.IRequest;
+ import com.netscape.certsrv.dbs.*;
+ import com.netscape.certsrv.dbs.certdb.*;
+ import com.netscape.certsrv.ldap.*;
+ import com.netscape.certsrv.logging.*;
+ import com.netscape.certsrv.apps.CMS;
+ import com.netscape.certsrv.authentication.*;
+ import com.netscape.certsrv.authorization.*;
+ import com.netscape.cms.servlet.*;
+
+
+ /**
+ * Retrieve the Certificates comprising the CA Chain for this CA.
+ *
+ * @version $Revision$, $Date$
+ */
+ public class GetCAChain extends CMSServlet {
+ private final static String TPL_FILE = "displayCaCert.template";
+ private String mFormPath = null;
+
+ public GetCAChain() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ // override success to display own output.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ // coming from ee
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ // Get the operation code
+ String op = null;
+
+ op = args.getValueAsString("op", null);
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_OPTIONS_SELECTED"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_OPTIONS_SELECTED"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ AuthzToken authzToken = null;
+
+ if (op.startsWith("download")) {
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "download");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ downloadChain(op, args, httpReq, httpResp, cmsReq);
+ } else if (op.startsWith("display")) {
+ try {
+ authzToken = mAuthz.authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ displayChain(op, args, httpReq, httpResp, cmsReq);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_OPTIONS_CA_CHAIN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_OPTIONS_SELECTED"));
+ }
+ // cmsReq.setResult(null);
+ return;
+ }
+
+ private void downloadChain(String op,
+ IArgBlock args,
+ HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ CMSRequest cmsReq)
+ throws EBaseException {
+
+ /* check browser info ? */
+
+ /* check if pkcs7 will work for both nav and ie */
+
+ byte[] bytes = null;
+
+ /*
+ * Some IE actions - IE doesn't want PKCS7 for "download" CA Cert.
+ * This means that we can only hand out the root CA, and not
+ * the whole chain.
+ */
+
+ if (clientIsMSIE(httpReq) && (op.equals("download") || op.equals("downloadBIN"))) {
+ X509Certificate[] caCerts =
+ ((ICertAuthority) mAuthority).getCACertChain().getChain();
+
+ try {
+ bytes = caCerts[0].getEncoded();
+ } catch (CertificateEncodingException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_GETTING_CACERT_ENCODED", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_GETTING_CA_CERT_ERROR"));
+ }
+ } else {
+ CertificateChain certChain =
+ ((ICertAuthority) mAuthority).getCACertChain();
+
+ if (certChain == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_CHAIN_EMPTY"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CA_CHAIN_EMPTY"));
+ }
+
+ try {
+ ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+
+ certChain.encode(encoded, false);
+ bytes = encoded.toByteArray();
+ } catch (IOException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_ENCODING_CA_CHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_CA_CHAIN_ERROR"));
+ }
+ }
+
+ String mimeType = null;
+
+ if (op.equals("downloadBIN")) {
+ mimeType = "application/octet-stream";
+ } else {
+ try {
+ mimeType = args.getValueAsString("mimeType");
+ } catch (EBaseException e) {
+ mimeType = "application/octet-stream";
+ }
+ }
+
+ try {
+ if (op.equals("downloadBIN")) {
+ // file suffixes changed to comply with RFC 5280
+ // requirements for AIA extensions
+ if (clientIsMSIE(httpReq)) {
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=ca.cer");
+ } else {
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=ca.p7c");
+ }
+ }
+ httpResp.setContentType(mimeType);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().flush();
+ } catch (IOException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CACHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CACHAIN_ERROR"));
+ }
+ }
+
+ private void displayChain(String op,
+ IArgBlock args,
+ HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ CMSRequest cmsReq)
+ throws EBaseException {
+ String outputString = null;
+
+ CertificateChain certChain =
+ ((ICertAuthority) mAuthority).getCACertChain();
+
+ if (certChain == null) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_CHAIN_NOT_AVAILABLE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CA_CHAIN_NOT_AVAILABLE"));
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String displayFormat = null;
+
+ if (op.equals("displayIND")) {
+ displayFormat = "individual";
+ } else {
+ try {
+ displayFormat = args.getValueAsString("displayFormat");
+ } catch (EBaseException e) {
+ displayFormat = "chain";
+ }
+ }
+
+ header.addStringValue("displayFormat", displayFormat);
+
+ if (displayFormat.equals("chain")) {
+ String subjectdn = null;
+ byte[] bytes = null;
+
+ try {
+ subjectdn =
+ certChain.getFirstCertificate().getSubjectDN().toString();
+ ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+
+ certChain.encode(encoded);
+ bytes = encoded.toByteArray();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_ENCODING_CA_CHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_CA_CHAIN_ERROR"));
+ }
+
+ String chainBase64 = getBase64(bytes);
+
+ header.addStringValue("subjectdn", subjectdn);
+ header.addStringValue("chainBase64", chainBase64);
+ } else {
+ try {
+ X509Certificate[] certs = certChain.getChain();
+
+ header.addIntegerValue("length", certs.length);
+ locale[0] = getLocale(httpReq);
+ for (int i = 0; i < certs.length; i++) {
+ byte[] bytes = null;
+
+ try {
+ bytes = certs[i].getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new IOException("Internal Error");
+ }
+ String subjectdn = certs[i].getSubjectDN().toString();
+ String finger = null;
+ try {
+ finger = CMS.getFingerPrints(certs[i]);
+ } catch (Exception e) {
+ throw new IOException("Internal Error");
+ }
+
+ ICertPrettyPrint certDetails =
+ CMS.getCertPrettyPrint((X509CertImpl) certs[i]);
+
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("fingerprints", finger);
+ rarg.addStringValue("subjectdn", subjectdn);
+ rarg.addStringValue("base64", getBase64(bytes));
+ rarg.addStringValue("certDetails",
+ certDetails.toString(locale[0]));
+ argSet.addRepeatRecord(rarg);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CACHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CACHAIN_ERROR"));
+ }
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+
+ }
+
+ /**
+ * gets base 64 encoded cert
+ */
+ private String getBase64(byte[] certBytes) {
+ String certBase64 = CMS.BtoA(certBytes);
+
+ return certBase64;
+ }
+
+ /**
+ * gets base 64 encoded cert chain
+ */
+ private String getChainBase64(byte[] certBytes) {
+ String certBase64 = CMS.BtoA(certBytes);
+
+ return certBase64;
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
new file mode 100644
index 000000000..6298b7d59
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
@@ -0,0 +1,468 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Retrieve CRL for a Certificate Authority
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCRL extends CMSServlet {
+ private final static String TPL_FILE = "displayCRL.template";
+ private String mFormPath = null;
+
+ public GetCRL() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ * @see DisplayCRL#process
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("**** mFormPath before getTemplate = "+mFormPath);
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // Get the operation code
+ String op = null;
+ String crlId = null;
+
+ op = args.getValueAsString("op", null);
+ crlId = args.getValueAsString("crlIssuingPoint", null);
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_OPTIONS_SELECTED"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_OPTIONS_SELECTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crlId == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_CRL_SELECTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ ICRLIssuingPointRecord crlRecord = null;
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+ ICRLIssuingPoint crlIP = null;
+ if (ca != null) crlIP = ca.getCRLIssuingPoint(crlId);
+
+ try {
+ crlRecord = (ICRLIssuingPointRecord) ca.getCRLRepository().readCRLIssuingPointRecord(crlId);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT_FOUND", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_FOUND")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ header.addStringValue("crlIssuingPoint", crlId);
+ header.addStringValue("crlNumber", crlRecord.getCRLNumber().toString());
+ long lCRLSize = crlRecord.getCRLSize().longValue();
+
+ header.addLongValue("crlSize", lCRLSize);
+ if (crlIP != null) {
+ header.addStringValue("crlDescription", crlIP.getDescription());
+ }
+
+ String crlDisplayType = args.getValueAsString("crlDisplayType", null);
+ if (crlDisplayType != null) {
+ header.addStringValue("crlDisplayType", crlDisplayType);
+ }
+
+ if ((op.equals("checkCRLcache") ||
+ (op.equals("displayCRL") && crlDisplayType != null && crlDisplayType.equals("cachedCRL"))) &&
+ (crlIP == null || (!crlIP.isCRLCacheEnabled()) || crlIP.isCRLCacheEmpty())) {
+ cmsReq.setError(
+ CMS.getUserMessage(
+ ((crlIP != null && crlIP.isCRLCacheEnabled() && crlIP.isCRLCacheEmpty())?
+ "CMS_GW_CRL_CACHE_IS_EMPTY":"CMS_GW_CRL_CACHE_IS_NOT_ENABLED"), crlId));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ byte[] crlbytes = null;
+
+ if (op.equals("importDeltaCRL") || op.equals("getDeltaCRL") ||
+ (op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("deltaCRL"))) {
+ crlbytes = crlRecord.getDeltaCRL();
+ } else if (op.equals("importCRL") || op.equals("getCRL") ||
+ op.equals("checkCRL") ||
+ (op.equals("displayCRL") &&
+ crlDisplayType != null &&
+ (crlDisplayType.equals("entireCRL") ||
+ crlDisplayType.equals("crlHeader") ||
+ crlDisplayType.equals("base64Encoded")))) {
+ crlbytes = crlRecord.getCRL();
+ }
+
+ if (crlbytes == null && (!op.equals("checkCRLcache")) &&
+ (!(op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("cachedCRL")))) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ byte[] bytes = crlbytes;
+
+ X509CRLImpl crl = null;
+
+ if (op.equals("checkCRL") || op.equals("importCRL") ||
+ op.equals("importDeltaCRL") ||
+ (op.equals("displayCRL") && crlDisplayType != null &&
+ (crlDisplayType.equals("entireCRL") ||
+ crlDisplayType.equals("crlHeader") ||
+ crlDisplayType.equals("base64Encoded") ||
+ crlDisplayType.equals("deltaCRL")))) {
+ try {
+ if (op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("crlHeader")) {
+ crl = new X509CRLImpl(crlbytes, false);
+ } else {
+ crl = new X509CRLImpl(crlbytes);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAILED_DECODE_CRL_1", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODE_CRL_FAILED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crl == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAILED_DECODE_CRL"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODE_CRL_FAILED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if ((op.equals("importDeltaCRL") || (op.equals("displayCRL") &&
+ crlDisplayType != null && crlDisplayType.equals("deltaCRL"))) &&
+ ((!(crlIP != null && crlIP.isThisCurrentDeltaCRL(crl))) &&
+ (crlRecord.getCRLNumber() == null ||
+ crlRecord.getDeltaCRLNumber() == null ||
+ crlRecord.getDeltaCRLNumber().compareTo(crlRecord.getCRLNumber()) < 0 ||
+ crlRecord.getDeltaCRLSize() == null ||
+ crlRecord.getDeltaCRLSize().longValue() == -1))) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_NO_DELTA_CRL_1"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ }
+
+ String mimeType = "application/x-pkcs7-crl";
+
+ if (op.equals("checkCRLcache") || op.equals("checkCRL") || op.equals("displayCRL")) {
+ header.addStringValue("toDo", op);
+ String certSerialNumber = args.getValueAsString("certSerialNumber", "");
+
+ header.addStringValue("certSerialNumber", certSerialNumber);
+ if (certSerialNumber.startsWith("0x")) {
+ certSerialNumber = hexToDecimal(certSerialNumber);
+ }
+
+ if (op.equals("checkCRLcache")) {
+ if (crlIP.getRevocationDateFromCache(
+ new BigInteger(certSerialNumber), false, false) != null) {
+ header.addBooleanValue("isOnCRL", true);
+ } else {
+ header.addBooleanValue("isOnCRL", false);
+ }
+ }
+
+ if (op.equals("checkCRL")) {
+ header.addBooleanValue("isOnCRL",
+ crl.isRevoked(new BigInteger(certSerialNumber)));
+ }
+
+ if (op.equals("displayCRL")) {
+ if (crlDisplayType.equals("entireCRL") || crlDisplayType.equals("cachedCRL")) {
+ ICRLPrettyPrint crlDetails = (crlDisplayType.equals("entireCRL"))?
+ CMS.getCRLPrettyPrint(crl):
+ CMS.getCRLCachePrettyPrint(crlIP);
+ String pageStart = args.getValueAsString("pageStart", null);
+ String pageSize = args.getValueAsString("pageSize", null);
+
+ if (pageStart != null && pageSize != null) {
+ long lPageStart = new Long(pageStart).longValue();
+ long lPageSize = new Long(pageSize).longValue();
+
+ if (lPageStart < 1) lPageStart = 1;
+
+ header.addStringValue("crlPrettyPrint",
+ crlDetails.toString(locale[0],
+ lCRLSize, lPageStart, lPageSize));
+ header.addLongValue("pageStart", lPageStart);
+ header.addLongValue("pageSize", lPageSize);
+ } else {
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0]));
+ }
+ } else if (crlDisplayType.equals("crlHeader")) {
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0], lCRLSize, 0, 0));
+ } else if (crlDisplayType.equals("base64Encoded")) {
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else if (crlDisplayType.equals("deltaCRL")) {
+ header.addIntegerValue("deltaCRLSize",
+ crl.getNumberOfRevokedCertificates());
+
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0], 0, 0, 0));
+
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ }
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ return;
+ } else if (op.equals("importCRL") || op.equals("importDeltaCRL")) {
+ if (clientIsMSIE(httpReq))
+ mimeType = "application/pkix-crl";
+ else
+ mimeType = "application/x-pkcs7-crl";
+ } else if (op.equals("getCRL")) {
+ mimeType = "application/octet-stream";
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=" + crlId + ".crl");
+ } else if (op.equals("getDeltaCRL")) {
+ mimeType = "application/octet-stream";
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=delta-" + crlId + ".crl");
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_OPTIONS_SELECTED"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_OPTIONS_SELECTED"));
+ }
+
+ try {
+ // if (clientIsMSIE(httpReq) && op.equals("getCRL"))
+ // httpResp.setHeader("Content-disposition",
+ // "attachment; filename=getCRL.crl");
+ httpResp.setContentType(mimeType);
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.getOutputStream().flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CRLINFO"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CRLINFO_ERROR"));
+ }
+ // cmsReq.setResult(null);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private String hexToDecimal(String hex) {
+ String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(newHex, 16);
+
+ return bi.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java
new file mode 100644
index 000000000..7f260216c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java
@@ -0,0 +1,338 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import netscape.security.extensions.*;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.*;
+import java.util.Locale;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Gets a issued certificate from a request id.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCertFromRequest extends CMSServlet {
+ private final static String PROP_IMPORT = "importCert";
+ protected static final String
+ GET_CERT_FROM_REQUEST_TEMPLATE = "ImportCert.template";
+ protected static final String
+ DISPLAY_CERT_FROM_REQUEST_TEMPLATE = "displayCertFromRequest.template";
+
+ protected static final String REQUEST_ID = "requestId";
+ protected static final String CERT_TYPE = "certtype";
+
+ protected String mCertFrReqSuccessTemplate = null;
+ protected ICMSTemplateFiller mCertFrReqFiller = null;
+
+ protected IRequestQueue mQueue = null;
+ protected boolean mImportCert = true;
+
+ public GetCertFromRequest() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template files
+ * "displayCertFromRequest.template" and "ImportCert.template"
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mQueue = mAuthority.getRequestQueue();
+ try {
+ String tmp = sc.getInitParameter(
+ PROP_IMPORT);
+
+ if (tmp != null && tmp.trim().equalsIgnoreCase("false"))
+ mImportCert = false;
+
+ String defTemplate = null;
+
+ if (mImportCert)
+ defTemplate = GET_CERT_FROM_REQUEST_TEMPLATE;
+ else
+ defTemplate = DISPLAY_CERT_FROM_REQUEST_TEMPLATE;
+ if (mAuthority instanceof IRegistrationAuthority)
+ defTemplate = "/ra/" + defTemplate;
+ else
+ defTemplate = "/ca/" + defTemplate;
+ mCertFrReqSuccessTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mCertFrReqSuccessTemplate == null)
+ mCertFrReqSuccessTemplate = defTemplate;
+ String fillername =
+ sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mCertFrReqFiller = filler;
+ } else {
+ mCertFrReqFiller = new CertFrRequestFiller();
+ }
+ } catch (Exception e) {
+ // should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
+ mId));
+ }
+ }
+
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param requestId The request ID to search on
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String requestId = httpParams.getValueAsString(REQUEST_ID, null);
+
+ if (requestId == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_REQUEST_ID_PROVIDED"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_REQUEST_ID_PROVIDED"));
+ }
+ // check if request Id is valid.
+ try {
+ Integer.parseInt(requestId);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_REQ_ID_FORMAT", requestId));
+ throw new EBaseException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId));
+ }
+
+ IRequest r = mQueue.findRequest(new RequestId(requestId));
+
+ if (r == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId));
+ }
+
+ if (authToken != null) {
+ //if RA, group and requestOwner must match
+ String group = authToken.getInString("group");
+ if ((group != null) && (group != "") &&
+ group.equals("Registration Manager Agents")) {
+ boolean groupMatched = false;
+ String reqOwner = r.getRequestOwner();
+ if (reqOwner != null) {
+ CMS.debug("GetCertFromRequest process: req owner="+reqOwner);
+ if (reqOwner.equals(group))
+ groupMatched = true;
+ }
+ if (groupMatched == false) {
+ CMS.debug("RA group unmatched");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId));
+ }
+ }
+ }
+
+ if (!((r.getRequestType().equals(IRequest.ENROLLMENT_REQUEST)) || (r.getRequestType().equals(IRequest.RENEWAL_REQUEST)))) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQUEST_NOT_ENROLLMENT_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_NOT_ENROLLMENT", requestId));
+ }
+ RequestStatus status = r.getRequestStatus();
+
+ if (!status.equals(RequestStatus.COMPLETE)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQUEST_NOT_COMPLETED_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_NOT_COMPLETED", requestId));
+ }
+ Integer result = r.getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && !result.equals(IRequest.RES_SUCCESS)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQUEST_HAD_ERROR_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_HAD_ERROR", requestId));
+ }
+ Object o = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (r.getExtDataInString("profile") != null) {
+ // handle profile-based request
+ X509CertImpl cert = r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ X509CertImpl certs[] = new X509CertImpl[1];
+
+ certs[0] = cert;
+ o = certs;
+ }
+ if (o == null || !(o instanceof X509CertImpl[])) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQUEST_HAD_NO_CERTS_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_HAD_NO_CERTS", requestId));
+ }
+ if (o instanceof X509CertImpl[]) {
+ X509CertImpl[] certs = (X509CertImpl[]) o;
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQUEST_HAD_NO_CERTS_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_HAD_NO_CERTS", requestId));
+ }
+
+ // for importsCert to get the crmf_reqid.
+ cmsReq.setIRequest(r);
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ if (mImportCert &&
+ checkImportCertToNav(cmsReq.getHttpResp(), httpParams, certs[0])) {
+ return;
+ }
+ try {
+ cmsReq.setResult(certs);
+ renderTemplate(cmsReq, mCertFrReqSuccessTemplate, mCertFrReqFiller);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGE_ERROR_DISPLAY_TEMPLATE_1",
+ mCertFrReqSuccessTemplate, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+ return;
+ }
+}
+
+
+class CertFrRequestFiller extends ImportCertsTemplateFiller {
+ public CertFrRequestFiller() {
+ }
+
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ CMSTemplateParams tparams =
+ super.getTemplateParams(cmsReq, authority, locale, e);
+ String reqId = cmsReq.getHttpParams().getValueAsString(
+ GetCertFromRequest.REQUEST_ID);
+
+ tparams.getHeader().addStringValue(GetCertFromRequest.REQUEST_ID, reqId);
+
+ if (reqId != null) {
+ IRequest r = authority.getRequestQueue().findRequest(new RequestId(reqId));
+ if (r != null) {
+ boolean noCertImport = true;
+ String certType = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType != null && certType.equals(IRequest.CLIENT_CERT)) {
+ noCertImport = false;
+ }
+ tparams.getHeader().addBooleanValue("noCertImport", noCertImport);
+
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs != null) {
+ X509CertInfo info = (X509CertInfo) certs[0].get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
+
+ tparams.getHeader().addStringValue(GetCertFromRequest.CERT_TYPE, "x509");
+
+ boolean emailCert = false;
+
+ if (extensions != null) {
+ for (int i = 0; i < extensions.size(); i++) {
+ Extension ext = (Extension) extensions.elementAt(i);
+
+ if (ext instanceof NSCertTypeExtension) {
+ NSCertTypeExtension type = (NSCertTypeExtension) ext;
+
+ if (((Boolean) type.get(NSCertTypeExtension.EMAIL)).booleanValue())
+ emailCert = true;
+ }
+ if (ext instanceof KeyUsageExtension) {
+ KeyUsageExtension usage =
+ (KeyUsageExtension) ext;
+
+ try {
+ if (((Boolean) usage.get(KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue() ||
+ ((Boolean) usage.get(KeyUsageExtension.DATA_ENCIPHERMENT)).booleanValue())
+ emailCert = true;
+ } catch (ArrayIndexOutOfBoundsException e0) {
+ // bug356108:
+ // In case there is only DIGITAL_SIGNATURE,
+ // don't report error
+ }
+ }
+ }
+ }
+ tparams.getHeader().addBooleanValue("emailCert", emailCert);
+ }
+ }
+ }
+
+ return tparams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java
new file mode 100644
index 000000000..7f1196bab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java
@@ -0,0 +1,174 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Servlet to get the enrollment status, enable or disable.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetEnableStatus extends CMSServlet {
+ private final static String TPL_FILE = "userEnroll.template";
+ private String mFormPath = null;
+
+ public GetEnableStatus() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE",
+ mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+ long timeout = mgr.DEFAULT_TIMEOUT / 1000;
+
+ header.addStringValue("timeout", "" + timeout);
+ header.addStringValue("reqHost", reqHost);
+
+ for (Enumeration hosts = mgr.getHosts(); hosts.hasMoreElements();) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("hosts", (String) hosts.nextElement());
+ argSet.addRepeatRecord(rarg);
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
new file mode 100644
index 000000000..4d9515861
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
@@ -0,0 +1,368 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+
+/**
+ * Get detailed information about CA CRL processing
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetInfo extends CMSServlet {
+
+ private final static String INFO = "GetInfo";
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs GetInfo servlet.
+ */
+ public GetInfo() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mFormPath = "";
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output our own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * XXX Process the HTTP request.
+ * <ul>
+ * <li>http.param template filename of template to use to render the result
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String template = req.getParameter("template");
+ String formFile = "";
+
+/*
+ for (int i = 0; ((template != null) && (i < template.length())); i++) {
+ char c = template.charAt(i);
+ if (!Character.isLetterOrDigit(c) && c != '_' && c != '-') {
+ template = null;
+ break;
+ }
+ }
+*/
+
+
+ if (template != null) {
+ formFile = template + ".template";
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE_1"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("*** formFile = "+formFile);
+ try {
+ form = getTemplate(formFile, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", formFile, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ process(argSet, header, req, resp, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ if (mCA != null) {
+ String crlIssuingPoints = "";
+ String crlNumbers = "";
+ String deltaNumbers = "";
+ String crlSizes = "";
+ String deltaSizes = "";
+ String crlDescriptions = "";
+ StringBuffer crlSplits = new StringBuffer();
+ String recentChanges = "";
+ String crlTesting = "";
+ boolean isDeltaCRLEnabled = false;
+
+ String masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ String masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+
+ ICRLRepository crlRepository = mCA.getCRLRepository();
+
+ Vector ipNames = crlRepository.getIssuingPointsNames();
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+ ICRLIssuingPointRecord crlRecord = null;
+ try {
+ crlRecord = crlRepository.readCRLIssuingPointRecord(ipName);
+ } catch (Exception e) {
+ }
+ if (crlRecord != null) {
+ if (crlIssuingPoints.length() > 0)
+ crlIssuingPoints += "+";
+ crlIssuingPoints += ipName;
+
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ if (crlNumbers.length() > 0)
+ crlNumbers += "+";
+ if (crlNumber != null)
+ crlNumbers += crlNumber.toString();
+
+ if (crlSizes.length() > 0)
+ crlSizes += "+";
+ crlSizes += ((crlRecord.getCRLSize() != null)?
+ crlRecord.getCRLSize().toString(): "-1");
+
+ if (deltaSizes.length() > 0)
+ deltaSizes += "+";
+ long dSize = -1;
+ if (crlRecord.getDeltaCRLSize() != null)
+ dSize = crlRecord.getDeltaCRLSize().longValue();
+ deltaSizes += dSize;
+
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ if (deltaNumbers.length() > 0)
+ deltaNumbers += "+";
+ if (deltaNumber != null && dSize > -1) {
+ deltaNumbers += deltaNumber.toString();
+ isDeltaCRLEnabled |= true;
+ } else {
+ deltaNumbers += "0";
+ }
+
+ if (recentChanges.length() > 0)
+ recentChanges += "+";
+ recentChanges += "-, -, -";
+
+ if (crlTesting.length() > 0)
+ crlTesting += "+";
+ crlTesting += "0";
+ }
+ }
+
+ } else {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (ip.isCRLIssuingPointEnabled()) {
+ if (crlIssuingPoints.length() > 0)
+ crlIssuingPoints += "+";
+ crlIssuingPoints += ip.getId();
+
+ BigInteger crlNumber = ip.getCRLNumber();
+ if (crlNumbers.length() > 0)
+ crlNumbers += "+";
+ if (crlNumber != null)
+ crlNumbers += crlNumber.toString();
+
+ BigInteger deltaNumber = ip.getDeltaCRLNumber();
+ if (deltaNumbers.length() > 0)
+ deltaNumbers += "+";
+ if (deltaNumber != null)
+ deltaNumbers += deltaNumber.toString();
+
+ if (crlSizes.length() > 0)
+ crlSizes += "+";
+ crlSizes += ip.getCRLSize();
+
+ if (deltaSizes.length() > 0)
+ deltaSizes += "+";
+ deltaSizes += ip.getDeltaCRLSize();
+
+ if (crlDescriptions.length() > 0)
+ crlDescriptions += "+";
+ crlDescriptions += ip.getDescription();
+
+ if (recentChanges.length() > 0)
+ recentChanges += "+";
+ if (ip.isCRLUpdateInProgress() == ip.CRL_PUBLISHING_STARTED) {
+ recentChanges += "Publishing CRL #" + ip.getCRLNumber();
+ } else if (ip.isCRLUpdateInProgress() == ip.CRL_UPDATE_STARTED) {
+ recentChanges += "Creating CRL #" + ip.getNextCRLNumber();
+ } else { // ip.CRL_UPDATE_DONE
+ recentChanges += ip.getNumberOfRecentlyRevokedCerts() + ", " +
+ ip.getNumberOfRecentlyUnrevokedCerts() + ", " +
+ ip.getNumberOfRecentlyExpiredCerts();
+ }
+ isDeltaCRLEnabled |= ip.isDeltaCRLEnabled();
+
+ if (crlSplits.length() > 0)
+ crlSplits.append("+");
+ Vector splits = ip.getSplitTimes();
+
+ for (int i = 0; i < splits.size(); i++) {
+ crlSplits.append(splits.elementAt(i));
+ if (i + 1 < splits.size())
+ crlSplits.append(",");
+ }
+
+ if (crlTesting.length() > 0)
+ crlTesting += "+";
+ crlTesting += ((ip.isCRLCacheTestingEnabled())?"1":"0");
+ }
+ }
+
+ }
+
+ header.addStringValue("crlIssuingPoints", crlIssuingPoints);
+ header.addStringValue("crlDescriptions", crlDescriptions);
+ header.addStringValue("crlNumbers", crlNumbers);
+ header.addStringValue("deltaNumbers", deltaNumbers);
+ header.addStringValue("crlSizes", crlSizes);
+ header.addStringValue("deltaSizes", deltaSizes);
+ header.addStringValue("crlSplits", crlSplits.toString());
+ header.addStringValue("crlTesting", crlTesting);
+ header.addBooleanValue("isDeltaCRLEnabled", isDeltaCRLEnabled);
+
+ header.addStringValue("master_host", masterHost);
+ header.addStringValue("master_port", masterPort);
+
+ header.addStringValue("masterCRLIssuingPoint", mCA.PROP_MASTER_CRL);
+ ICRLIssuingPoint ip0 = mCA.getCRLIssuingPoint(mCA.PROP_MASTER_CRL);
+
+ if (ip0 != null) {
+ header.addStringValue("defaultAlgorithm", ip0.getSigningAlgorithm());
+ }
+
+ if (recentChanges.length() > 0)
+ header.addStringValue("recentChanges", recentChanges);
+
+ String validAlgorithms = null;
+ String[] allAlgorithms = mCA.getCASigningAlgorithms();
+
+ if (allAlgorithms == null) {
+ CMS.debug("GetInfo: signing algorithms set to All algorithms");
+ allAlgorithms = AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+
+ for (int i = 0; i < allAlgorithms.length; i++) {
+ if (i > 0) {
+ validAlgorithms += "+" + allAlgorithms[i];
+ } else {
+ validAlgorithms = allAlgorithms[i];
+ }
+ }
+ if (validAlgorithms != null)
+ header.addStringValue("validAlgorithms", validAlgorithms);
+ }
+
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java
new file mode 100644
index 000000000..3f4eb66a9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java
@@ -0,0 +1,1241 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.*;
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.ObjectIdentifier;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.asn1.InvalidBERException;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.math.*;
+
+
+/**
+ * performs face-to-face enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class HashEnrollServlet extends CMSServlet {
+ public final static String ADMIN_ENROLL_SERVLET_ID = "adminEnroll";
+
+ // enrollment templates.
+ public static final String
+ ENROLL_SUCCESS_TEMPLATE = "/ra/HashEnrollSuccess.template";
+
+ // http params
+ public static final String OLD_CERT_TYPE = "csrCertType";
+ public static final String CERT_TYPE = "certType";
+ // same as in ConfigConstant.java
+ public static final String REQUEST_FORMAT = "reqFormat";
+ public static final String REQUEST_CONTENT = "requestContent";
+ public static final String SUBJECT_KEYGEN_INFO = "subjectKeyGenInfo";
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public static final String SUBJECT_NAME = "subject";
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String CHALLENGE_PASSWORD = "challengePhrase";
+
+ private static final String CERT_AUTH_DUAL = "dual";
+ private static final String CERT_AUTH_ENCRYPTION = "encryption";
+ private static final String CERT_AUTH_SINGLE = "single";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+ public static final String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+
+ private boolean mAuthTokenOverride = true;
+ private String mEnrollSuccessTemplate = null;
+ private ICMSTemplateFiller
+ mEnrollSuccessFiller = new ImportCertsTemplateFiller();
+
+ ICertificateAuthority mCa = null;
+ ICertificateRepository mRepository = null;
+
+ public HashEnrollServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success template to allow direct import of keygen certs.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ try {
+ mEnrollSuccessTemplate = sc.getInitParameter(
+ CMSServlet.PROP_SUCCESS_TEMPLATE);
+ if (mEnrollSuccessTemplate == null)
+ mEnrollSuccessTemplate = ENROLL_SUCCESS_TEMPLATE;
+ String fillername =
+ sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mEnrollSuccessFiller = filler;
+ }
+
+ // cfu
+ mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+
+ init_testbed_hack(mConfig);
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(), mId));
+ }
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ String certType = null;
+
+ String reqHost = httpReq.getRemoteHost();
+
+ String host = httpParams.getValueAsString("hostname", null);
+
+ if (host == null || !host.equals(reqHost)) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ boolean enable = mgr.isEnable(reqHost);
+
+ if (!enable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ } else {;
+ }
+
+ processX509(cmsReq);
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM",
+ e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+
+ protected void processX509(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+
+ // create enrollment request in request queue.
+ IRequest req = mRequestQueue.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+
+ String certAuthEnrollOn =
+ httpParams.getValueAsString("certauthEnroll", null);
+ X509CertInfo new_certInfo = null;
+
+ if ((certAuthEnrollOn != null) && (certAuthEnrollOn.equals("on"))) {
+ certAuthEnroll = true;
+ CMS.debug("HashEnrollServlet: certAuthEnroll is on");
+ }
+
+ String certauthEnrollType = null;
+
+ if (certAuthEnroll == true) {
+ certauthEnrollType =
+ httpParams.getValueAsString("certauthEnrollType", null);
+ if (certauthEnrollType != null) {
+ if (certauthEnrollType.equals("dual")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is dual");
+ } else if (certauthEnrollType.equals("encryption")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is encryption");
+ } else if (certauthEnrollType.equals("single")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is single");
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERTAUTH_ENROLL_TYPE_1", certauthEnrollType));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERTAUTH_ENROLL_TYPE"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ }
+ }
+
+ String challengePassword = httpParams.getValueAsString("challengePassword", "");
+
+ cmsReq.setIRequest(req);
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+ IAuthToken token = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "import");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+ // cert auth enroll
+ String certBasedOldSubjectDN = null;
+ BigInteger certBasedOldSerialNum = null;
+
+ // check if request was authenticated, if so set authtoken & certInfo.
+ // also if authenticated, take certInfo from authToken.
+ X509CertInfo certInfo = null;
+
+ if (certAuthEnroll == true) {
+ sslClientCert = getSSLClientCertificate(httpReq);
+ if (sslClientCert == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_MISSING_SSL_CLIENT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SSL_CLIENT_CERT"));
+ }
+
+ certBasedOldSubjectDN = (String) sslClientCert.getSubjectDN().toString();
+ certBasedOldSerialNum = (BigInteger) sslClientCert.getSerialNumber();
+ try {
+ certInfo = (X509CertInfo)
+ ((X509CertImpl) sslClientCert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+ } else {
+ certInfo = CMS.getDefaultX509CertInfo();
+ }
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[] {certInfo};
+
+ //AuthToken authToken = access.getAuthToken();
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr1 = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr1;
+ String pageID = httpParams.getValueAsString("pageID", null);
+
+ IAuthToken authToken = mgr.getAuthToken(pageID);
+
+ X509CertInfo authCertInfo = null;
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken == null) {
+ printError(cmsReq, "3");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ } else {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ // don't store agent token in request.
+ // agent currently used for bulk issuance.
+ // if (!authMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ log(ILogger.LL_INFO,
+ "Enrollment request was authenticated by " +
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME));
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ // save authtoken attrs to request directly (for policy use)
+ saveAuthToken(authToken, req);
+ // req.set(IRequest.AUTH_TOKEN, authToken);
+ // }
+ }
+
+ if (certAuthEnroll == true) {
+ // log(ILogger.LL_DEBUG, "just gotten subjectDN and serialNumber from ssl client cert");
+ if (authToken == null) {
+ // authToken is null, can't match to anyone; bail!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESS_ENROLL_NO_AUTH"));
+ return;
+ }
+ }
+
+ // fill certInfo from input types: keygen, cmc, pkcs10 or crmf
+ KeyGenInfo keyGenInfo =
+ httpParams.getValueAsKeyGenInfo(SUBJECT_KEYGEN_INFO, null);
+
+ String certType = null;
+
+ //
+ String test = httpParams.getValueAsString("certNickname", null);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ } else {
+ // some policies may rely on the fact that
+ // CERT_TYPE is set. So for 3.5.1 or eariler
+ // we need to set CERT_TYPE here.
+ req.setExtData(IRequest.HTTP_PARAMS, CERT_TYPE, certType);
+ }
+
+ String crmf =
+ httpParams.getValueAsString(CRMF_REQUEST, null);
+
+ if (certAuthEnroll == true) {
+
+ fillCertInfoFromAuthToken(certInfo, authToken);
+
+ // for dual certs
+ if (certauthEnrollType.equals(CERT_AUTH_DUAL)) {
+ if (mCa == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_A_CA"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_A_CA"));
+ }
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+ X509Key key = null;
+
+ // for signing cert
+ key = (X509Key) sslClientCert.getPublicKey();
+ try {
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ String filter =
+ "(&(x509cert.subject=" + certBasedOldSubjectDN + ")(!(x509cert.serialNumber=" + certBasedOldSerialNum + "))(certStatus=VALID))";
+ ICertRecordList list =
+ (ICertRecordList) mCa.getCertificateRepository().findCertRecordsInList(filter,
+ null, 10);
+ int size = list.getSize();
+ Enumeration en = list.getCertRecords(0, size - 1);
+ boolean gotEncCert = false;
+
+ if (!en.hasMoreElements()) {
+ // pairing encryption cert not found
+ } else {
+ X509CertInfo encCertInfo = CMS.getDefaultX509CertInfo();
+ X509CertInfo[] cInfoArray = new X509CertInfo[] {certInfo,
+ encCertInfo};
+ int i = 1;
+
+ while (en.hasMoreElements()) {
+ ICertRecord record = (ICertRecord) en.nextElement();
+ X509CertImpl cert = record.getCertificate();
+
+ // if not encryption cert only, try next one
+ if ((CMS.isEncryptionCert(cert) == false) ||
+ ((CMS.isEncryptionCert(cert) == true) &&
+ (CMS.isSigningCert(cert) == true))) {
+ continue;
+ }
+
+ key = (X509Key) cert.getPublicKey();
+ try {
+ encCertInfo = (X509CertInfo)
+ cert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+
+ try {
+ encCertInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+ fillCertInfoFromAuthToken(encCertInfo, authToken);
+
+ cInfoArray[i++] = encCertInfo;
+ certInfoArray = cInfoArray;
+ gotEncCert = true;
+ break;
+ }
+ }
+
+ if (gotEncCert == false) {
+ // encryption cert not found, bail
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ENCRYPTION_CERT_NOT_FOUND"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCRYPTION_CERT_NOT_FOUND"));
+ }
+ } else if (certauthEnrollType.equals(CERT_AUTH_ENCRYPTION)) {
+ // first, make sure the client cert is indeed a
+ // signing only cert
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+
+ /*
+ * crmf
+ */
+ if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug(
+ "HashEnrollServlet: sslClientCert issuerDN = " + sslClientCert.getIssuerDN().toString());
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ } else if (certauthEnrollType.equals(CERT_AUTH_SINGLE)) {
+ // have to be buried here to handle the issuer
+
+ if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ }
+ } else if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+ req.setExtData(IRequest.CERT_INFO, certInfoArray);
+
+ if (challengePassword != null && !challengePassword.equals("")) {
+ String pwd = hashPassword(challengePassword);
+
+ req.setExtData(CHALLENGE_PASSWORD, pwd);
+ }
+
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+ // process result.
+
+ // render OLD_CERT_TYPE's response differently, we
+ // dont want any javascript in HTML, and need to
+ // override the default render.
+ if (httpParams.getValueAsString(OLD_CERT_TYPE, null) != null) {
+ try {
+ renderServerEnrollResult(cmsReq);
+ cmsReq.setStatus(CMSRequest.SUCCESS); // no default render
+ } catch (IOException ex) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ return;
+ }
+
+ //for audit log
+ String initiative = null;
+ String agentID = null;
+
+ if (!authMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // if service not complete return standard templates.
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus(); // set status acc. to IRequest status.
+ // audit log the status
+ try {
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT),
+ " violation: " +
+ wholeMsg.toString()},
+ ILogger.L_MULTILINE
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } else { // other imcomplete status
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING", e.toString()));
+ }
+ return;
+ }
+ // if service error use standard error templates.
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ // audit log the error
+ try {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // service success
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ X509CertImpl[] issuedCerts =
+ req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ // audit log the success.
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ issuedCerts[0].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ issuedCerts[0].getSerialNumber().toString(16)}
+ );
+
+ // return cert as mime type binary if requested.
+ if (checkImportCertToNav(
+ cmsReq.getHttpResp(), httpParams, issuedCerts[0])) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ // use success template.
+ try {
+ cmsReq.setResult(issuedCerts);
+ renderTemplate(cmsReq, mEnrollSuccessTemplate,
+ mEnrollSuccessFiller);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_TEMP_REND_ERR", mEnrollSuccessFiller.toString(), e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_RETURNING_RESULT_ERROR"));
+ }
+ return;
+ }
+
+ /**
+ * fill subject name, validity, extensions from authoken if any,
+ * overriding what was in pkcs10.
+ * fill subject name, extensions from http input if not authenticated.
+ * requests not authenticated will need to be approved by an agent.
+ */
+ protected void fillCertInfoFromAuthToken(
+ X509CertInfo certInfo, IAuthToken authToken)
+ throws EBaseException {
+ // override subject, validity and extensions from auth token
+ // CA determines algorithm, version and issuer.
+ // take key from keygen, cmc, pkcs10 or crmf.
+
+ // subject name.
+ try {
+ String subjectname =
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT);
+
+ if (subjectname != null) {
+ CertificateSubjectName certSubject = (CertificateSubjectName)
+ new CertificateSubjectName(new X500Name(subjectname));
+
+ certInfo.set(X509CertInfo.SUBJECT, certSubject);
+ log(ILogger.LL_INFO,
+ "cert subject set to " + certSubject + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ }
+
+ // validity
+ try {
+ CertificateValidity validity = null;
+ Date notBefore =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTBEFORE);
+ Date notAfter =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTAFTER);
+
+ if (notBefore != null && notAfter != null) {
+ validity = new CertificateValidity(notBefore, notAfter);
+ certInfo.set(X509CertInfo.VALIDITY, validity);
+ log(ILogger.LL_INFO,
+ "cert validity set to " + validity + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ }
+
+ // extensions
+ try {
+ CertificateExtensions extensions =
+ authToken.getInCertExts(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ log(ILogger.LL_INFO, "cert extensions set from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ }
+ }
+
+ protected X509CertInfo[] fillCRMF(
+ String crmf, IAuthToken authToken, IArgBlock httpParams, IRequest req)
+ throws EBaseException {
+ try {
+ byte[] crmfBlob = CMS.AtoB(crmf);
+ ByteArrayInputStream crmfBlobIn =
+ new ByteArrayInputStream(crmfBlob);
+
+ SEQUENCE crmfMsgs = (SEQUENCE)
+ new SEQUENCE.OF_Template(new CertReqMsg.Template()).decode(crmfBlobIn);
+
+ int nummsgs = crmfMsgs.size();
+ X509CertInfo[] certInfoArray = new X509CertInfo[nummsgs];
+
+ for (int i = 0; i < nummsgs; i++) {
+ // decode message.
+ CertReqMsg certReqMsg = (CertReqMsg) crmfMsgs.elementAt(i);
+
+ /*
+ if (certReqMsg.hasPop()) {
+ try {
+ certReqMsg.verify();
+ } catch (ChallengeResponseException ex) {
+ // create and save the challenge
+ // construct the cmmf message together
+ // in a sequence to challenge the requestor
+ } catch (Exception e) {
+ // failed, should only affect one request
+ }
+ }
+ */
+ CertRequest certReq = certReqMsg.getCertReq();
+ INTEGER certReqId = certReq.getCertReqId();
+ int srcId = certReqId.intValue();
+
+ req.setExtData(IRequest.CRMF_REQID, String.valueOf(srcId));
+
+ CertTemplate certTemplate = certReq.getCertTemplate();
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ // get key
+ SubjectPublicKeyInfo spki = certTemplate.getPublicKey();
+ ByteArrayOutputStream keyout = new ByteArrayOutputStream();
+
+ spki.encode(keyout);
+ byte[] keybytes = keyout.toByteArray();
+ X509Key key = new X509Key();
+
+ key.decode(keybytes);
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+
+ // field suggested notBefore and notAfter in CRMF
+ // Tech Support #383184
+ if (certTemplate.getNotBefore() != null || certTemplate.getNotAfter() != null) {
+ CertificateValidity certValidity = new CertificateValidity(certTemplate.getNotBefore(), certTemplate.getNotAfter());
+
+ certInfo.set(X509CertInfo.VALIDITY, certValidity);
+ }
+
+ if (certTemplate.hasSubject()) {
+ Name subjectdn = certTemplate.getSubject();
+ ByteArrayOutputStream subjectEncStream =
+ new ByteArrayOutputStream();
+
+ subjectdn.encode(subjectEncStream);
+ byte[] subjectEnc = subjectEncStream.toByteArray();
+ X500Name subject = new X500Name(subjectEnc);
+
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+ } else if (authToken == null ||
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) == null) {
+ // No subject name - error!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ }
+
+ // get extensions
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (CertificateException e) {
+ extensions = null;
+ } catch (IOException e) {
+ extensions = null;
+ }
+ if (certTemplate.hasExtensions()) {
+ // put each extension from CRMF into CertInfo.
+ // index by extension name, consistent with
+ // CertificateExtensions.parseExtension() method.
+ if (extensions == null)
+ extensions = new CertificateExtensions();
+ int numexts = certTemplate.numExtensions();
+
+ for (int j = 0; j < numexts; j++) {
+ org.mozilla.jss.pkix.cert.Extension jssext =
+ certTemplate.extensionAt(j);
+ boolean isCritical = jssext.getCritical();
+ org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssoid =
+ jssext.getExtnId();
+ long[] numbers = jssoid.getNumbers();
+ int[] oidNumbers = new int[numbers.length];
+
+ for (int k = numbers.length - 1; k >= 0; k--) {
+ oidNumbers[k] = (int) numbers[k];
+ }
+ ObjectIdentifier oid =
+ new ObjectIdentifier(oidNumbers);
+ org.mozilla.jss.asn1.OCTET_STRING jssvalue =
+ jssext.getExtnValue();
+ ByteArrayOutputStream jssvalueout =
+ new ByteArrayOutputStream();
+
+ jssvalue.encode(jssvalueout);
+ byte[] extValue = jssvalueout.toByteArray();
+
+ Extension ext =
+ new Extension(oid, isCritical, extValue);
+
+ extensions.parseExtension(ext);
+ }
+
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ }
+
+ // Added a new configuration parameter
+ // eeGateway.Enrollment.authTokenOverride=[true|false]
+ // By default, it is set to true. In most
+ // of the case, administrator would want
+ // to have the control of the subject name
+ // formulation.
+ // -- CRMFfillCert
+ if (authToken != null &&
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) != null) {
+ // if authenticated override subect name, validity and
+ // extensions if any from authtoken.
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ }
+
+ certInfoArray[i] = certInfo;
+ }
+
+ do_testbed_hack(nummsgs, certInfoArray, httpParams);
+
+ return certInfoArray;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ }
+ }
+
+ protected void renderServerEnrollResult(CMSRequest cmsReq) throws
+ IOException {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = null;
+
+ out = httpResp.getOutputStream();
+
+ // get template based on request status
+ out.println("<HTML>");
+ out.println("<TITLE>");
+ out.println("Server Enrollment");
+ out.println("</TITLE>");
+ // out.println("<BODY BGCOLOR=white>");
+
+ if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ out.println("<H1>");
+ out.println("SUCCESS");
+ out.println("</H1>");
+ out.println("Your request is submitted and approved. Please cut and paste the certificate into your server."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("Certificate: ");
+ out.println("<P>");
+ out.println("<PRE>");
+ X509CertImpl certs[] =
+ cmsReq.getIRequest().getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ out.println(CMS.getEncodedCert(certs[0]));
+ out.println("</PRE>");
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ out.println("<!HTTP_OUTPUT X509_CERTIFICATE=" +
+ CMS.getEncodedCert(certs[0]) + ">");
+ } else if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.PENDING)) {
+ out.println("<H1>");
+ out.println("PENDING");
+ out.println("</H1>");
+ out.println("Your request is submitted. You can check on the status of your request with an authorized agent or local administrator by referring to the request ID."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ } else {
+ out.println("<H1>");
+ out.println("ERROR");
+ out.println("</H1>");
+ out.println("<!INFO>");
+ out.println("Please consult your local administrator for assistance."); // XXX - localize the message
+ out.println("<!/INFO>");
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Error: ");
+ out.println(cmsReq.getError()); // XXX - need to parse in Locale
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT ERROR=" +
+ cmsReq.getError() + ">");
+ }
+
+ /**
+ // include all the input data
+ IArgBlock args = cmsReq.getHttpParams();
+ Enumeration ele = args.getElements();
+ while (ele.hasMoreElements()) {
+ String eleT = (String)ele.nextElement();
+ out.println("<!HTTP_INPUT " + eleT + "=" +
+ args.get(eleT) + ">");
+ }
+ **/
+
+ out.println("</HTML>");
+ }
+
+ // XXX ALERT !!
+ // Remove the following and calls to them when we bundle a cartman
+ // later than alpha1.
+ // These are here to cover up problem in cartman where the
+ // key usage extension always ends up being digital signature only
+ // and for rsa-ex ends up having no bits set.
+
+ private boolean mIsTestBed = false;
+
+ private void init_testbed_hack(IConfigStore config)
+ throws EBaseException {
+ mIsTestBed = config.getBoolean("isTestBed", true);
+ }
+
+ private void do_testbed_hack(
+ int nummsgs, X509CertInfo[] certinfo, IArgBlock httpParams)
+ throws EBaseException {
+ if (!mIsTestBed)
+ return;
+
+ // get around bug in cartman - bits are off by one byte.
+ for (int i = 0; i < certinfo.length; i++) {
+ try {
+ X509CertInfo cert = certinfo[i];
+ CertificateExtensions exts = (CertificateExtensions)
+ cert.get(CertificateExtensions.NAME);
+
+ if (exts == null) {
+ // should not happen.
+ continue;
+ }
+ KeyUsageExtension ext = (KeyUsageExtension)
+ exts.get(KeyUsageExtension.NAME);
+
+ if (ext == null)
+ // should not happen
+ continue;
+ byte[] value = ext.getExtensionValue();
+
+ if (value[0] == 0x03 && value[1] == 0x02 && value[2] == 0x07) {
+ byte[] newvalue = new byte[value.length + 1];
+
+ newvalue[0] = 0x03;
+ newvalue[1] = 0x03;
+ newvalue[2] = 0x07;
+ newvalue[3] = value[3];
+ // force encryption certs to have digitial signature
+ // set too so smime can find the cert for encryption.
+ if (value[3] == 0x20) {
+
+ /*
+ newvalue[3] = 0x3f;
+ newvalue[4] = (byte)0x80;
+ */
+ if (httpParams.getValueAsBoolean(
+ "dual-use-hack", true)) {
+ newvalue[3] = (byte) 0xE0; // same as rsa-dual-use.
+ }
+ }
+ newvalue[4] = 0;
+ KeyUsageExtension newext =
+ new KeyUsageExtension(Boolean.valueOf(true),
+ (Object) newvalue);
+
+ exts.delete(KeyUsageExtension.NAME);
+ exts.set(KeyUsageExtension.NAME, newext);
+ }
+ } catch (IOException e) {
+ // should never happen
+ continue;
+ } catch (CertificateException e) {
+ // should never happen
+ continue;
+ }
+ }
+
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
new file mode 100644
index 000000000..98da80372
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
@@ -0,0 +1,372 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Locale;
+import java.math.BigInteger;
+import java.io.ByteArrayOutputStream;
+import java.io.StringWriter;
+import java.io.StringReader;
+import java.io.BufferedReader;
+
+
+import javax.servlet.http.HttpServletRequest;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.NoSuchAlgorithmException;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.SignerInfo;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.request.IRequest;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.cmmf.*;
+
+
+/**
+ * Set up HTTP response to import certificate into browsers
+ *
+ * The result must have been populate with the set of certificates
+ * to return.
+ * <pre>
+ * inputs: certtype.
+ * outputs:
+ * - cert type from http input (if any)
+ * - CA chain
+ * - authority name (RM, CM, DRM)
+ * - scheme:host:port of server.
+ * array of one or more
+ * - cert serial number
+ * - cert pretty print
+ * - cert in base 64 encoding.
+ * - cmmf blob to import
+ * </pre>
+ * @version $Revision$, $Date$
+ */
+public class ImportCertsTemplateFiller implements ICMSTemplateFiller {
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String ISSUED_CERT_SERIAL = "serialNo";
+ public static final String CERT_TYPE = "certType";
+ public static final String BASE64_CERT = "base64Cert";
+ public static final String CERT_PRETTYPRINT = "certPrettyPrint";
+ public static final String CERT_FINGERPRINT = "certFingerprint"; // cisco
+ public static final String CERT_NICKNAME = "certNickname";
+ public static final String CMMF_RESP = "cmmfResponse";
+ public static final String PKCS7_RESP = "pkcs7ChainBase64"; // for MSIE
+
+ public ImportCertsTemplateFiller() {
+ }
+
+ /**
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ Certificate[] certs = (Certificate[]) cmsReq.getResult();
+
+ if (certs instanceof X509CertImpl[])
+ return getX509TemplateParams(cmsReq, authority, locale, e);
+ else
+ return null;
+ }
+
+ public CMSTemplateParams getX509TemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(header, fixed);
+
+ // set host name and port.
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String host = httpReq.getServerName();
+ int port = httpReq.getServerPort();
+ String scheme = httpReq.getScheme();
+ String format = httpReq.getParameter("format");
+ if(format!=null && format.equals("cmc"))
+ fixed.set("importCMC", "false");
+ String agentPort = ""+port;
+ fixed.set("agentHost", host);
+ fixed.set("agentPort", agentPort);
+ fixed.set(ICMSTemplateFiller.HOST, host);
+ fixed.set(ICMSTemplateFiller.PORT, Integer.valueOf(port));
+ fixed.set(ICMSTemplateFiller.SCHEME, scheme);
+ IRequest r = cmsReq.getIRequest();
+
+ if (r != null) {
+ fixed.set(ICMSTemplateFiller.REQUEST_ID, r.getRequestId().toString());
+ }
+
+ // set key record (if KRA enabled)
+ if (r != null) {
+ BigInteger keyRecSerialNo = r.getExtDataInBigInteger("keyRecord");
+
+ if (keyRecSerialNo != null) {
+ fixed.set(ICMSTemplateFiller.KEYREC_ID, keyRecSerialNo.toString());
+ }
+ }
+
+ // set cert type.
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ String certType =
+ httpParams.getValueAsString(CERT_TYPE, null);
+
+ if (certType != null)
+ fixed.set(CERT_TYPE, certType);
+
+ // this authority
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ (String) authority.getOfficialName());
+
+ // CA chain.
+ CertificateChain cachain =
+ ((ICertAuthority) authority).getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+
+ String replyTo = httpParams.getValueAsString("replyTo", null);
+
+ if (replyTo != null) fixed.set("replyTo", replyTo);
+
+ // set user + CA cert chain and pkcs7 for MSIE.
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++)
+ userChain[m] = (X509CertImpl) cacerts[n];
+
+ // certs.
+ X509CertImpl[] certs = (X509CertImpl[]) cmsReq.getResult();
+
+ // expose CRMF request id
+ String crmfReqId = cmsReq.getExtData(IRequest.CRMF_REQID);
+
+ if (crmfReqId == null) {
+ crmfReqId = (String) cmsReq.getResult(
+ IRequest.CRMF_REQID);
+ }
+ if (crmfReqId != null) {
+ fixed.set(CRMF_REQID, crmfReqId);
+ }
+
+ // set CA certs in cmmf, initialize CertRepContent
+ // note cartman can't trust ca certs yet but it'll import them.
+ // also set cert nickname for cartman.
+ CertRepContent certRepContent = null;
+
+ if (CMSServlet.doCMMFResponse(httpParams)) {
+ byte[][] caPubs = new byte[cacerts.length][];
+
+ for (int j = 0; j < cacerts.length; j++)
+ caPubs[j] = ((X509CertImpl) cacerts[j]).getEncoded();
+ certRepContent = new CertRepContent(caPubs);
+
+ String certnickname =
+ cmsReq.getHttpParams().getValueAsString(CERT_NICKNAME, null);
+
+ // if nickname is not requested set to subject name by default.
+ if (certnickname == null)
+ fixed.set(CERT_NICKNAME, certs[0].getSubjectDN().toString());
+ else
+ fixed.set(CERT_NICKNAME, certnickname);
+ }
+
+ // make pkcs7 for MSIE
+ if (CMSServlet.clientIsMSIE(cmsReq.getHttpReq()) &&
+ (certType == null || certType.equals("client"))) {
+ userChain[0] = certs[0];
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+ // String p7Str = encoder.encodeBuffer(p7Bytes);
+ String p7Str = CMS.BtoA(p7Bytes);
+
+ header.set(PKCS7_RESP, p7Str);
+ }
+
+ // set base 64, pretty print and cmmf response for each issued cert.
+ for (int i = 0; i < certs.length; i++) {
+ IArgBlock repeat = CMS.createArgBlock();
+ X509CertImpl cert = certs[i];
+
+ // set serial number.
+ BigInteger serialNo =
+ ((X509Certificate) cert).getSerialNumber();
+
+ repeat.addBigIntegerValue(ISSUED_CERT_SERIAL, serialNo, 16);
+
+ // set base64 encoded blob.
+ byte[] certEncoded = cert.getEncoded();
+ // String b64 = encoder.encodeBuffer(certEncoded);
+ String b64 = CMS.BtoA(certEncoded);
+ String b64cert = "-----BEGIN CERTIFICATE-----\n" +
+ b64 + "\n-----END CERTIFICATE-----";
+
+ repeat.set(BASE64_CERT, b64cert);
+
+ // set cert pretty print.
+
+ String prettyPrintRequested =
+ cmsReq.getHttpParams().getValueAsString(CERT_PRETTYPRINT, null);
+
+ if (prettyPrintRequested == null) {
+ prettyPrintRequested = "true";
+ }
+ String ppStr = "";
+
+ if (!prettyPrintRequested.equals("false")) {
+ ICertPrettyPrint pp = CMS.getCertPrettyPrint(cert);
+
+ ppStr = pp.toString(locale);
+ }
+ repeat.set(CERT_PRETTYPRINT, ppStr);
+
+ // Now formulate a PKCS#7 blob
+ X509CertImpl[] certsInChain = new X509CertImpl[1];;
+ if (cacerts != null) {
+ for (int j = 0; j < cacerts.length; j++) {
+ if (cert.equals(cacerts[j])) {
+ certsInChain = new
+ X509CertImpl[cacerts.length];
+ break;
+ }
+ certsInChain = new X509CertImpl[cacerts.length + 1];
+ }
+ }
+
+ // Set the EE cert
+ certsInChain[0] = cert;
+
+ // Set the Ca certificate chain
+ if (cacerts != null) {
+ for (int j = 0; j < cacerts.length; j++) {
+ if (!cert.equals(cacerts[j]))
+ certsInChain[j + 1] = (X509CertImpl) cacerts[j];
+ }
+ }
+ // Wrap the chain into a degenerate P7 object
+ String p7Str;
+
+ try {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ certsInChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+
+ //p7Str = encoder.encodeBuffer(p7Bytes);
+ p7Str = CMS.BtoA(p7Bytes);
+ repeat.addStringValue("pkcs7ChainBase64", p7Str);
+ } catch (Exception ex) {
+ //p7Str = "PKCS#7 B64 Encoding error - " + ex.toString()
+ //+ "; Please contact your administrator";
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_FORMING_PKCS7_ERROR"));
+ }
+
+ // set cert fingerprint (for Cisco routers)
+ String fingerprint = null;
+
+ try {
+ fingerprint = CMS.getFingerPrints(cert);
+ } catch (CertificateEncodingException ex) {
+ // should never happen
+ throw new EBaseException(
+ CMS.getUserMessage(locale, "CMS_BASE_INTERNAL_ERROR", ex.toString()));
+ } catch (NoSuchAlgorithmException ex) {
+ // should never happen
+ throw new EBaseException(
+ CMS.getUserMessage(locale, "CMS_BASE_INTERNAL_ERROR", ex.toString()));
+ }
+ if (fingerprint != null && fingerprint.length() > 0)
+ repeat.set(CERT_FINGERPRINT, fingerprint);
+
+ // cmmf response for this cert.
+ if (CMSServlet.doCMMFResponse(httpParams) && crmfReqId != null &&
+ (certType == null || certType.equals("client"))) {
+ PKIStatusInfo status = new PKIStatusInfo(PKIStatusInfo.granted);
+ CertifiedKeyPair certifiedKP =
+ new CertifiedKeyPair(new CertOrEncCert(certEncoded));
+ CertResponse resp =
+ new CertResponse(new INTEGER(crmfReqId), status,
+ certifiedKP);
+
+ certRepContent.addCertResponse(resp);
+ }
+
+ params.addRepeatRecord(repeat);
+ }
+
+ // if cartman set whole cmmf response (CertRepContent) string.
+ if (CMSServlet.doCMMFResponse(httpParams)) {
+ ByteArrayOutputStream certRepOut = new ByteArrayOutputStream();
+
+ certRepContent.encode(certRepOut);
+ byte[] certRepBytes = certRepOut.toByteArray();
+ String certRepB64 = com.netscape.osutil.OSUtil.BtoA(certRepBytes);
+ // add CR to each return as required by cartman
+ BufferedReader certRepB64lines =
+ new BufferedReader(new StringReader(certRepB64));
+ StringWriter certRepStringOut = new StringWriter();
+ String oneLine = null;
+ boolean first = true;
+
+ while ((oneLine = certRepB64lines.readLine()) != null) {
+ if (first) {
+ //certRepStringOut.write("\""+oneLine+"\"");
+ certRepStringOut.write(oneLine);
+ first = false;
+ } else {
+ //certRepStringOut.write("+\"\\n"+oneLine+"\"");
+ certRepStringOut.write("\n" + oneLine);
+ }
+ }
+ String certRepString = certRepStringOut.toString();
+
+ fixed.set(CMMF_RESP, certRepString);
+ }
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java
new file mode 100644
index 000000000..d7160daa6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java
@@ -0,0 +1,733 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve a paged list of certs matching the specified query
+ *
+ * @version $Revision$, $Date$
+ */
+public class ListCerts extends CMSServlet {
+
+ private final static String TPL_FILE = "queryCert.template";
+ private final static String INFO = "ListCerts";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private final static String CURRENT_TIME = "currentTime";
+ private final static String USE_CLIENT_FILTER = "useClientFilter";
+ private final static String ALLOWED_CLIENT_FILTERS = "allowedClientFilters";
+
+ private ICertificateRepository mCertDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private boolean mReverse = false;
+ private boolean mHardJumpTo = false; //jump to the end
+ private String mDirection = null;
+ private boolean mUseClientFilter = false;
+ private Vector mAllowedClientFilters = new Vector();
+ private int mMaxReturns = 2000;
+
+ /**
+ * Constructs query key servlet.
+ */
+ public ListCerts() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "queryCert.template" to render the response
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ mMaxReturns = Integer.parseInt(sc.getInitParameter("maxResults"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ /* useClientFilter should be off by default. We keep
+ this parameter around so that we do not break
+ the client applications that submits raw LDAP
+ filter into this servlet. */
+ if (sc.getInitParameter(USE_CLIENT_FILTER) != null &&
+ sc.getInitParameter(USE_CLIENT_FILTER).equalsIgnoreCase("true")) { mUseClientFilter = true;
+ }
+ if (sc.getInitParameter(ALLOWED_CLIENT_FILTERS) == null || sc.getInitParameter(ALLOWED_CLIENT_FILTERS).equals("")) {
+ mAllowedClientFilters.addElement("(certStatus=*)");
+ mAllowedClientFilters.addElement("(certStatus=VALID)");
+ mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))");
+ mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=REVOKED))");
+ } else {
+ StringTokenizer st = new StringTokenizer(sc.getInitParameter(ALLOWED_CLIENT_FILTERS), ",");
+ while (st.hasMoreTokens()) {
+ mAllowedClientFilters.addElement(st.nextToken());
+ }
+ }
+ }
+
+ public String buildFilter(HttpServletRequest req)
+ {
+ String queryCertFilter = req.getParameter("queryCertFilter");
+
+ com.netscape.certsrv.apps.CMS.debug("client queryCertFilter=" + queryCertFilter);
+
+ if (mUseClientFilter) {
+ com.netscape.certsrv.apps.CMS.debug("useClientFilter=true");
+ Enumeration filters = mAllowedClientFilters.elements();
+ // check to see if the filter is allowed
+ while (filters.hasMoreElements()) {
+ String filter = (String)filters.nextElement();
+ com.netscape.certsrv.apps.CMS.debug("Comparing filter=" + filter + " queryCertFilter=" + queryCertFilter);
+ if (filter.equals(queryCertFilter)) {
+ return queryCertFilter;
+ }
+ }
+ com.netscape.certsrv.apps.CMS.debug("Requested filter '" + queryCertFilter + "' is not allowed. Please check the " + ALLOWED_CLIENT_FILTERS + "parameter");
+ return null;
+ } else {
+ com.netscape.certsrv.apps.CMS.debug("useClientFilter=false");
+ }
+
+ boolean skipRevoked = false;
+ boolean skipNonValid = false;
+ if (req.getParameter("skipRevoked") != null &&
+ req.getParameter("skipRevoked").equals("on")) {
+ skipRevoked = true;
+ }
+ if (req.getParameter("skipNonValid") != null &&
+ req.getParameter("skipNonValid").equals("on")) {
+ skipNonValid = true;
+ }
+
+ if (!skipRevoked && !skipNonValid) {
+ queryCertFilter = "(certStatus=*)";
+ } else if (skipRevoked && skipNonValid) {
+ queryCertFilter = "(certStatus=VALID)";
+ } else if (skipRevoked) {
+ queryCertFilter = "(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))";
+ } else if (skipNonValid) {
+ queryCertFilter = "(|(certStatus=VALID)(certStatus=REVOKED))";
+ }
+ return queryCertFilter;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param maxCount Number of certificates to show
+ * <li>http.param queryFilter and ldap style filter specifying the
+ * certificates to show
+ * <li>http.param querySentinelDown the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging down
+ * <li>http.param querySentinelUp the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging up
+ * <li>http.param direction "up", "down", "begin", or "end"
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (Exception e) {
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ EBaseException error = null;
+
+ int maxCount = -1;
+ BigInteger sentinel = new BigInteger("0");
+
+ IArgBlock header = com.netscape.certsrv.apps.CMS.createArgBlock();
+ IArgBlock ctx = com.netscape.certsrv.apps.CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ mHardJumpTo = false;
+ try {
+
+ if (req.getParameter("direction") != null) {
+ mDirection = req.getParameter("direction").trim();
+ mReverse = mDirection.equals("up");
+ if (mReverse)
+ com.netscape.certsrv.apps.CMS.debug("reverse is true");
+ else
+ com.netscape.certsrv.apps.CMS.debug("reverse is false");
+
+ }
+
+ if (req.getParameter("maxCount") != null) {
+ maxCount = Integer.parseInt(req.getParameter("maxCount"));
+ }
+ if (maxCount == -1 || maxCount > mMaxReturns) {
+ com.netscape.certsrv.apps.CMS.debug("Resetting page size from " + maxCount + " to " + mMaxReturns);
+ maxCount = mMaxReturns;
+ }
+
+ String sentinelStr = "";
+ if (mReverse) {
+ sentinelStr = req.getParameter("querySentinelUp");
+ } else if (mDirection.equals("end")) {
+ // this servlet will figure out the end
+ sentinelStr = "0";
+ mReverse = true;
+ mHardJumpTo = true;
+ } else if (mDirection.equals("down")) {
+ sentinelStr = req.getParameter("querySentinelDown");
+ } else
+ sentinelStr = "0";
+ //begin and non-specified have sentinel default "0"
+
+ if (sentinelStr != null) {
+ if (sentinelStr.trim().startsWith("0x")) {
+ sentinel = new BigInteger(sentinelStr.trim().substring(2), 16);
+ } else {
+ sentinel = new BigInteger(sentinelStr, 10);
+ }
+ }
+
+ revokeAll = req.getParameter("revokeAll");
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ X509CertImpl caCert = ((ICertificateAuthority) mAuthority).getSigningUnit().getCertImpl();
+
+ //if (isCertFromCA(caCert))
+ header.addStringValue("caSerialNumber",
+ caCert.getSerialNumber().toString(16));
+ }
+
+ // constructs the ldap filter on the server side
+ String queryCertFilter = buildFilter(req);
+
+ if (queryCertFilter == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ com.netscape.certsrv.apps.CMS.debug("queryCertFilter=" + queryCertFilter);
+
+ int totalRecordCount = -1;
+
+ try {
+ totalRecordCount = Integer.parseInt(req.getParameter("totalRecordCount"));
+ } catch (Exception e) {
+ }
+ processCertFilter(argSet, header, maxCount,
+ sentinel,
+ totalRecordCount,
+ req.getParameter("serialTo"),
+ queryCertFilter,
+ req, resp, revokeAll, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+
+ error = new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ ctx.addIntegerValue("maxCount", maxCount);
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void processCertFilter(CMSTemplateParams argSet,
+ IArgBlock header,
+ int maxCount,
+ BigInteger sentinel,
+ int totalRecordCount,
+ String serialTo,
+ String filter,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll,
+ Locale locale
+ ) throws EBaseException {
+ BigInteger serialToVal = MINUS_ONE;
+
+ try {
+ if (serialTo != null) {
+ serialTo = serialTo.trim();
+ if (serialTo.startsWith("0x")) {
+ serialToVal = new BigInteger
+ (serialTo.substring(2), 16);
+ serialTo = serialToVal.toString();
+ } else {
+ serialToVal = new BigInteger(serialTo);
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ String jumpTo = sentinel.toString();
+ int pSize = 0;
+ if (mReverse) {
+ if (!mHardJumpTo) //reverse gets one more
+ pSize = -1*maxCount-1;
+ else
+ pSize = -1*maxCount;
+ } else
+ pSize = maxCount;
+
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ filter, (String[]) null, jumpTo, mHardJumpTo, "serialno",
+ pSize);
+ // retrive maxCount + 1 entries
+
+ Enumeration e = list.getCertRecords(0, maxCount);
+
+ ICertRecordList tolist = null;
+ int toCurIndex = 0;
+
+ if (!serialToVal.equals(MINUS_ONE)) {
+ // if user specify a range, we need to
+ // calculate the totalRecordCount
+ tolist = (ICertRecordList) mCertDB.findCertRecordsInList(
+ filter,
+ (String[]) null, serialTo,
+ "serialno", maxCount);
+ Enumeration en = tolist.getCertRecords(0, 0);
+
+ if (en == null || (!en.hasMoreElements())) {
+ toCurIndex = list.getSize() - 1;
+ } else {
+ toCurIndex = tolist.getCurrentIndex();
+ ICertRecord rx = (ICertRecord) en.nextElement();
+ BigInteger curToSerial = rx.getSerialNumber();
+
+ if (curToSerial.compareTo(serialToVal) == -1) {
+ toCurIndex = list.getSize() - 1;
+ } else {
+ if (!rx.getSerialNumber().toString().equals(serialTo.trim())) {
+ toCurIndex = toCurIndex - 1;
+ }
+ }
+ }
+ }
+
+ int curIndex = list.getCurrentIndex();
+
+ int count = 0;
+ BigInteger firstSerial = new BigInteger("0");
+ BigInteger curSerial = new BigInteger("0");
+ ICertRecord[] recs = new ICertRecord[maxCount];
+ int rcount = 0;
+
+ if (e != null) {
+ /* in reverse (page up), because the sentinel is the one after the
+ * last item to be displayed, we need to skip it
+ */
+ while ((count < ((mReverse &&!mHardJumpTo)? (maxCount+1):maxCount)) && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null) {
+ com.netscape.certsrv.apps.CMS.debug("record "+count+" is null");
+ break;
+ }
+ curSerial = rec.getSerialNumber();
+ com.netscape.certsrv.apps.CMS.debug("record "+count+" is serial#"+curSerial);
+
+ if (count == 0) {
+ firstSerial = curSerial;
+ if (mReverse && !mHardJumpTo) {//reverse got one more, skip
+ count++;
+ continue;
+ }
+ }
+
+ // DS has a problem where last record will be returned
+ // even though the filter is not matched.
+ /*cfu - is this necessary? it breaks when paging up
+ if (curSerial.compareTo(sentinel) == -1) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial compare sentinel -1 break...");
+
+ break;
+ }
+ */
+ if (!serialToVal.equals(MINUS_ONE)) {
+ // check if we go over the limit
+ if (curSerial.compareTo(serialToVal) == 1) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial compare serialToVal 1 breaking...");
+ break;
+ }
+ }
+
+ if (mReverse) {
+ recs[rcount++] = rec;
+ } else {
+
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ count++;
+ }
+ } else {
+ com.netscape.certsrv.apps.CMS.debug(
+ "ListCerts::processCertFilter() - no Cert Records found!" );
+ return;
+ }
+
+ if (mReverse) {
+ // fill records into arg block and argSet
+ for (int ii = rcount-1; ii>= 0; ii--) {
+ if (recs[ii] != null) {
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+ //com.netscape.certsrv.apps.CMS.debug("item "+ii+" is serial # "+ recs[ii].getSerialNumber());
+ fillRecordIntoArg(recs[ii], rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ // peek ahead
+ ICertRecord nextRec = null;
+
+ if (e.hasMoreElements()) {
+ nextRec = (ICertRecord) e.nextElement();
+ }
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ if (!serialToVal.equals(MINUS_ONE))
+ header.addStringValue("serialTo", serialToVal.toString());
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("queryCertFilter", filter);
+ header.addStringValue("templateName", "queryCert");
+ header.addStringValue("queryFilter", filter);
+ header.addIntegerValue("maxCount", maxCount);
+ if (totalRecordCount == -1) {
+ if (!serialToVal.equals(MINUS_ONE)) {
+ totalRecordCount = toCurIndex - curIndex + 1;
+ com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
+ } else {
+ totalRecordCount = list.getSize() -
+ list.getCurrentIndex();
+ com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", totalRecordCount);
+ header.addIntegerValue("currentRecordCount", list.getSize() -
+ list.getCurrentIndex());
+
+ String qs = "";
+ if (mReverse)
+ qs = "querySentinelUp";
+ else
+ qs = "querySentinelDown";
+
+ if (mHardJumpTo) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
+
+ header.addStringValue("querySentinelUp", curSerial.toString());
+ } else {
+ if (nextRec == null) {
+ header.addStringValue(qs, null);
+ com.netscape.certsrv.apps.CMS.debug("nextRec is null");
+ if (mReverse) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
+
+ header.addStringValue("querySentinelUp", curSerial.toString());
+ }
+ } else {
+ BigInteger nextRecNo = nextRec.getSerialNumber();
+
+ if (serialToVal.equals(MINUS_ONE)) {
+ header.addStringValue(
+ qs, nextRecNo.toString());
+ } else {
+ if (nextRecNo.compareTo(serialToVal) <= 0) {
+ header.addStringValue(
+ qs, nextRecNo.toString());
+ } else {
+ header.addStringValue(qs,
+ null);
+ }
+ }
+ com.netscape.certsrv.apps.CMS.debug("querySentinel "+qs+" = "+nextRecNo.toString());
+ }
+ } // !mHardJumpto
+
+ header.addStringValue(!mReverse? "querySentinelUp":"querySentinelDown",
+ firstSerial.toString());
+
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int maxCount, int sentinel,
+ String filter, HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll, Locale locale)
+ throws EBaseException {
+ try {
+ if (filter.indexOf(CURRENT_TIME, 0) > -1) {
+ filter = insertCurrentTime(filter);
+ }
+ if (revokeAll != null && revokeAll.indexOf(CURRENT_TIME, 0) > -1) {
+ revokeAll = insertCurrentTime(revokeAll);
+ }
+
+ // xxx the filter includes serial number range???
+ ICertRecordList list =
+ (ICertRecordList) mCertDB.findCertRecordsInList(filter, null, maxCount);
+ // sentinel is the index on the list now, not serial number
+ Enumeration e =
+ list.getCertRecords(sentinel, sentinel + maxCount - 1);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ count++;
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("templateName", "queryCert");
+ header.addStringValue("queryFilter", filter);
+ header.addIntegerValue("maxCount", maxCount);
+ header.addIntegerValue("totalRecordCount", list.getSize());
+ if ((sentinel + count) < list.getSize())
+ header.addIntegerValue("querySentinelDown", sentinel + count);
+ else
+ header.addStringValue("querySentinelDown", null);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString()));
+ throw e;
+ }
+ return;
+ }
+
+ private String insertCurrentTime(String filter) {
+ Date now = null;
+ StringBuffer newFilter = new StringBuffer();
+ int k = 0;
+ int i = filter.indexOf(CURRENT_TIME, k);
+
+ while (i > -1) {
+ if (now == null) now = new Date();
+ if (newFilter.length() == 0) {
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ } else {
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ }
+ k = i + CURRENT_TIME.length();
+ i = filter.indexOf(CURRENT_TIME, k);
+ }
+ if (k > 0) {
+ newFilter.append(filter.substring(k, filter.length()));
+ }
+ return newFilter.toString();
+ }
+
+ /**
+ * Fills cert record into argument block.
+ */
+ private void fillRecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null) {
+ fillX509RecordIntoArg(rec, rarg);
+ }
+ }
+
+ private void fillX509RecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl cert = rec.getCertificate();
+
+ rarg.addIntegerValue("version", cert.getVersion());
+ rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal", cert.getSerialNumber().toString());
+
+ if (cert.getSubjectDN().toString().equals("")) {
+ rarg.addStringValue("subject", " ");
+ } else
+ rarg.addStringValue("subject", cert.getSubjectDN().toString());
+
+ rarg.addStringValue("type", "X.509");
+
+ try {
+ PublicKey pKey = cert.getPublicKey();
+ X509Key key = null;
+
+ if (pKey instanceof CertificateX509Key) {
+ CertificateX509Key certKey = (CertificateX509Key) pKey;
+
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ }
+ if (pKey instanceof X509Key) {
+ key = (X509Key) pKey;
+ }
+ rarg.addStringValue("subjectPublicKeyAlgorithm", key.getAlgorithmId().getOID().toString());
+ if (key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) {
+ RSAPublicKey rsaKey = new RSAPublicKey(key.getEncoded());
+
+ rarg.addIntegerValue("subjectPublicKeyLength", rsaKey.getKeySize());
+ }
+ } catch (Exception e) {
+ rarg.addStringValue("subjectPublicKeyAlgorithm", null);
+ rarg.addIntegerValue("subjectPublicKeyLength", 0);
+ }
+
+ rarg.addLongValue("validNotBefore", cert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter", cert.getNotAfter().getTime() / 1000);
+ rarg.addStringValue("signatureAlgorithm", cert.getSigAlgOID());
+ String issuedBy = rec.getIssuedBy();
+
+ if (issuedBy == null) issuedBy = "";
+ rarg.addStringValue("issuedBy", issuedBy); // cert.getIssuerDN().toString()
+ rarg.addLongValue("issuedOn", rec.getCreateTime().getTime() / 1000);
+
+ rarg.addStringValue("revokedBy",
+ ((rec.getRevokedBy() == null) ? "" : rec.getRevokedBy()));
+ if (rec.getRevokedOn() == null) {
+ rarg.addStringValue("revokedOn", null);
+ } else {
+ rarg.addLongValue("revokedOn", rec.getRevokedOn().getTime() / 1000);
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enum1 = crlExts.getElements();
+ int reason = 0;
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = (Extension) enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ rarg.addIntegerValue("revocationReason", reason);
+ }
+ }
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java b/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java
new file mode 100644
index 000000000..6b4e76496
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java
@@ -0,0 +1,389 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Provide statistical queries of request and certificate records.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Monitor extends CMSServlet {
+
+ private final static String TPL_FILE = "monitor.template";
+ private final static String INFO = "Monitor";
+
+ private ICertificateRepository mCertDB = null;
+ private IRequestQueue mQueue = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+
+ private int mTotalCerts = 0;
+ private int mTotalReqs = 0;
+
+ /**
+ * Constructs query servlet.
+ */
+ public Monitor() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'monitor.template' to render the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param startTime start of time period to query
+ * <li>http.param endTime end of time period to query
+ * <li>http.param interval time between queries
+ * <li>http.param numberOfIntervals number of queries to run
+ * <li>http.param maxResults =number
+ * <li>http.param timeLimit =time
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String startTime = null;
+ String endTime = null;
+ String interval = null;
+ String numberOfIntervals = null;
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ startTime = req.getParameter("startTime");
+ endTime = req.getParameter("endTime");
+ interval = req.getParameter("interval");
+ numberOfIntervals = req.getParameter("numberOfIntervals");
+
+ process(argSet, header, startTime, endTime, interval, numberOfIntervals, locale[0]);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESSING_REQ", e.toString()));
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE",
+ e.toString()));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ String startTime, String endTime,
+ String interval, String numberOfIntervals,
+ Locale locale)
+ throws EBaseException {
+ if (interval == null || interval.length() == 0) {
+ header.addStringValue("error", "Invalid interval: " + interval);
+ return;
+ }
+ if (numberOfIntervals == null || numberOfIntervals.length() == 0) {
+ header.addStringValue("error", "Invalid number of intervals: " + numberOfIntervals);
+ return;
+ }
+
+ Date startDate = StringToDate(startTime);
+
+ if (startDate == null) {
+ header.addStringValue("error", "Invalid start time: " + startTime);
+ return;
+ }
+
+ int iInterval = 0;
+
+ try {
+ iInterval = Integer.parseInt(interval);
+ } catch (NumberFormatException nfe) {
+ header.addStringValue("error", "Invalid interval: " + interval);
+ return;
+ }
+
+ int iNumberOfIntervals = 0;
+
+ try {
+ iNumberOfIntervals = Integer.parseInt(numberOfIntervals);
+ } catch (NumberFormatException nfe) {
+ header.addStringValue("error", "Invalid number of intervals: " + numberOfIntervals);
+ return;
+ }
+
+ header.addStringValue("startDate", startDate.toString());
+ header.addStringValue("startTime", startTime);
+ header.addIntegerValue("interval", iInterval);
+ header.addIntegerValue("numberOfIntervals", iNumberOfIntervals);
+
+ mTotalCerts = 0;
+ mTotalReqs = 0;
+
+ Date d1 = startDate;
+
+ for (int i = 0; i < iNumberOfIntervals; i++) {
+ Date d2 = nextDate(d1, iInterval - 1);
+ IArgBlock rarg = CMS.createArgBlock();
+ String e = getIntervalInfo(rarg, d1, d2);
+
+ if (e != null) {
+ header.addStringValue("error", e);
+ return;
+ }
+ argSet.addRepeatRecord(rarg);
+ d1 = nextDate(d2, 1);
+ }
+
+ header.addIntegerValue("totalNumberOfCertificates", mTotalCerts);
+ header.addIntegerValue("totalNumberOfRequests", mTotalReqs);
+
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+
+ return;
+ }
+
+ Date nextDate(Date d, int seconds) {
+ Date date = new Date((d.getTime()) + ((long) (seconds * 1000)));
+
+ return date;
+ }
+
+ String getIntervalInfo(IArgBlock arg, Date startDate, Date endDate) {
+ if (startDate != null && endDate != null) {
+ String startTime = DateToZString(startDate);
+ String endTime = DateToZString(endDate);
+ String filter = null;
+
+ arg.addStringValue("startTime", startTime);
+ arg.addStringValue("endTime", endTime);
+
+ try {
+ if (mCertDB != null) {
+ filter = Filter(ICertRecord.ATTR_CREATE_TIME, startTime, endTime);
+
+ Enumeration e = mCertDB.findCertRecs(filter);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec != null) {
+ count++;
+ }
+ }
+ arg.addIntegerValue("numberOfCertificates", count);
+ mTotalCerts += count;
+ }
+
+ if (mQueue != null) {
+ filter = Filter(IRequestRecord.ATTR_CREATE_TIME, startTime, endTime);
+
+ IRequestList reqList = mQueue.listRequestsByFilter(filter);
+
+ int count = 0;
+
+ while (reqList != null && reqList.hasMoreElements()) {
+ IRequestRecord rec = (IRequestRecord) reqList.nextRequest();
+
+ if (rec != null) {
+ if (count == 0) {
+ arg.addStringValue("firstRequest", rec.getRequestId().toString());
+ }
+ count++;
+ }
+ }
+ arg.addIntegerValue("numberOfRequests", count);
+ mTotalReqs += count;
+ }
+ } catch (Exception ex) {
+ return "Exception: " + ex;
+ }
+
+ return null;
+ } else {
+ return "Missing start or end date";
+ }
+ }
+
+ Date StringToDate(String z) {
+ Date d = null;
+
+ if (z != null && (z.length() == 14 ||
+ z.length() == 15 && (z.charAt(14) == 'Z' || z.charAt(14) == 'z'))) {
+ // 20020516132030Z or 20020516132030
+ try {
+ int year = Integer.parseInt(z.substring(0, 4)) - 1900;
+ int month = Integer.parseInt(z.substring(4, 6)) - 1;
+ int date = Integer.parseInt(z.substring(6, 8));
+ int hour = Integer.parseInt(z.substring(8, 10));
+ int minute = Integer.parseInt(z.substring(10, 12));
+ int second = Integer.parseInt(z.substring(12, 14));
+
+ d = new Date(year, month, date, hour, minute, second);
+ } catch (NumberFormatException nfe) {
+ }
+ } else if (z != null && z.length() > 1 && z.charAt(0) == '-') { // -5
+ try {
+ int i = Integer.parseInt(z);
+
+ d = new Date();
+ d = nextDate(d, i);
+ } catch (NumberFormatException nfe) {
+ }
+ }
+
+ return d;
+ }
+
+ String DateToZString(Date d) {
+ String time = "" + (d.getYear() + 1900);
+ int i = d.getMonth() + 1;
+
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getDate();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getHours();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getMinutes();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getSeconds();
+ if (i < 10) time += "0";
+ time += i + "Z";
+ return time;
+ }
+
+ String Filter(String name, String start, String end) {
+ String filter = "(&(" + name + ">=" + start + ")(" + name + "<=" + end + "))";
+
+ return filter;
+ }
+
+ String uriFilter(String name, String start, String end) {
+ String filter = "(%26(" + name + "%3e%3d" + start + ")(" + name + "%3c%3d" + end + "))";
+
+ return filter;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java
new file mode 100644
index 000000000..bb39b3ad8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java
@@ -0,0 +1,281 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Specify the RevocationReason when revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class ReasonToRevoke extends CMSServlet {
+
+ private final static String TPL_FILE = "reasonToRevoke.template";
+ private final static String INFO = "ReasonToRevoke";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+ private Random mRandom = null;
+ private Nonces mNonces = null;
+ private int mTimeLimits = 30; /* in seconds */
+
+ public ReasonToRevoke() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'reasonToRevoke.template' to render the response
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mCA != null && mCA.noncesEnabled()) {
+ mRandom = new Random();
+ mNonces = mCA.getNonces();
+ }
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ /* Server-Side time limit */
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "revoke");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ int totalRecordCount = 1;
+ EBaseException error = null;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ if (req.getParameter("totalRecordCount") != null) {
+ totalRecordCount =
+ Integer.parseInt(req.getParameter("totalRecordCount"));
+ }
+
+ revokeAll = req.getParameter("revokeAll");
+
+ process(argSet, header, req, resp,
+ revokeAll, totalRecordCount, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_RECORD_COUNT_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT"));
+ }
+
+ /*
+ catch (Exception e) {
+ noError = false;
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ errorlocale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll, int totalRecordCount,
+ Locale locale)
+ throws EBaseException {
+
+ header.addStringValue("revokeAll", revokeAll);
+ header.addIntegerValue("totalRecordCount", totalRecordCount);
+
+ if (mNonces != null) {
+ long n = mRandom.nextLong();
+ long m = mNonces.addNonce(n, getSSLClientCertificate(req));
+ if ((n + m) != 0) {
+ header.addStringValue("nonce", Long.toString(m));
+ }
+ }
+
+ try {
+ if (mCA != null) {
+ X509CertImpl caCert = mCA.getSigningUnit().getCertImpl();
+
+ if (isCertFromCA(caCert)) {
+ header.addStringValue("caSerialNumber",
+ caCert.getSerialNumber().toString(16));
+ }
+ }
+
+ /**
+ ICertRecordList list = mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+ **/
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ int count = 0;
+ String errorMsg = null;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null)
+ continue;
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null)
+ if (!(rec.getStatus().equals(ICertRecord.STATUS_REVOKED))) {
+ count++;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal",
+ xcert.getSerialNumber().toString());
+ rarg.addStringValue("subject",
+ xcert.getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ xcert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ xcert.getNotAfter().getTime() / 1000);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ header.addIntegerValue("verifiedRecordCount", count);
+
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error " + e);
+ throw e;
+ }
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
new file mode 100644
index 000000000..f046ebc9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
@@ -0,0 +1,607 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Allow agent to turn on/off authentication managers
+ *
+ * @version $Revision$, $Date$
+ */
+public class RemoteAuthConfig extends CMSServlet {
+
+ private final static String INFO = "RemoteAuthConfig";
+ private final static String TPL_FILE = "remoteAuthConfig.template";
+ private final static String ENABLE_REMOTE_CONFIG = "enableRemoteConfiguration";
+ private final static String REMOTELY_SET_INSTANCES = "remotelySetInstances";
+ private final static String MEMBER_OF = "memberOf";
+ private final static String UNIQUE_MEMBER = "uniqueMember";
+
+ private String mFormPath = null;
+ private IAuthSubsystem mAuthSubsystem = null;
+ private IConfigStore mAuthConfig = null;
+ private IConfigStore mFileConfig = null;
+ private Vector mRemotelySetInstances = new Vector();
+ private boolean mEnableRemoteConfiguration = false;
+
+ /**
+ * Constructs RemoteAuthConfig servlet.
+ */
+ public RemoteAuthConfig() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ *
+ * Presence of "auths.enableRemoteConfiguration=true" in CMS.cfg
+ * enables remote configuration for authentication plugins.
+ * List of remotely set instances can be found in CMS.cfg
+ * at "auths.remotelySetInstances=<name1>,<name2>,...,<nameN>"
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mFileConfig = CMS.getConfigStore();
+ mAuthConfig = mFileConfig.getSubStore("auths");
+ try {
+ mEnableRemoteConfiguration = mAuthConfig.getBoolean(ENABLE_REMOTE_CONFIG, false);
+ } catch (EBaseException eb) {
+ // Thanks to design of getBoolean we have to catch but we will never get anything.
+ }
+
+ String remoteList = null;
+
+ try {
+ remoteList = mAuthConfig.getString(REMOTELY_SET_INSTANCES, null);
+ } catch (EBaseException eb) {
+ // Thanks to design of getString we have to catch but we will never get anything.
+ }
+ if (remoteList != null) {
+ StringTokenizer s = new StringTokenizer(remoteList, ",");
+
+ while (s.hasMoreTokens()) {
+ String token = s.nextToken();
+
+ if (token != null && token.trim().length() > 0) {
+ mRemotelySetInstances.add(token.trim());
+ }
+ }
+ }
+
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTPS request. The format of this request is as follows:
+ * https://host:ee-port/remoteAuthConfig?
+ * op="add"|"delete"&
+ * instance=<instanceName>&
+ * of=<authPluginName>&
+ * host=<hostName>&
+ * port=<portNumber>&
+ * password=<password>&
+ * [adminDN=<adminDN>]&
+ * [uid=<uid>]&
+ * [baseDN=<baseDN>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ String host = req.getParameter("host");
+ String port = req.getParameter("port");
+
+ String adminDN = req.getParameter("adminDN");
+ String uid = req.getParameter("uid");
+ String baseDN = req.getParameter("baseDN");
+ String password = req.getParameter("password");
+
+ String replyTo = req.getParameter("replyTo");
+
+ if (replyTo != null && replyTo.length() > 0) {
+ ctx.addStringValue("replyTo", replyTo);
+ }
+
+ if (mEnableRemoteConfiguration) {
+ String errMsg = null;
+
+ if (adminDN != null && adminDN.length() > 0) {
+ errMsg = authenticateRemoteAdmin(host, port, adminDN, password);
+ } else {
+ errMsg = authenticateRemoteAdmin(host, port, uid, baseDN, password);
+ }
+ if (errMsg == null || errMsg.length() == 0) {
+ if (mAuthSubsystem != null && mAuthConfig != null) {
+ String op = req.getParameter("op");
+
+ if (op == null || op.length() == 0) {
+ header.addStringValue("error", "Undefined operation");
+ } else {
+ header.addStringValue("op", op);
+
+ if (op.equals("delete")) {
+ String plugin = req.getParameter("of");
+
+ if (isPluginListed(plugin)) {
+ String instance = req.getParameter("instance");
+
+ if (isInstanceListed(instance)) {
+ errMsg = deleteInstance(instance);
+ if (errMsg != null && errMsg.length() > 0) {
+ header.addStringValue("error", errMsg);
+ } else {
+ header.addStringValue("plugin", plugin);
+ header.addStringValue("instance", instance);
+ }
+ } else {
+ header.addStringValue("error", "Unknown instance " +
+ instance + ".");
+ }
+ } else {
+ header.addStringValue("error", "Unknown plugin name: " + plugin);
+ }
+ } else if (op.equals("add")) {
+ String plugin = req.getParameter("of");
+
+ if (isPluginListed(plugin)) {
+ String instance = req.getParameter("instance");
+
+ if (instance == null || instance.length() == 0) {
+ instance = makeInstanceName();
+ }
+ if (isInstanceListed(instance)) {
+ header.addStringValue("error", "Instance name " +
+ instance + " is already in use.");
+ } else {
+ errMsg = addInstance(instance, plugin,
+ host, port, baseDN,
+ req.getParameter("dnPattern"));
+ if (errMsg != null && errMsg.length() > 0) {
+ header.addStringValue("error", errMsg);
+ } else {
+ header.addStringValue("plugin", plugin);
+ header.addStringValue("instance", instance);
+ }
+ }
+ } else {
+ header.addStringValue("error", "Unknown plugin name: " + plugin);
+ }
+ } else {
+ header.addStringValue("error", "Unsupported operation: " + op);
+ }
+ }
+ } else {
+ header.addStringValue("error", "Invalid configuration data.");
+ }
+ } else {
+ header.addStringValue("error", errMsg);
+ }
+ } else {
+ header.addStringValue("error", "Remote configuration is disabled.");
+ }
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private String authenticateRemoteAdmin(String host, String port,
+ String adminDN, String password) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0 || port.trim().length() == 0) {
+ return "Missing port number.";
+ }
+ if (adminDN == null || adminDN.length() == 0) {
+ return "Missing admin DN.";
+ }
+ if (password == null || password.length() == 0) {
+ return "Missing password.";
+ }
+ int p = 0;
+
+ try {
+ p = Integer.parseInt(port.trim());
+ } catch (NumberFormatException e) {
+ return "Invalid port number: " + port + " (" + e.toString() + ")";
+ }
+
+ boolean connected = false;
+ LDAPConnection c = new LDAPConnection();
+
+ try {
+ c.connect(host, p);
+ connected = true;
+ try {
+ c.authenticate(adminDN, password);
+ LDAPEntry entry = c.read(adminDN);
+ LDAPAttribute attr = entry.getAttribute(MEMBER_OF);
+
+ if (attr != null) {
+ Enumeration eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = (String) eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ Enumeration eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = (String) eValues.nextElement();
+
+ if (value.equals(entry.getDN())) {
+ c.disconnect();
+ return null;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ c.disconnect();
+ return null;
+ }
+
+ } catch (LDAPException e) {
+
+ /*
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.INVALID_CREDENTIALS:
+ case LDAPException.INSUFFICIENT_ACCESS_RIGHTS:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ default:
+ }
+ */
+ c.disconnect();
+ return "LDAP error: " + e.toString();
+ }
+
+ if (connected) {
+ c.disconnect();
+ }
+ } catch (LDAPException e) {
+ return "LDAP error: " + e.toString();
+ }
+
+ return "Access unauthorized";
+ }
+
+ private String authenticateRemoteAdmin(String host, String port,
+ String uid, String baseDN,
+ String password) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0 || port.trim().length() == 0) {
+ return "Missing port number.";
+ }
+ if (uid == null || uid.length() == 0) {
+ return "Missing UID.";
+ }
+ if (uid.indexOf('*') > -1) {
+ return "Invalid UID: " + uid;
+ }
+ if (password == null || password.length() == 0) {
+ return "Missing password.";
+ }
+ int p = 0;
+
+ try {
+ p = Integer.parseInt(port.trim());
+ } catch (NumberFormatException e) {
+ return "Invalid port number: " + port + " (" + e.toString() + ")";
+ }
+ if (baseDN == null || baseDN.length() == 0) {
+ return "Missing base DN.";
+ }
+
+ boolean connected = false;
+ LDAPConnection c = new LDAPConnection();
+
+ try {
+ c.connect(host, p);
+ connected = true;
+ boolean memberOf = false;
+ LDAPSearchResults results = c.search(baseDN, LDAPv2.SCOPE_SUB,
+ "(uid=" + uid + ")",
+ null, false);
+
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = null;
+
+ try {
+ entry = results.next();
+ c.authenticate(entry.getDN(), password);
+ LDAPAttribute attr = entry.getAttribute(MEMBER_OF);
+
+ if (attr != null) {
+ memberOf = true;
+ Enumeration eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = (String) eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ Enumeration eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = (String) eValues.nextElement();
+
+ if (value.equals(entry.getDN())) {
+ c.disconnect();
+ return null;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ continue;
+
+ case LDAPException.INVALID_CREDENTIALS:
+ break;
+
+ case LDAPException.INSUFFICIENT_ACCESS_RIGHTS:
+ break;
+
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ break;
+
+ default:
+ continue;
+ }
+ }
+ }
+ if (connected) {
+ c.disconnect();
+ }
+
+ if (!memberOf) {
+ return null;
+ }
+ } catch (LDAPException e) {
+ return "LDAP error: " + e.toString();
+ }
+
+ return "Access unauthorized";
+ }
+
+ private String addInstance(String instance, String plugin,
+ String host, String port,
+ String baseDN, String dnPattern) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0) {
+ return "Missing port number.";
+ }
+
+ IConfigStore c0 = mAuthConfig.getSubStore("instance");
+ IConfigStore c1 = c0.makeSubStore(instance);
+
+ c1.putString("dnpattern", dnPattern);
+ c1.putString("ldapByteAttributes", "");
+ c1.putString("ldapStringAttributes", "");
+ c1.putString("pluginName", plugin);
+ if (baseDN != null && baseDN.length() > 0)
+ c1.putString("ldap.basedn", baseDN);
+ c1.putString("ldap.minConns", "");
+ c1.putString("ldap.maxConns", "");
+ c1.putString("ldap.ldapconn.host", host);
+ c1.putString("ldap.ldapconn.port", port);
+ c1.putString("ldap.ldapconn.secureConn", "false");
+ c1.putString("ldap.ldapconn.version", "3");
+
+ mRemotelySetInstances.add(instance);
+
+ IAuthManager authMgrInst = mAuthSubsystem.getAuthManagerPlugin(plugin);
+
+ if (authMgrInst != null) {
+ try {
+ authMgrInst.init(instance, plugin, c1);
+ } catch (EBaseException e) {
+ c0.removeSubStore(instance);
+ mRemotelySetInstances.remove(instance);
+ return e.toString();
+ }
+ mAuthSubsystem.add(instance, authMgrInst);
+ }
+
+ StringBuffer list = new StringBuffer();
+
+ for (int i = 0; i < mRemotelySetInstances.size(); i++) {
+ if (i > 0) list.append(",");
+ list.append((String) mRemotelySetInstances.elementAt(i));
+ }
+
+ mAuthConfig.putString(REMOTELY_SET_INSTANCES, list.toString());
+
+ try {
+ mFileConfig.commit(false);
+ } catch (EBaseException e) {
+ c0.removeSubStore(instance);
+ mRemotelySetInstances.remove(instance);
+ return e.toString();
+ }
+
+ return null;
+ }
+
+ private String deleteInstance(String instance) {
+ IConfigStore c = mAuthConfig.getSubStore("instance");
+
+ c.removeSubStore(instance);
+
+ if (mRemotelySetInstances.remove(instance)) {
+ StringBuffer list = new StringBuffer();
+
+ for (int i = 0; i < mRemotelySetInstances.size(); i++) {
+ if (i > 0) list.append(",");
+ list.append((String) mRemotelySetInstances.elementAt(i));
+ }
+
+ mAuthConfig.putString(REMOTELY_SET_INSTANCES, list.toString());
+ }
+
+ try {
+ mFileConfig.commit(false);
+ } catch (EBaseException e) {
+ return e.toString();
+ }
+ mAuthSubsystem.delete(instance);
+
+ return null;
+ }
+
+ private boolean isPluginListed(String pluginName) {
+ boolean isListed = false;
+
+ if (pluginName != null && pluginName.length() > 0) {
+ Enumeration e = mAuthSubsystem.getAuthManagerPlugins();
+
+ while (e.hasMoreElements()) {
+ AuthMgrPlugin plugin = (AuthMgrPlugin) e.nextElement();
+
+ if (pluginName.equals(plugin.getId())) {
+ isListed = true;
+ break;
+ }
+ }
+ }
+
+ return isListed;
+ }
+
+ private boolean isInstanceListed(String instanceName) {
+ boolean isListed = false;
+
+ if (instanceName != null && instanceName.length() > 0) {
+ Enumeration e = mAuthSubsystem.getAuthManagers();
+
+ while (e.hasMoreElements()) {
+ IAuthManager authManager = (IAuthManager) e.nextElement();
+
+ if (instanceName.equals(authManager.getName())) {
+ isListed = true;
+ break;
+ }
+ }
+ }
+
+ return isListed;
+ }
+
+ private String makeInstanceName() {
+ Date now = new Date();
+ int y = 1900 + now.getYear();
+ String name = "R" + y;
+
+ if (now.getMonth() < 10) name += "0";
+ name += now.getMonth();
+ if (now.getDate() < 10) name += "0";
+ name += now.getDate();
+ if (now.getHours() < 10) name += "0";
+ name += now.getHours();
+ if (now.getMinutes() < 10) name += "0";
+ name += now.getMinutes();
+ if (now.getSeconds() < 10) name += "0";
+ name += now.getSeconds();
+ return name;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java
new file mode 100644
index 000000000..fb0bf75da
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java
@@ -0,0 +1,517 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+import netscape.security.extensions.*;
+
+/**
+ * Certificate Renewal
+ *
+ * @version $Revision$, $Date$
+ */
+public class RenewalServlet extends CMSServlet {
+ // renewal templates.
+ public static final String
+ RENEWAL_SUCCESS_TEMPLATE = "RenewalSuccess.template";
+
+ // http params
+ public static final String CERT_TYPE = "certType";
+ public static final String SERIAL_NO = "serialNo";
+ // XXX can't do pkcs10 cause it's got no serial no.
+ // (unless put serial no in pki attributes)
+ // public static final String PKCS10 = "pkcs10";
+ public static final String IMPORT_CERT = "importCert";
+
+ private String mRenewalSuccessTemplate = RENEWAL_SUCCESS_TEMPLATE;
+ private ICMSTemplateFiller
+ mRenewalSuccessFiller = new ImportCertsTemplateFiller();
+
+ public RenewalServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet makes use of the
+ * template file "RenewalSuccess.template" to render the
+ * response
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success template. has same info as enrollment.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ try {
+ mRenewalSuccessTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mRenewalSuccessTemplate == null)
+ mRenewalSuccessTemplate = RENEWAL_SUCCESS_TEMPLATE;
+ String fillername =
+ sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mRenewalSuccessFiller = filler;
+ }
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
+ mId));
+ }
+
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ long startTime = CMS.getCurrentDate().getTime();
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+
+ // renewal requires either:
+ // - coming from ee:
+ // - old cert from ssl client auth
+ // - old certs from auth manager
+ // - coming from agent or trusted RA:
+ // - serial no of cert to be renewed.
+
+ BigInteger old_serial_no = null;
+ X509CertImpl old_cert = null;
+ X509CertImpl renewed_cert = null;
+ Date notBefore = null;
+ Date notAfter = null;
+ boolean doSaveAuthToken = false;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "renew");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null && !mAuthMgr.equals("sslClientCertAuthMgr")) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+
+ // coming from agent
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ X509Certificate[] cert = new X509Certificate[1];
+
+ old_serial_no = getCertFromAgent(httpParams, cert);
+ old_cert = (X509CertImpl) cert[0];
+
+ // optional validity params from input.
+ int beginYear = httpParams.getValueAsInt("beginYear", -1);
+ int beginMonth = httpParams.getValueAsInt("beginMonth", -1);
+ int beginDate = httpParams.getValueAsInt("beginDate", -1);
+ int endYear = httpParams.getValueAsInt("endYear", -1);
+ int endMonth = httpParams.getValueAsInt("endMonth", -1);
+ int endDate = httpParams.getValueAsInt("endDate", -1);
+
+ if (beginYear != -1 && beginMonth != -1 && beginDate != -1 &&
+ endYear != -1 && endMonth != -1 && endDate != -1) {
+ notBefore = new Date(beginYear, beginMonth, beginDate);
+ notAfter = new Date(endYear, endMonth, endDate);
+ }
+ } // coming from client
+ else {
+ // from auth manager
+ X509CertImpl[] cert = new X509CertImpl[1];
+
+ old_serial_no = getCertFromAuthMgr(authToken, cert);
+ old_cert = cert[0];
+ }
+
+ IRequest req = null;
+
+ try {
+ // get ready to send request to request queue.
+ X509CertInfo new_certInfo = null;
+
+ req = mRequestQueue.newRequest(IRequest.RENEWAL_REQUEST);
+ req.setExtData(IRequest.OLD_SERIALS, new BigInteger[] {old_serial_no});
+ if (old_cert != null) {
+ req.setExtData(IRequest.OLD_CERTS,
+ new X509CertImpl[] { old_cert }
+ );
+ // create new certinfo from old_cert contents.
+ X509CertInfo old_certInfo = (X509CertInfo)
+ ((X509CertImpl) old_cert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ new_certInfo = new X509CertInfo(old_certInfo.getEncodedInfo());
+ } else {
+ // if no old cert (came from RA agent) create new cert info
+ // (serializable) to pass through policies. And set the old
+ // serial number to pick up.
+ new_certInfo = new CertInfo();
+ new_certInfo.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber(old_serial_no));
+ }
+
+ if (notBefore == null || notAfter == null) {
+ notBefore = new Date(0);
+ notAfter = new Date(0);
+ }
+ new_certInfo.set(X509CertInfo.VALIDITY,
+ new CertificateValidity(notBefore, notAfter));
+ req.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { new_certInfo }
+ );
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_RENEWAL_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SETTING_RENEWAL_VALIDITY_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_RENEWAL_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SETTING_RENEWAL_VALIDITY_ERROR"));
+ }
+
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+ if (doSaveAuthToken)
+ saveAuthToken(authToken, req);
+ cmsReq.setIRequest(req);
+
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+
+ // for audit log
+ String initiative = null;
+ String agentID = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }else {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ // check resulting status
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus();
+ // audit log the status
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "violation: " +
+ wholeMsg.toString()}
+ // wholeMsg},
+ // ILogger.L_MULTILINE
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+ }
+ } else { // other imcomplete status
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+ }
+ return;
+ }
+
+ // service error
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ CMS.debug(
+ "RenewalServlet: Result for request " + req.getRequestId() + " is " + result);
+ if (result.equals(IRequest.RES_ERROR)) {
+ CMS.debug(
+ "RenewalServlet: Result for request " + req.getRequestId() + " is error.");
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+
+ }
+ }
+ }
+ return;
+ }
+
+ // success.
+ X509CertImpl[] certs = req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ renewed_cert = certs[0];
+ respondSuccess(cmsReq, renewed_cert);
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "new serial number: 0x" +
+ renewed_cert.getSerialNumber().toString(16) + " time: " + (endTime - startTime)}
+ );
+
+ return;
+ }
+
+ private void respondSuccess(
+ CMSRequest cmsReq, X509CertImpl renewed_cert)
+ throws EBaseException {
+ cmsReq.setResult(new X509CertImpl[] {renewed_cert}
+ );
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // check if cert should be imported.
+ // browser must have input type set to nav or cartman since
+ // there's no other way to tell
+
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ String agent = httpReq.getHeader("user-agent");
+
+ if (checkImportCertToNav(cmsReq.getHttpResp(),
+ httpParams, renewed_cert)) {
+ return;
+ } else {
+ try {
+ renderTemplate(cmsReq,
+ mRenewalSuccessTemplate, mRenewalSuccessFiller);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGE_ERROR_DISPLAY_TEMPLATE_1",
+ mRenewalSuccessTemplate, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+ return;
+ }
+
+ protected BigInteger getRenewedCert(ICertRecord certRec)
+ throws EBaseException {
+ BigInteger renewedCert = null;
+ String serial = null;
+ MetaInfo meta = certRec.getMetaInfo();
+
+ if (meta == null) {
+ log(ILogger.LL_INFO,
+ "no meta info in cert serial 0x" + certRec.getSerialNumber().toString(16));
+ return null;
+ }
+ serial = (String) meta.get(ICertRecord.META_RENEWED_CERT);
+ if (serial == null) {
+ log(ILogger.LL_INFO,
+ "no renewed cert in cert 0x" + certRec.getSerialNumber().toString(16));
+ return null;
+ }
+ renewedCert = new BigInteger(serial);
+ log(ILogger.LL_INFO,
+ "renewed cert serial 0x" + renewedCert.toString(16) + "found for 0x" +
+ certRec.getSerialNumber().toString(16));
+ return renewedCert;
+ }
+
+ /**
+ * get certs to renew from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_RENEW"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_RENEW"));
+ }
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_RENEW_1", serialno.toString(16)));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_RENEWAL"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * get cert to renew from auth manager
+ */
+ private BigInteger getCertFromAuthMgr(
+ IAuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_RENEW_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_RENEW_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, "certficate from auth manager for " +
+ " renewal is not from this ca.");
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_RENEWAL"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
new file mode 100644
index 000000000..67a829f9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
@@ -0,0 +1,386 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Random;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateEncodingException;
+
+import netscape.security.x509.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Perform the first step in revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class RevocationServlet extends CMSServlet {
+ private final static String PROP_REVOKEBYDN = "revokeByDN";
+ // revocation templates.
+ private final static String TPL_FILE = "reasonToRevoke.template";
+
+ // http params
+ public static final String SERIAL_NO = "serialNo";
+ // XXX can't do pkcs10 cause it's got no serial no.
+ // (unless put serial no in pki attributes)
+ // public static final String PKCS10 = "pkcs10";
+ public static final String REASON_CODE = "reasonCode";
+
+ private String mFormPath = null;
+ private boolean mRevokeByDN = true;
+
+ private Random mRandom = null;
+ private Nonces mNonces = null;
+
+
+ public RevocationServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses
+ * the template file "reasonToRevoke.template" to render the
+ * result.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success template. has same info as enrollment.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ mFormPath = "/" + TPL_FILE;
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = "/" + TPL_FILE;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ if (((ICertificateAuthority) mAuthority).noncesEnabled()) {
+ mNonces = ((ICertificateAuthority) mAuthority).getNonces();
+ mRandom = new Random();
+ }
+ }
+
+ // set to false by revokeByDN=false in web.xml
+ mRevokeByDN = false;
+ String tmp = sc.getInitParameter(PROP_REVOKEBYDN);
+
+ if (tmp == null || tmp.trim().equalsIgnoreCase("false"))
+ mRevokeByDN = false;
+ else if (tmp.trim().equalsIgnoreCase("true"))
+ mRevokeByDN = true;
+ } catch (Exception e) {
+ }
+ }
+
+
+ /**
+ * Process the HTTP request. Note that this servlet does not
+ * actually perform the certificate revocation. This is the first
+ * step in the multi-step revocation process. (the next step is
+ * in the ReasonToRevoke servlet.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ // revocation requires either:
+ // - coming from ee:
+ // - old cert from ssl client auth
+ // - old certs from auth manager
+ // - coming from agent or trusted RA:
+ // - serial no of cert to be revoked.
+
+ BigInteger old_serial_no = null;
+ X509CertImpl old_cert = null;
+ String revokeAll = null;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // coming from agent
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ X509Certificate[] cert = new X509Certificate[1];
+
+ old_serial_no = getCertFromAgent(httpParams, cert);
+ old_cert = (X509CertImpl) cert[0];
+ } // coming from client
+ else {
+ // from auth manager
+ X509CertImpl[] cert = new X509CertImpl[1];
+
+ old_serial_no = getCertFromAuthMgr(authToken, cert);
+ old_cert = cert[0];
+ }
+
+ header.addStringValue("serialNumber", old_cert.getSerialNumber().toString(16));
+ header.addStringValue("serialNumberDecimal", old_cert.getSerialNumber().toString());
+ // header.addStringValue("subject", old_cert.getSubjectDN().toString());
+ // header.addLongValue("validNotBefore", old_cert.getNotBefore().getTime()/1000);
+ // header.addLongValue("validNotAfter", old_cert.getNotAfter().getTime()/1000);
+
+ if (mNonces != null) {
+ long n = mRandom.nextLong();
+ long m = mNonces.addNonce(n, (X509Certificate)old_cert);
+ if ((n + m) != 0) {
+ header.addStringValue("nonce", Long.toString(m));
+ }
+ }
+
+ boolean noInfo = false;
+ X509CertImpl[] certsToRevoke = null;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ certsToRevoke = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificates(
+ old_cert.getSubjectDN().toString(),
+ ICertificateRepository.ALL_UNREVOKED_CERTS);
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest req = mRequestQueue.newRequest(IRequest.GETCERTS_REQUEST);
+ String filter = "(&(" + ICertRecord.ATTR_X509CERT + "." +
+ X509CertInfo.SUBJECT + "=" +
+ old_cert.getSubjectDN().toString() + ")(|(" +
+ ICertRecord.ATTR_CERT_STATUS + "=" +
+ ICertRecord.STATUS_VALID + ")(" +
+ ICertRecord.ATTR_CERT_STATUS + "=" +
+ ICertRecord.STATUS_EXPIRED + ")))";
+
+ req.setExtData(IRequest.CERT_FILTER, filter);
+ mRequestQueue.processRequest(req);
+ RequestStatus status = req.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ header.addStringValue("request", req.getRequestId().toString());
+ Enumeration enum1 = req.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(IRequest.OLD_CERTS)) {
+ X509CertImpl[] certs = req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ certsToRevoke = certs;
+ }
+ }
+ } else {
+ noInfo = true;
+ }
+ }
+
+ boolean authorized = false;
+
+ if (certsToRevoke != null && certsToRevoke.length > 0) {
+ for (int i = 0; i < certsToRevoke.length; i++) {
+ if (old_cert.getSerialNumber().equals(certsToRevoke[i].getSerialNumber())) {
+ authorized = true;
+ break;
+ }
+ }
+ }
+
+ if (!noInfo && (certsToRevoke == null || certsToRevoke.length == 0 ||
+ (!authorized))) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_ALREADY_REVOKED_1", old_serial_no.toString(16)));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_CERT_ALREADY_REVOKED"));
+ }
+
+ if (!mRevokeByDN || noInfo) {
+ certsToRevoke = new X509CertImpl[1];
+ certsToRevoke[0] = old_cert;
+ try {
+ byte[] ba = old_cert.getEncoded();
+ // Do base 64 encoding
+
+ header.addStringValue("b64eCertificate", com.netscape.osutil.OSUtil.BtoA(ba));
+ } catch (CertificateEncodingException e) {
+ }
+ }
+
+ if (certsToRevoke != null && certsToRevoke.length > 0) {
+ header.addIntegerValue("totalRecordCount", certsToRevoke.length);
+ header.addIntegerValue("verifiedRecordCount", certsToRevoke.length);
+
+ for (int i = 0; i < certsToRevoke.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ certsToRevoke[i].getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal",
+ certsToRevoke[i].getSerialNumber().toString());
+ rarg.addStringValue("subject",
+ certsToRevoke[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certsToRevoke[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certsToRevoke[i].getNotAfter().getTime() / 1000);
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ // set revocation reason, default to unspecified if not set.
+ int reasonCode = httpParams.getValueAsInt(REASON_CODE, 0);
+
+ header.addIntegerValue("reason", reasonCode);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ return;
+ }
+
+ /**
+ * get cert to revoke from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_REVOKE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_REVOKE"));
+ }
+
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * get cert to revoke from auth manager
+ */
+ private BigInteger getCertFromAuthMgr(
+ IAuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
new file mode 100644
index 000000000..95622c9bb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
@@ -0,0 +1,101 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.RevokedCertImpl;
+
+import org.mozilla.jss.ssl.SSLSocket;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Certificates Template filler.
+ * must have list of certificates in result.
+ * looks at inputs: certtype.
+ * outputs:
+ * - cert type from http input (if any)
+ * - CA chain
+ * - authority name (RM, CM, DRM)
+ * - scheme:host:port of server.
+ * array of one or more
+ * - cert serial number
+ * - cert pretty print
+ * - cert in base 64 encoding.
+ * - cmmf blob to import
+ * @version $Revision$, $Date$
+ */
+class RevocationSuccessTemplateFiller implements ICMSTemplateFiller {
+ public final static String SERIAL_NO = "serialNo";
+
+ public RevocationSuccessTemplateFiller() {
+ }
+
+ /**
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // set host name and port.
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String host = httpReq.getServerName();
+ int port = httpReq.getServerPort();
+ String scheme = httpReq.getScheme();
+
+ fixed.set(ICMSTemplateFiller.HOST, host);
+ fixed.set(ICMSTemplateFiller.PORT, Integer.valueOf(port));
+ fixed.set(ICMSTemplateFiller.SCHEME, scheme);
+
+ // this authority
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ (String) authority.getOfficialName());
+
+ // XXX CA chain.
+
+ RevokedCertImpl[] revoked =
+ (RevokedCertImpl[]) cmsReq.getResult();
+
+ // revoked certs.
+ for (int i = 0; i < revoked.length; i++) {
+ IArgBlock repeat = CMS.createArgBlock();
+
+ repeat.set(SERIAL_NO, revoked[i].getSerialNumber());
+ params.addRepeatRecord(repeat);
+ }
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java b/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
new file mode 100644
index 000000000..3f74a2696
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
@@ -0,0 +1,758 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Search for certificates matching complex query filter
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchCerts extends CMSServlet {
+
+ private final static String TPL_FILE = "srchCert.template";
+ private final static String INFO = "SrchCerts";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ private final static String CURRENT_TIME = "currentTime";
+ private final static int MAX_RESULTS = 1000;
+
+ private ICertificateRepository mCertDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = MAX_RESULTS;
+ private int mTimeLimits = 30; /* in seconds */
+ private boolean mUseClientFilter = false;
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchCerts() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses srchCert.template
+ * to render the response
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ISubsystem) {
+ ISubsystem sub = (ISubsystem) mAuthority;
+ IConfigStore authConfig = sub.getConfigStore();
+
+ if (authConfig != null) {
+ try {
+ mMaxReturns = authConfig.getInteger(PROP_MAX_SEARCH_RETURNS, MAX_RESULTS);
+ } catch (EBaseException e) {
+ // do nothing
+ }
+ }
+ }
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ /* Server-Side time limit */
+ try {
+ int maxResults = Integer.parseInt(sc.getInitParameter("maxResults"));
+ if (maxResults < mMaxReturns)
+ mMaxReturns = maxResults;
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ /* useClientFilter should be off by default. We keep
+ this parameter around so that we do not break
+ the client applications that submits raw LDAP
+ filter into this servlet. */
+ if (sc.getInitParameter("useClientFilter") != null &&
+ sc.getInitParameter("useClientFilter").equalsIgnoreCase("true")) {
+ mUseClientFilter = true;
+ }
+ }
+
+ private boolean isOn(HttpServletRequest req, String name)
+ {
+ String inUse = req.getParameter(name);
+ if (inUse == null) {
+ return false;
+ }
+ if (inUse.equals("on")) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isOff(HttpServletRequest req, String name)
+ {
+ String inUse = req.getParameter(name);
+ if (inUse == null) {
+ return false;
+ }
+ if (inUse.equals("off")) {
+ return true;
+ }
+ return false;
+ }
+
+ private void buildCertStatusFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "statusInUse")) {
+ return;
+ }
+ String status = req.getParameter("status");
+ filter.append("(certStatus=");
+ filter.append(status);
+ filter.append(")");
+ }
+
+ private void buildProfileFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "profileInUse")) {
+ return;
+ }
+ String profile = req.getParameter("profile");
+ filter.append("(certMetaInfo=profileId:");
+ filter.append(profile);
+ filter.append(")");
+ }
+
+ private void buildBasicConstraintsFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "basicConstraintsInUse")) {
+ return;
+ }
+ filter.append("(x509cert.BasicConstraints.isCA=on)");
+ }
+
+ private void buildSerialNumberRangeFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "serialNumberRangeInUse")) {
+ return;
+ }
+ boolean changed = false;
+ String serialFrom = req.getParameter("serialFrom");
+ if (serialFrom != null && !serialFrom.equals("")) {
+ filter.append("(certRecordId>=" + serialFrom + ")");
+ changed = true;
+ }
+ String serialTo = req.getParameter("serialTo");
+ if (serialTo != null && !serialTo.equals("")) {
+ filter.append("(certRecordId<=" + serialTo + ")");
+ changed = true;
+ }
+ if (!changed) {
+ filter.append("(certRecordId=*)");
+ }
+ }
+
+ private void buildAVAFilter(HttpServletRequest req, String paramName,
+ String avaName, StringBuffer lf, String match)
+ {
+ String val = req.getParameter(paramName);
+ if (val != null && !val.equals("")) {
+ if (match != null && match.equals("exact")) {
+ lf.append("(|");
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append(",*)");
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append(")");
+ lf.append(")");
+ } else {
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append("*");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append("*)");
+ }
+ }
+ }
+
+ private void buildSubjectFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "subjectInUse")) {
+ return;
+ }
+ StringBuffer lf = new StringBuffer();
+ String match = req.getParameter("match");
+
+ buildAVAFilter(req, "eMail", "E", lf, match);
+ buildAVAFilter(req, "commonName", "CN", lf, match);
+ buildAVAFilter(req, "userID", "UID", lf, match);
+ buildAVAFilter(req, "orgUnit", "OU", lf, match);
+ buildAVAFilter(req, "org", "O", lf, match);
+ buildAVAFilter(req, "locality", "L", lf, match);
+ buildAVAFilter(req, "state", "ST", lf, match);
+ buildAVAFilter(req, "country", "C", lf, match);
+
+ if (lf.length() == 0) {
+ filter.append("(x509cert.subject=*)");
+ return;
+ }
+ if (match.equals("exact")) {
+ filter.append("(&");
+ filter.append(lf);
+ filter.append(")");
+ } else {
+ filter.append("(|");
+ filter.append(lf);
+ filter.append(")");
+ }
+ }
+
+ private void buildRevokedByFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revokedByInUse")) {
+ return;
+ }
+ String revokedBy = req.getParameter("revokedBy");
+ if (revokedBy == null || revokedBy.equals("")) {
+ filter.append("(certRevokedBy=*)");
+ } else {
+ filter.append("(certRevokedBy=");
+ filter.append(revokedBy);
+ filter.append(")");
+ }
+ }
+
+ private void buildDateFilter(HttpServletRequest req, String prefix,
+ String outStr, long adjustment,
+ StringBuffer filter)
+ {
+ String queryCertFilter = null;
+ long epoch = 0;
+ try {
+ epoch = Long.parseLong(req.getParameter(prefix));
+ } catch (NumberFormatException e) {
+ // exception safely ignored
+ }
+ Calendar from = Calendar.getInstance();
+ from.setTimeInMillis(epoch);
+ CMS.debug("buildDateFilter epoch=" + req.getParameter(prefix));
+ CMS.debug("buildDateFilter from=" + from);
+ filter.append("(");
+ filter.append(outStr);
+ filter.append(Long.toString(from.getTimeInMillis() + adjustment));
+ filter.append(")");
+ }
+
+ private void buildRevokedOnFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revokedOnInUse")) {
+ return;
+ }
+ buildDateFilter(req, "revokedOnFrom", "certRevokedOn>=", 0, filter);
+ buildDateFilter(req, "revokedOnTo", "certRevokedOn<=", 86399999,
+ filter);
+ }
+
+ private void buildRevocationReasonFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revocationReasonInUse")) {
+ return;
+ }
+ String reasons = req.getParameter("revocationReason");
+ if (reasons == null) {
+ return;
+ }
+ String queryCertFilter = null;
+ StringTokenizer st = new StringTokenizer(reasons, ",");
+ if (st.hasMoreTokens()) {
+ filter.append("(|");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (queryCertFilter == null) {
+ queryCertFilter = "";
+ }
+ filter.append("(x509cert.certRevoInfo=");
+ filter.append(token);
+ filter.append(")");
+ }
+ filter.append(")");
+ }
+ }
+
+ private void buildIssuedByFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "issuedByInUse")) {
+ return;
+ }
+ String issuedBy = req.getParameter("issuedBy");
+ if (issuedBy == null || issuedBy.equals("")) {
+ filter.append("(certIssuedBy=*)");
+ } else {
+ filter.append("(certIssuedBy=");
+ filter.append(issuedBy);
+ filter.append(")");
+ }
+ }
+
+ private void buildIssuedOnFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "issuedOnInUse")) {
+ return;
+ }
+ buildDateFilter(req, "issuedOnFrom", "certCreateTime>=", 0, filter);
+ buildDateFilter(req, "issuedOnTo", "certCreateTime<=", 86399999,
+ filter);
+ }
+
+ private void buildValidNotBeforeFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validNotBeforeInUse")) {
+ return;
+ }
+ buildDateFilter(req, "validNotBeforeFrom", "x509cert.notBefore>=",
+ 0, filter);
+ buildDateFilter(req, "validNotBeforeTo", "x509cert.notBefore<=",
+ 86399999, filter);
+ }
+
+ private void buildValidNotAfterFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validNotAfterInUse")) {
+ return;
+ }
+ buildDateFilter(req, "validNotAfterFrom", "x509cert.notAfter>=",
+ 0, filter);
+ buildDateFilter(req, "validNotAfterTo", "x509cert.notAfter<=",
+ 86399999, filter);
+ }
+
+ private void buildValidityLengthFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validityLengthInUse")) {
+ return;
+ }
+ String op = req.getParameter("validityOp");
+ long count = 0;
+ try {
+ count = Long.parseLong(req.getParameter("count"));
+ } catch (NumberFormatException e) {
+ // safely ignore
+ }
+ long unit = 0;
+ try {
+ unit = Long.parseLong(req.getParameter("unit"));
+ } catch (NumberFormatException e) {
+ // safely ignore
+ }
+ filter.append("(");
+ filter.append("x509cert.duration");
+ filter.append(op);
+ filter.append(count * unit);
+ filter.append(")");
+ }
+
+ private void buildCertTypeFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "certTypeInUse")) {
+ return;
+ }
+ if (isOn(req, "SSLClient")) {
+ filter.append("(x509cert.nsExtension.SSLClient=on)");
+ } else if (isOff(req, "SSLClient")) {
+ filter.append("(x509cert.nsExtension.SSLClient=off)");
+ }
+ if (isOn(req, "SSLServer")) {
+ filter.append("(x509cert.nsExtension.SSLServer=on)");
+ } else if (isOff(req, "SSLServer")) {
+ filter.append("(x509cert.nsExtension.SSLServer=off)");
+ }
+ if (isOn(req, "SecureEmail")) {
+ filter.append("(x509cert.nsExtension.SecureEmail=on)");
+ } else if (isOff(req, "SecureEmail")) {
+ filter.append("(x509cert.nsExtension.SecureEmail=off)");
+ }
+ if (isOn(req, "SubordinateSSLCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateSSLCA=on)");
+ } else if (isOff(req, "SubordinateSSLCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateSSLCA=off)");
+ }
+ if (isOn(req, "SubordinateEmailCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateEmailCA=on)");
+ } else if (isOff(req, "SubordinateEmailCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateEmailCA=off)");
+ }
+ }
+
+ public String buildFilter(HttpServletRequest req)
+ {
+ String queryCertFilter = req.getParameter("queryCertFilter");
+
+ StringBuffer filter = new StringBuffer();
+ buildSerialNumberRangeFilter(req, filter);
+ buildSubjectFilter(req, filter);
+ buildRevokedByFilter(req, filter);
+ buildRevokedOnFilter(req, filter);
+ buildRevocationReasonFilter(req, filter);
+ buildIssuedByFilter(req, filter);
+ buildIssuedOnFilter(req, filter);
+ buildValidNotBeforeFilter(req, filter);
+ buildValidNotAfterFilter(req, filter);
+ buildValidityLengthFilter(req, filter);
+ buildCertTypeFilter(req, filter);
+ buildCertStatusFilter(req, filter);
+ buildProfileFilter(req, filter);
+ buildBasicConstraintsFilter(req, filter);
+
+ if (mUseClientFilter) {
+ CMS.debug("useClientFilter=true");
+ } else {
+ CMS.debug("useClientFilter=false");
+ CMS.debug("client queryCertFilter = " + queryCertFilter);
+ queryCertFilter = "(&" + filter.toString() + ")";
+ }
+ CMS.debug("queryCertFilter = " + queryCertFilter);
+ return queryCertFilter;
+ }
+
+ /**
+ * Serves HTTP request. This format of this request is as follows:
+ * queryCert?
+ * [maxCount=<number>]
+ * [queryFilter=<filter>]
+ * [revokeAll=<filter>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ EBaseException error = null;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ revokeAll = req.getParameter("revokeAll");
+
+ String maxResultsStr = req.getParameter("maxResults");
+
+ if (maxResultsStr != null && maxResultsStr.length() > 0)
+ maxResults = Integer.parseInt(maxResultsStr);
+ String timeLimitStr = req.getParameter("timeLimit");
+
+ if (timeLimitStr != null && timeLimitStr.length() > 0)
+ timeLimit = Integer.parseInt(timeLimitStr);
+
+ String queryCertFilter = buildFilter(req);
+ process(argSet, header, queryCertFilter,
+ revokeAll, maxResults, timeLimit, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ String filter, String revokeAll,
+ int maxResults, int timeLimit,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ long startTime = CMS.getCurrentDate().getTime();
+
+ if (filter.indexOf(CURRENT_TIME, 0) > -1) {
+ filter = insertCurrentTime(filter);
+ }
+
+ // xxx the filter includes serial number range???
+ if (maxResults == -1 || maxResults > mMaxReturns) {
+ CMS.debug("Resetting maximum of returned results from " + maxResults + " to " + mMaxReturns);
+ maxResults = mMaxReturns;
+ }
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... " + "filter=" + filter + " maxreturns=" + maxResults + " timelimit=" + timeLimit);
+ Enumeration e = mCertDB.searchCertificates(filter, maxResults, timeLimit);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec != null) {
+ count++;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ header.addStringValue("time", Long.toString(endTime - startTime));
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("queryFilter", filter);
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ header.addIntegerValue("totalRecordCount", count);
+ header.addIntegerValue("maxSize", maxResults);
+ } catch (EBaseException e) {
+ CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString());
+ throw e;
+ }
+ return;
+ }
+
+ private String insertCurrentTime(String filter) {
+ Date now = null;
+ StringBuffer newFilter = new StringBuffer();
+ int k = 0;
+ int i = filter.indexOf(CURRENT_TIME, k);
+
+ while (i > -1) {
+ if (now == null) now = new Date();
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ k = i + CURRENT_TIME.length();
+ i = filter.indexOf(CURRENT_TIME, k);
+ }
+ if (k > 0) {
+ newFilter.append(filter.substring(k, filter.length()));
+ }
+ return newFilter.toString();
+ }
+
+ /**
+ * Fills cert record into argument block.
+ */
+ private void fillRecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null) {
+ fillX509RecordIntoArg(rec, rarg);
+ }
+ }
+
+ private void fillX509RecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl cert = rec.getCertificate();
+
+ rarg.addIntegerValue("version", cert.getVersion());
+ rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal", cert.getSerialNumber().toString());
+
+ String subject = (String) cert.getSubjectDN().toString();
+
+ if (subject.equals("")) {
+ rarg.addStringValue("subject", " ");
+ } else {
+ rarg.addStringValue("subject", subject);
+
+ }
+
+ rarg.addStringValue("type", "X.509");
+
+ try {
+ PublicKey pKey = cert.getPublicKey();
+ X509Key key = null;
+
+ if (pKey instanceof CertificateX509Key) {
+ CertificateX509Key certKey = (CertificateX509Key) pKey;
+
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ }
+ if (pKey instanceof X509Key) {
+ key = (X509Key) pKey;
+ }
+ rarg.addStringValue("subjectPublicKeyAlgorithm", key.getAlgorithmId().getOID().toString());
+ if (key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) {
+ RSAPublicKey rsaKey = new RSAPublicKey(key.getEncoded());
+
+ rarg.addIntegerValue("subjectPublicKeyLength", rsaKey.getKeySize());
+ }
+ } catch (Exception e) {
+ rarg.addStringValue("subjectPublicKeyAlgorithm", null);
+ rarg.addIntegerValue("subjectPublicKeyLength", 0);
+ }
+
+ rarg.addLongValue("validNotBefore", cert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter", cert.getNotAfter().getTime() / 1000);
+ rarg.addStringValue("signatureAlgorithm", cert.getSigAlgOID());
+ String issuedBy = rec.getIssuedBy();
+
+ if (issuedBy == null) issuedBy = "";
+ rarg.addStringValue("issuedBy", issuedBy); // cert.getIssuerDN().toString()
+ rarg.addLongValue("issuedOn", rec.getCreateTime().getTime() / 1000);
+
+ rarg.addStringValue("revokedBy",
+ ((rec.getRevokedBy() == null) ? "" : rec.getRevokedBy()));
+ if (rec.getRevokedOn() == null) {
+ rarg.addStringValue("revokedOn", null);
+ } else {
+ rarg.addLongValue("revokedOn", rec.getRevokedOn().getTime() / 1000);
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enum1 = crlExts.getElements();
+ int reason = 0;
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = (Extension) enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ rarg.addIntegerValue("revocationReason", reason);
+ }
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java
new file mode 100644
index 000000000..52b66874f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -0,0 +1,512 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Force the CRL to be updated now.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateCRL extends CMSServlet {
+
+ private final static String INFO = "UpdateCRL";
+ private final static String TPL_FILE = "updateCRL.template";
+
+ private static Vector mTesting = new Vector();
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs UpdateCRL servlet.
+ */
+ public UpdateCRL() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet. This servlet uses updateCRL.template
+ * to render the result
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output orw own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param signatureAlgorithm the algorithm to use to sign the CRL
+ * <li>http.param waitForUpdate true/false - should the servlet wait until
+ * the CRL update is complete?
+ * <li>http.param clearCRLCache true/false - should the CRL cache cleared
+ * before the CRL is generated?
+ * <li>http.param crlIssuingPoint the CRL Issuing Point to Update
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("crl", true /* main action */);
+ }
+
+ long startTime = CMS.getCurrentDate().getTime();
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "update");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ return;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ String signatureAlgorithm =
+ req.getParameter("signatureAlgorithm");
+
+ process(argSet, header, req, resp,
+ signatureAlgorithm, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE",
+ e.toString()));
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ }
+
+ private CRLExtensions crlEntryExtensions (String reason, String invalidity) {
+ CRLExtensions entryExts = new CRLExtensions();
+
+ CRLReasonExtension crlReasonExtn = null;
+ if (reason != null && reason.length() > 0) {
+ try {
+ RevocationReason revReason = RevocationReason.fromInt(Integer.parseInt(reason));
+ if (revReason == null) revReason = RevocationReason.UNSPECIFIED;
+ crlReasonExtn = new CRLReasonExtension(revReason);
+ } catch (Exception e) {
+ CMS.debug("Invalid revocation reason: "+reason);
+ }
+ }
+
+ InvalidityDateExtension invalidityDateExtn = null;
+ if (invalidity != null && invalidity.length() > 0) {
+ long now = System.currentTimeMillis();
+ Date invalidityDate = null;
+ try {
+ long backInTime = Long.parseLong(invalidity);
+ invalidityDate = new Date(now-(backInTime*60000));
+ } catch (Exception e) {
+ CMS.debug("Invalid invalidity time offset: "+invalidity);
+ }
+ if (invalidityDate != null) {
+ try {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ } catch (Exception e) {
+ CMS.debug("Error creating invalidity extension: "+e);
+ }
+ }
+ }
+
+ if (crlReasonExtn != null) {
+ try {
+ entryExts.set(crlReasonExtn.getName(), crlReasonExtn);
+ } catch (Exception e) {
+ CMS.debug("Error adding revocation reason extension to entry extensions: "+e);
+ }
+ }
+
+ if (invalidityDateExtn != null) {
+ try {
+ entryExts.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ } catch (Exception e) {
+ CMS.debug("Error adding invalidity date extension to entry extensions: "+e);
+ }
+ }
+
+ return entryExts;
+ }
+
+ private void addInfo(CMSTemplateParams argSet, ICRLIssuingPoint crlIssuingPoint, long cacheUpdate) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addLongValue("cacheUpdate", cacheUpdate);
+
+ String crlNumbers = crlIssuingPoint.getCRLNumber().toString();
+ BigInteger deltaNumber = crlIssuingPoint.getDeltaCRLNumber();
+ String crlSizes = "" + crlIssuingPoint.getCRLSize();
+ if (deltaNumber != null && deltaNumber.compareTo(BigInteger.ZERO) > 0) {
+ if (crlNumbers != null)
+ crlNumbers += ",";
+ if (crlNumbers != null)
+ crlNumbers += deltaNumber.toString();
+ if (crlSizes != null)
+ crlSizes += "," + crlIssuingPoint.getDeltaCRLSize();
+ }
+ rarg.addStringValue("crlNumbers", crlNumbers);
+ rarg.addStringValue("crlSizes", crlSizes);
+
+ StringBuffer crlSplits = new StringBuffer();
+ Vector splits = crlIssuingPoint.getSplitTimes();
+ for (int i = 0; i < splits.size(); i++) {
+ crlSplits.append(splits.elementAt(i));
+ if (i + 1 < splits.size())
+ crlSplits.append(",");
+ }
+ rarg.addStringValue("crlSplits", crlSplits.toString());
+
+ argSet.addRepeatRecord(rarg);
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String signatureAlgorithm,
+ Locale locale)
+ throws EBaseException {
+ long startTime = CMS.getCurrentDate().getTime();
+ String waitForUpdate =
+ req.getParameter("waitForUpdate");
+ String clearCache =
+ req.getParameter("clearCRLCache");
+ String crlIssuingPointId =
+ req.getParameter("crlIssuingPoint");
+ String test = req.getParameter("test");
+ String add = req.getParameter("add");
+ String from = req.getParameter("from");
+ String by = req.getParameter("by");
+ String reason = req.getParameter("reason");
+ String invalidity = req.getParameter("invalidity");
+ String results = req.getParameter("results");
+
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ if (crlIssuingPointId == null) {
+ crlIssuingPointId = mCA.PROP_MASTER_CRL;
+ }
+
+ ICRLIssuingPoint crlIssuingPoint =
+ mCA.getCRLIssuingPoint(crlIssuingPointId);
+ header.addStringValue("crlIssuingPoint", crlIssuingPointId);
+ IPublisherProcessor lpm = mCA.getPublisherProcessor();
+
+ if (crlIssuingPoint != null) {
+ if (clearCache != null && clearCache.equals("true") &&
+ crlIssuingPoint.isCRLGenerationEnabled() &&
+ crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+ crlIssuingPoint.isCRLIssuingPointInitialized()
+ == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ crlIssuingPoint.clearCRLCache();
+ }
+ if (waitForUpdate != null && waitForUpdate.equals("true") &&
+ crlIssuingPoint.isCRLGenerationEnabled() &&
+ crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+ crlIssuingPoint.isCRLIssuingPointInitialized()
+ == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ if (test != null && test.equals("true") &&
+ crlIssuingPoint.isCRLCacheTestingEnabled() &&
+ (!mTesting.contains(crlIssuingPointId))) {
+ CMS.debug("CRL test started.");
+ mTesting.add(crlIssuingPointId);
+ BigInteger addLen = null;
+ BigInteger startFrom = null;
+ if (add != null && add.length() > 0 &&
+ from != null && from.length() > 0) {
+ try {
+ addLen = new BigInteger(add);
+ startFrom = new BigInteger(from);
+ } catch (Exception e) {
+ }
+ }
+ if (addLen != null && startFrom != null) {
+ Date revocationDate = CMS.getCurrentDate();
+ String err = null;
+
+ CRLExtensions entryExts = crlEntryExtensions (reason, invalidity);
+
+ BigInteger serialNumber = startFrom;
+ BigInteger counter = addLen;
+ BigInteger stepBy = null;
+ if (by != null && by.length() > 0) {
+ try {
+ stepBy = new BigInteger(by);
+ } catch (Exception e) {
+ }
+ }
+
+ long t1 = System.currentTimeMillis();
+ long t2 = 0;
+
+ while (counter.compareTo(BigInteger.ZERO) > 0) {
+ RevokedCertImpl revokedCert =
+ new RevokedCertImpl(serialNumber, revocationDate, entryExts);
+ crlIssuingPoint.addRevokedCert(serialNumber, revokedCert);
+ serialNumber = serialNumber.add(BigInteger.ONE);
+ counter = counter.subtract(BigInteger.ONE);
+
+ if ((counter.compareTo(BigInteger.ZERO) == 0) ||
+ (stepBy != null && ((counter.mod(stepBy)).compareTo(BigInteger.ZERO) == 0))) {
+ t2 = System.currentTimeMillis();
+ long t0 = t2 - t1;
+ t1 = t2;
+ try {
+ if (signatureAlgorithm != null) {
+ crlIssuingPoint.updateCRLNow(signatureAlgorithm);
+ } else {
+ crlIssuingPoint.updateCRLNow();
+ }
+ } catch (Throwable e) {
+ counter = BigInteger.ZERO;
+ err = e.toString();
+ }
+ if (results != null && results.equals("1")) {
+ addInfo(argSet, crlIssuingPoint, t0);
+ }
+ }
+ }
+ if (err != null) {
+ header.addStringValue("crlUpdate", "Failure");
+ header.addStringValue("error", err);
+ } else {
+ header.addStringValue("crlUpdate", "Success");
+ }
+ } else {
+ CMS.debug("CRL test error: missing parameters.");
+ header.addStringValue("crlUpdate", "missingParameters");
+ }
+
+ mTesting.remove(crlIssuingPointId);
+ CMS.debug("CRL test finished.");
+ } else if (test != null && test.equals("true") &&
+ crlIssuingPoint.isCRLCacheTestingEnabled() &&
+ mTesting.contains(crlIssuingPointId)) {
+ header.addStringValue("crlUpdate", "testingInProgress");
+ } else if (test != null && test.equals("true") &&
+ (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
+ header.addStringValue("crlUpdate", "testingNotEnabled");
+ } else {
+ try {
+ EBaseException publishError = null;
+
+ try {
+ long now1 = System.currentTimeMillis();
+
+ if (signatureAlgorithm != null) {
+ crlIssuingPoint.updateCRLNow(signatureAlgorithm);
+ } else {
+ crlIssuingPoint.updateCRLNow();
+ }
+
+ long now2 = System.currentTimeMillis();
+
+ header.addStringValue("time", "" + (now2 - now1));
+ } catch (EErrorPublishCRL e) {
+ publishError = e;
+ }
+
+ if (lpm != null && lpm.enabled()) {
+ Enumeration rules = lpm.getRules(IPublisherProcessor.PROP_LOCAL_CRL);
+ if (rules != null && rules.hasMoreElements()) {
+ if (publishError != null) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("error", publishError.toString(locale));
+ } else {
+ header.addStringValue("crlPublished", "Success");
+ }
+ }
+ }
+
+ // for audit log
+ SessionContext sContext = SessionContext.getContext();
+ String agentId = (String) sContext.get(SessionContext.USER_ID);
+ IAuthToken authToken = (IAuthToken) sContext.get(SessionContext.AUTH_TOKEN);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+ long endTime = CMS.getCurrentDate().getTime();
+
+ if (crlIssuingPoint.getNextUpdate() != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.CRLUPDATEFORMAT,
+ new Object[] {
+ AuditFormat.FROMAGENT + " agentID: " + agentId,
+ authMgr,
+ "completed",
+ crlIssuingPoint.getId(),
+ crlIssuingPoint.getCRLNumber(),
+ crlIssuingPoint.getLastUpdate(),
+ crlIssuingPoint.getNextUpdate(),
+ Long.toString(crlIssuingPoint.getCRLSize()) + " time: " + (endTime - startTime)}
+ );
+ }else {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.CRLUPDATEFORMAT,
+ new Object[] {
+ AuditFormat.FROMAGENT + " agentID: " + agentId,
+ authMgr,
+ "completed",
+ crlIssuingPoint.getId(),
+ crlIssuingPoint.getCRLNumber(),
+ crlIssuingPoint.getLastUpdate(),
+ "not set",
+ Long.toString(crlIssuingPoint.getCRLSize()) + " time: " + (endTime - startTime)}
+ );
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_UPDATE_CRL", e.toString()));
+ if ((lpm != null) && lpm.enabled() && (e instanceof ELdapException)) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("error", e.toString(locale));
+ } else {
+ throw e;
+ }
+ }
+ }
+ } else {
+ if (crlIssuingPoint.isCRLIssuingPointInitialized()
+ != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ header.addStringValue("crlUpdate", "notInitialized");
+ } else if (crlIssuingPoint.isCRLUpdateInProgress()
+ != ICRLIssuingPoint.CRL_UPDATE_DONE ||
+ crlIssuingPoint.isManualUpdateSet()) {
+ header.addStringValue("crlUpdate", "inProgress");
+ } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
+ header.addStringValue("crlUpdate", "Disabled");
+ } else {
+ crlIssuingPoint.setManualUpdate(signatureAlgorithm);
+ header.addStringValue("crlUpdate", "Scheduled");
+ }
+ }
+ }
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
new file mode 100644
index 000000000..5f5afad1d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
@@ -0,0 +1,734 @@
+// --- 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.servlet.cert;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Update the configured LDAP server with specified objects
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateDir extends CMSServlet {
+
+ private final static String INFO = "UpdateDir";
+ private final static String TPL_FILE = "updateDir.template";
+ private final static int UPDATE_ALL = 0;
+ private final static int UPDATE_CRL = 1;
+ private final static int UPDATE_CA = 2;
+ private final static int UPDATE_VALID = 3;
+ private final static int VALID_FROM = 4;
+ private final static int VALID_TO = 5;
+ private final static int UPDATE_EXPIRED = 6;
+ private final static int EXPIRED_FROM = 7;
+ private final static int EXPIRED_TO = 8;
+ private final static int UPDATE_REVOKED = 9;
+ private final static int REVOKED_FROM = 10;
+ private final static int REVOKED_TO = 11;
+ private final static int CHECK_FLAG = 12;
+ private final static String[] updateName =
+ {"updateAll", "updateCRL", "updateCA",
+ "updateValid", "validFrom", "validTo",
+ "updateExpired", "expiredFrom", "expiredTo",
+ "updateRevoked", "revokedFrom", "revokedTo",
+ "checkFlag"};
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private ICRLRepository mCRLRepository = null;
+ private boolean mClonedCA = false;
+
+ /**
+ * Constructs UpdateDir servlet.
+ */
+ public UpdateDir() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the template
+ * 'updateDir.template' to render the response
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ if( mAuthority != null ) {
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ mPublisherProcessor = mCA.getPublisherProcessor();
+ mCRLRepository = mCA.getCRLRepository();
+ }
+
+ // override success to do output orw own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null) {
+ mFormPath = mOutputTemplatePath;
+ }
+ }
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "update");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ String crlIssuingPointId = req.getParameter("crlIssuingPoint");
+
+ if (mPublisherProcessor == null ||
+ !mPublisherProcessor.enabled())
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_PUB_MODULE"));
+
+ String[] updateValue = new String[updateName.length];
+
+ for (int i = 0; i < updateName.length; i++) {
+ updateValue[i] = req.getParameter(updateName[i]);
+ }
+
+ String masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ String masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+ mClonedCA = true;
+ }
+
+ process(argSet, header, req, resp, crlIssuingPointId, updateValue, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void updateCRLIssuingPoint(
+ IArgBlock header,
+ String crlIssuingPointId,
+ ICRLIssuingPoint crlIssuingPoint,
+ Locale locale) {
+ SessionContext sc = SessionContext.getContext();
+
+ sc.put(ICRLIssuingPoint.SC_ISSUING_POINT_ID, crlIssuingPointId);
+ sc.put(ICRLIssuingPoint.SC_IS_DELTA_CRL, "false");
+ ICRLIssuingPointRecord crlRecord = null;
+
+ try {
+ if (mCRLRepository != null) {
+ crlRecord = (ICRLIssuingPointRecord)mCRLRepository.readCRLIssuingPointRecord(crlIssuingPointId);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_CRL_RECORD", e.toString()));
+ }
+
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ } else {
+ String publishDN = (crlIssuingPoint != null)? crlIssuingPoint.getPublishDN(): null;
+ byte[] crlbytes = crlRecord.getCRL();
+
+ if (crlbytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", ""));
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ } else {
+ X509CRLImpl crl = null;
+
+ try {
+ crl = new X509CRLImpl(crlbytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_CRL", e.toString()));
+ }
+
+ if (crl == null) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale,"CMS_GW_DECODE_CRL_FAILED")).toString());
+ } else {
+ try {
+ if (publishDN != null) {
+ mPublisherProcessor.publishCRL(publishDN, crl);
+ } else {
+ mPublisherProcessor.publishCRL(crl,crlIssuingPointId);
+ }
+ header.addStringValue("crlPublished", "Success");
+ } catch (ELdapException e) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError", e.toString(locale));
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR_PUBLISH_CRL", e.toString()));
+ }
+ }
+ }
+
+ sc.put(ICRLIssuingPoint.SC_IS_DELTA_CRL, "true");
+ // handle delta CRL if any
+ byte[] deltaCrlBytes = crlRecord.getDeltaCRL();
+
+ if (deltaCrlBytes != null) {
+ X509CRLImpl deltaCrl = null;
+
+ try {
+ deltaCrl = new X509CRLImpl(deltaCrlBytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_DELTA_CRL", e.toString()));
+ }
+
+ boolean goodDelta = false;
+ if (mClonedCA) {
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ Long deltaCRLSize = crlRecord.getDeltaCRLSize();
+ if (deltaCRLSize != null && deltaCRLSize.longValue() > -1 &&
+ crlNumber != null && deltaNumber != null &&
+ deltaNumber.compareTo(crlNumber) >= 0) {
+ goodDelta = true;
+ }
+ }
+
+ if (deltaCrl != null && ((mClonedCA && goodDelta) ||
+ (crlIssuingPoint != null &&
+ crlIssuingPoint.isThisCurrentDeltaCRL(deltaCrl)))) {
+ try {
+ if (publishDN != null) {
+ mPublisherProcessor.publishCRL(publishDN, deltaCrl);
+ } else {
+ mPublisherProcessor.publishCRL(deltaCrl,crlIssuingPointId);
+ }
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_PUBLISH_DELTA_CRL", e.toString()));
+ }
+ }
+ }
+ } // if
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String crlIssuingPointId,
+ String[] updateValue,
+ Locale locale)
+ throws EBaseException {
+ // all or crl
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_CRL] != null &&
+ updateValue[UPDATE_CRL].equalsIgnoreCase("yes"))) {
+ // check if received issuing point ID is known to the server
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ if (crlIssuingPointId == null) {
+ // publish all issuing points
+ if (mClonedCA && mCRLRepository != null) {
+ Vector ipNames = mCRLRepository.getIssuingPointsNames();
+ if (ipNames != null && ipNames.size() > 0) {
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+
+ updateCRLIssuingPoint(header, ipName, null, locale);
+ }
+ }
+ } else {
+ Enumeration oips = mCA.getCRLIssuingPoints();
+
+ while (oips.hasMoreElements()) {
+ ICRLIssuingPoint oip = (ICRLIssuingPoint) oips.nextElement();
+
+ updateCRLIssuingPoint(header, oip.getId(), oip, locale);
+ }
+ }
+ } else {
+ ICRLIssuingPoint crlIssuingPoint =
+ mCA.getCRLIssuingPoint(crlIssuingPointId);
+ ICRLIssuingPointRecord crlRecord = null;
+
+ updateCRLIssuingPoint(header, crlIssuingPointId,
+ crlIssuingPoint, locale);
+ }
+ }
+
+ ICertificateRepository certificateRepository = (ICertificateRepository) mCA.getCertificateRepository();
+
+ // all or ca
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_CA] != null &&
+ updateValue[UPDATE_CA].equalsIgnoreCase("yes"))) {
+ X509CertImpl caCert = mCA.getSigningUnit().getCertImpl();
+
+ try {
+ mPublisherProcessor.publishCACert(caCert);
+ header.addStringValue("caCertPublished", "Success");
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR_PUBLISH_CACERT_1",
+ caCert.getSerialNumber().toString(16), e.toString()));
+ header.addStringValue("caCertPublished", "Failure");
+ header.addStringValue("caCertError", e.toString(locale));
+ }
+ }
+
+ // all or valid
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_VALID] != null &&
+ updateValue[UPDATE_VALID].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[VALID_FROM].startsWith("0x")) {
+ updateValue[VALID_FROM] = hexToDecimal(updateValue[VALID_FROM]);
+ }
+ if (updateValue[VALID_TO].startsWith("0x")) {
+ updateValue[VALID_TO] = hexToDecimal(updateValue[VALID_TO]);
+ }
+ Enumeration validCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ validCerts =
+ certificateRepository.getValidNotPublishedCertificates(
+ updateValue[VALID_FROM],
+ updateValue[VALID_TO]);
+ } else {
+ validCerts =
+ certificateRepository.getValidCertificates(
+ updateValue[VALID_FROM],
+ updateValue[VALID_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ String validCertsError = "";
+
+ if (validCerts != null) {
+ while (validCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) validCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ SessionContext sc = SessionContext.getContext();
+
+ if (r == null) {
+ if (CMS.isEncryptionCert(cert))
+ sc.put((Object) "isEncryptionCert", (Object) "true");
+ else
+ sc.put((Object) "isEncryptionCert", (Object) "false");
+ mPublisherProcessor.publishCert(cert, null);
+ } else {
+ if (CMS.isEncryptionCert(cert))
+ r.setExtData("isEncryptionCert", "true");
+ else
+ r.setExtData("isEncryptionCert", "false");
+ mPublisherProcessor.publishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_PUBLISH_CERT", certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ validCertsError +=
+ "Failed to publish certificate: 0x" +
+ certRecord.getSerialNumber().toString(16) +
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;";
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("validCertsPublished",
+ "Success");
+ if (i == 1)
+ header.addStringValue("validCertsError", i +
+ " valid certificate is published in the directory.");
+ else
+ header.addStringValue("validCertsError", i +
+ " valid certificates are published in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("validCertsPublished", "No");
+ } else {
+ header.addStringValue("validCertsPublished", "Failure");
+ header.addStringValue("validCertsError",
+ validCertsError);
+ }
+ }
+ } else {
+ header.addStringValue("validCertsPublished", "Failure");
+ header.addStringValue("validCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ // all or expired
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_EXPIRED] != null &&
+ updateValue[UPDATE_EXPIRED].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[EXPIRED_FROM].startsWith("0x")) {
+ updateValue[EXPIRED_FROM] = hexToDecimal(updateValue[EXPIRED_FROM]);
+ }
+ if (updateValue[EXPIRED_TO].startsWith("0x")) {
+ updateValue[EXPIRED_TO] = hexToDecimal(updateValue[EXPIRED_TO]);
+ }
+ Enumeration expiredCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ expiredCerts =
+ certificateRepository.getExpiredPublishedCertificates(
+ updateValue[EXPIRED_FROM],
+ updateValue[EXPIRED_TO]);
+ } else {
+ expiredCerts =
+ certificateRepository.getExpiredCertificates(
+ updateValue[EXPIRED_FROM],
+ updateValue[EXPIRED_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ StringBuffer expiredCertsError = new StringBuffer();
+
+ if (expiredCerts != null) {
+ while (expiredCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) expiredCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ if (r == null) {
+ mPublisherProcessor.unpublishCert(cert, null);
+ } else {
+ mPublisherProcessor.unpublishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LDAP_ERROR_UNPUBLISH_CERT",
+ certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ expiredCertsError.append(
+ "Failed to unpublish certificate: 0x");
+ expiredCertsError.append(
+ certRecord.getSerialNumber().toString(16));
+ expiredCertsError.append(
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;");
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("expiredCertsUnpublished", "Success");
+ if (i == 1)
+ header.addStringValue("expiredCertsError", i +
+ " expired certificate is unpublished in the directory.");
+ else
+ header.addStringValue("expiredCertsError", i +
+ " expired certificates are unpublished in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("expiredCertsUnpublished", "No");
+ } else {
+ header.addStringValue("expiredCertsUnpublished", "Failure");
+ header.addStringValue("expiredCertsError",
+ expiredCertsError.toString());
+ }
+ }
+ } else {
+ header.addStringValue("expiredCertsUnpublished", "Failure");
+ header.addStringValue("expiredCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ // all or revoked
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_REVOKED] != null &&
+ updateValue[UPDATE_REVOKED].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[REVOKED_FROM].startsWith("0x")) {
+ updateValue[REVOKED_FROM] = hexToDecimal(updateValue[REVOKED_FROM]);
+ }
+ if (updateValue[REVOKED_TO].startsWith("0x")) {
+ updateValue[REVOKED_TO] = hexToDecimal(updateValue[REVOKED_TO]);
+ }
+ Enumeration revokedCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ revokedCerts =
+ certificateRepository.getRevokedPublishedCertificates(
+ updateValue[REVOKED_FROM],
+ updateValue[REVOKED_TO]);
+ } else {
+ revokedCerts =
+ certificateRepository.getRevokedCertificates(
+ updateValue[REVOKED_FROM],
+ updateValue[REVOKED_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ String revokedCertsError = "";
+
+ if (revokedCerts != null) {
+ while (revokedCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) revokedCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ if (r == null) {
+ mPublisherProcessor.unpublishCert(cert, null);
+ } else {
+ mPublisherProcessor.unpublishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LDAP_ERROR_UNPUBLISH_CERT",
+ certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ revokedCertsError +=
+ "Failed to unpublish certificate: 0x" +
+ certRecord.getSerialNumber().toString(16) +
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;";
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("revokedCertsUnpublished", "Success");
+ if (i == 1)
+ header.addStringValue("revokedCertsError", i +
+ " revoked certificate is unpublished in the directory.");
+ else
+ header.addStringValue("revokedCertsError", i +
+ " revoked certificates are unpublished in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("revokedCertsUnpublished", "No");
+ } else {
+ header.addStringValue("revokedCertsUnpublished", "Failure");
+ header.addStringValue("revokedCertsError",
+ revokedCertsError);
+ }
+ }
+ } else {
+ header.addStringValue("revokedCertsUnpublished", "Failure");
+ header.addStringValue("revokedCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ return;
+ }
+
+ private String hexToDecimal(String hex) {
+ String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(newHex, 16);
+
+ return bi.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
new file mode 100644
index 000000000..97dde1a31
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
@@ -0,0 +1,2126 @@
+// --- 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.servlet.cert.scep;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.MessageDigest;
+
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authentication.AuthCredentials;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.cms.servlet.profile.*;
+import org.mozilla.jss.pkcs7.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import com.netscape.cmsutil.scep.CRSPKIMessage;
+
+
+/**
+ * This servlet deals with PKCS#10-based certificate requests from
+ * CRS, now called SCEP, and defined at:
+ * http://search.ietf.org/internet-drafts/draft-nourse-scep-02.txt
+ *
+ * The router is hardcoded to look for the http://host:80/cgi-bin/pkiclient.exe
+ *
+ * The HTTP parameters are 'operation' and 'message'
+ * operation can be either 'GetCACert' or 'PKIOperation'
+ *
+ * @version $Revision$, $Date$
+ */
+public class CRSEnrollment extends HttpServlet
+{
+ protected IProfileSubsystem mProfileSubsystem = null;
+ protected String mProfileId = null;
+ protected ICertAuthority mAuthority;
+ protected IConfigStore mConfig = null;
+ protected IAuthSubsystem mAuthSubsystem;
+ protected String mAppendDN=null;
+ protected String mEntryObjectclass=null;
+ protected boolean mCreateEntry=false;
+ protected boolean mFlattenDN=false;
+
+ private String mAuthManagerName;
+ private String mSubstoreName;
+ private boolean mEnabled = false;
+ private boolean mUseCA = true;
+ private String mNickname = null;
+ private String mTokenName = "";
+ private String mHashAlgorithm = "SHA1";
+ private String mHashAlgorithmList = null;
+ private String[] mAllowedHashAlgorithm;
+ private String mConfiguredEncryptionAlgorithm = "DES3";
+ private String mEncryptionAlgorithm = "DES3";
+ private String mEncryptionAlgorithmList = null;
+ private String[] mAllowedEncryptionAlgorithm;
+ private Random mRandom = null;
+ private int mNonceSizeLimit = 0;
+ protected ILogger mLogger = CMS.getLogger();
+ private ICertificateAuthority ca;
+ /* for hashing challenge password */
+ protected MessageDigest mSHADigest = null;
+
+ private static final String PROP_SUBSTORENAME = "substorename";
+ private static final String PROP_AUTHORITY = "authority";
+ private static final String PROP_CRS = "crs";
+ private static final String PROP_CRSCA = "casubsystem";
+ private static final String PROP_CRSAUTHMGR = "authName";
+ private static final String PROP_APPENDDN = "appendDN";
+ private static final String PROP_CREATEENTRY= "createEntry";
+ private static final String PROP_FLATTENDN = "flattenDN";
+ private static final String PROP_ENTRYOC = "entryObjectclass";
+
+ // URL parameters
+ private static final String URL_OPERATION = "operation";
+ private static final String URL_MESSAGE = "message";
+
+ // possible values for 'operation'
+ private static final String OP_GETCACERT = "GetCACert";
+ private static final String OP_PKIOPERATION = "PKIOperation";
+
+ public static final String AUTH_PASSWORD = "pwd";
+
+ public static final String AUTH_CREDS = "AuthCreds";
+ public static final String AUTH_TOKEN = "AuthToken";
+ public static final String AUTH_FAILED = "AuthFailed";
+
+ public static final String SANE_DNSNAME = "DNSName";
+ public static final String SANE_IPADDRESS = "IPAddress";
+
+ public static final String CERTINFO = "CertInfo";
+ public static final String SUBJECTNAME = "SubjectName";
+
+
+ public static ObjectIdentifier OID_UNSTRUCTUREDNAME = null;
+ public static ObjectIdentifier OID_UNSTRUCTUREDADDRESS = null;
+ public static ObjectIdentifier OID_SERIALNUMBER = null;
+
+ public CRSEnrollment(){}
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ httpReqHash.put(name, req.getParameter(name));
+ }
+ return httpReqHash;
+ }
+
+ public void init(ServletConfig sc) {
+ // Find the CertificateAuthority we should use for CRS.
+ String crsCA = sc.getInitParameter(PROP_AUTHORITY);
+ if (crsCA == null)
+ crsCA = "ca";
+ mAuthority = (ICertAuthority) CMS.getSubsystem(crsCA);
+ ca = (ICertificateAuthority)mAuthority;
+
+ if (mAuthority == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CANT_FIND_AUTHORITY",crsCA));
+ }
+
+ try {
+ if (mAuthority instanceof ISubsystem) {
+ IConfigStore authorityConfig = ((ISubsystem)mAuthority).getConfigStore();
+ IConfigStore scepConfig = authorityConfig.getSubStore("scep");
+ mEnabled = scepConfig.getBoolean("enable", false);
+ mHashAlgorithm = scepConfig.getString("hashAlgorithm", "SHA1");
+ mConfiguredEncryptionAlgorithm = scepConfig.getString("encryptionAlgorithm", "DES3");
+ mNonceSizeLimit = scepConfig.getInteger("nonceSizeLimit", 0);
+ mHashAlgorithmList = scepConfig.getString("allowedHashAlgorithms", "SHA1,SHA256,SHA512");
+ mAllowedHashAlgorithm = mHashAlgorithmList.split(",");
+ mEncryptionAlgorithmList = scepConfig.getString("allowedEncryptionAlgorithms", "DES3");
+ mAllowedEncryptionAlgorithm = mEncryptionAlgorithmList.split(",");
+ mNickname = scepConfig.getString("nickname", ca.getNickname());
+ if (mNickname.equals(ca.getNickname())) {
+ mTokenName = ca.getSigningUnit().getTokenName();
+ } else {
+ mTokenName = scepConfig.getString("tokenname", "");
+ mUseCA = false;
+ }
+ }
+ } catch (EBaseException e) {
+ CMS.debug("CRSEnrollment: init: EBaseException: "+e);
+ }
+ mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm;
+ CMS.debug("CRSEnrollment: init: SCEP support is "+((mEnabled)?"enabled":"disabled")+".");
+ CMS.debug("CRSEnrollment: init: SCEP nickname: "+mNickname);
+ CMS.debug("CRSEnrollment: init: CA nickname: "+ca.getNickname());
+ CMS.debug("CRSEnrollment: init: Token name: "+mTokenName);
+ CMS.debug("CRSEnrollment: init: Is SCEP using CA keys: "+mUseCA);
+ CMS.debug("CRSEnrollment: init: mNonceSizeLimit: "+mNonceSizeLimit);
+ CMS.debug("CRSEnrollment: init: mHashAlgorithm: "+mHashAlgorithm);
+ CMS.debug("CRSEnrollment: init: mHashAlgorithmList: "+mHashAlgorithmList);
+ for (int i = 0; i < mAllowedHashAlgorithm.length; i++) {
+ mAllowedHashAlgorithm[i] = mAllowedHashAlgorithm[i].trim();
+ CMS.debug("CRSEnrollment: init: mAllowedHashAlgorithm["+i+"]="+mAllowedHashAlgorithm[i]);
+ }
+ CMS.debug("CRSEnrollment: init: mEncryptionAlgorithm: "+mEncryptionAlgorithm);
+ CMS.debug("CRSEnrollment: init: mEncryptionAlgorithmList: "+mEncryptionAlgorithmList);
+ for (int i = 0; i < mAllowedEncryptionAlgorithm.length; i++) {
+ mAllowedEncryptionAlgorithm[i] = mAllowedEncryptionAlgorithm[i].trim();
+ CMS.debug("CRSEnrollment: init: mAllowedEncryptionAlgorithm["+i+"]="+mAllowedEncryptionAlgorithm[i]);
+ }
+
+ try {
+ mProfileSubsystem = (IProfileSubsystem)CMS.getSubsystem("profile");
+ mProfileId = sc.getInitParameter("profileId");
+ CMS.debug("CRSEnrollment: init: mProfileId="+mProfileId);
+
+ mAuthSubsystem = (IAuthSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ mAuthManagerName = sc.getInitParameter(PROP_CRSAUTHMGR);
+ mAppendDN = sc.getInitParameter(PROP_APPENDDN);
+ String tmp = sc.getInitParameter(PROP_CREATEENTRY);
+ if (tmp != null && tmp.trim().equalsIgnoreCase("true"))
+ mCreateEntry = true;
+ else
+ mCreateEntry = false;
+ tmp = sc.getInitParameter(PROP_FLATTENDN);
+ if (tmp != null && tmp.trim().equalsIgnoreCase("true"))
+ mFlattenDN = true;
+ else
+ mFlattenDN = false;
+ mEntryObjectclass = sc.getInitParameter(PROP_ENTRYOC);
+ if (mEntryObjectclass == null)
+ mEntryObjectclass = "cep";
+ mSubstoreName = sc.getInitParameter(PROP_SUBSTORENAME);
+ if (mSubstoreName == null)
+ mSubstoreName = "default";
+ } catch (Exception e) {
+ }
+
+ OID_UNSTRUCTUREDNAME = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDNAME");
+ OID_UNSTRUCTUREDADDRESS = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDADDRESS");
+ OID_SERIALNUMBER = X500NameAttrMap.getDefault().getOid("SERIALNUMBER");
+
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ }
+ catch (NoSuchAlgorithmException e) {
+ }
+
+ mRandom = new Random();
+ }
+
+
+ /**
+ *
+ * Service a CRS Request. It all starts here. This is where the message from the
+ * router is processed
+ *
+ * @param httpReq The HttpServletRequest.
+ * @param httpResp The HttpServletResponse.
+ *
+ */
+ public void service(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException
+ {
+ boolean running_state = CMS.isInRunningState();
+ if (!running_state)
+ throw new ServletException(
+ "CMS server is not ready to serve.");
+
+ String operation = null;
+ String message = null;
+ mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm;
+
+
+ // Parse the URL from the HTTP Request. Split it up into
+ // a structure which enables us to read the form elements
+ IArgBlock input = CMS.createArgBlock(toHashtable(httpReq));
+
+ try {
+ // Read in two form parameters - the router sets these
+ operation = (String)input.get(URL_OPERATION);
+ CMS.debug("operation=" + operation);
+ message = (String)input.get(URL_MESSAGE);
+ CMS.debug("message=" + message);
+
+ if (!mEnabled) {
+ CMS.debug("CRSEnrollment: SCEP support is disabled.");
+ throw new ServletException("SCEP support is disabled.");
+ }
+ if (operation == null) {
+ // 'operation' is mandatory.
+ throw new ServletException("Bad request: operation missing from URL");
+ }
+
+ /**
+ * the router can make two kinds of requests
+ * 1) simple request for CA cert
+ * 2) encoded, signed, enveloped request for anything else (PKIOperation)
+ */
+
+ if (operation.equals(OP_GETCACERT)) {
+ handleGetCACert(httpReq, httpResp);
+ }
+ else if (operation.equals(OP_PKIOPERATION)) {
+ String decodeMode = (String)input.get("decode");
+ if (decodeMode == null || decodeMode.equals("false")) {
+ handlePKIOperation(httpReq, httpResp, message);
+ } else {
+ decodePKIMessage(httpReq, httpResp, message);
+ }
+ }
+ else {
+ CMS.debug("Invalid operation " + operation);
+ throw new ServletException("unknown operation requested: "+operation);
+ }
+
+ }
+ catch (ServletException e)
+ {
+ CMS.debug("ServletException " + e);
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (Exception e)
+ {
+ CMS.debug("Service exception " + e);
+ log(ILogger.LL_FAILURE,e.getMessage());
+ }
+
+ }
+
+ /**
+ * Log a message to the system log
+ */
+
+
+ private void log(int level, String msg) {
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ level, "CEP Enrollment: "+msg);
+ }
+
+ private boolean isAlgorithmAllowed (String[] allowedAlgorithm, String algorithm) {
+ boolean allowed = false;
+
+ if (algorithm != null && algorithm.length() > 0) {
+ for (int i = 0; i < allowedAlgorithm.length; i++) {
+ if (algorithm.equalsIgnoreCase(allowedAlgorithm[i])) {
+ allowed = true;
+ }
+ }
+ }
+
+ return allowed;
+ }
+
+ public IAuthToken authenticate(AuthCredentials credentials, IProfileAuthenticator authenticator,
+ HttpServletRequest request) throws EBaseException {
+
+ // build credential
+ Enumeration authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = (String) authNames.nextElement();
+
+ credentials.set(authName, request.getParameter(authName));
+ }
+ }
+
+ credentials.set("clientHost", request.getRemoteHost());
+ IAuthToken authToken = authenticator.authenticate(credentials);
+ if (authToken == null) {
+ return null;
+ }
+ SessionContext sc = SessionContext.getContext();
+ if (sc != null) {
+ sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName());
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+ if (userid != null) {
+ sc.put(SessionContext.USER_ID, userid);
+ }
+ }
+
+ return authToken;
+ }
+
+ /**
+ * Return the CA certificate back to the requestor.
+ * This needs to be changed so that if the CA has a certificate chain,
+ * the whole thing should get packaged as a PKIMessage (degnerate PKCS7 - no
+ * signerInfo)
+ */
+
+ public void handleGetCACert(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException {
+ java.security.cert.X509Certificate[] chain = null;
+
+ CertificateChain certChain = mAuthority.getCACertChain();
+
+ try {
+ if (certChain == null) {
+ throw new ServletException("Internal Error: cannot get CA Cert");
+ }
+
+ chain = certChain.getChain();
+
+ byte[] bytes = null;
+
+ int i = 0;
+ String message = (String)httpReq.getParameter(URL_MESSAGE);
+ CMS.debug("handleGetCACert message=" + message);
+ if (message != null) {
+ try {
+ int j = Integer.parseInt(message);
+ if (j < chain.length) {
+ i = j;
+ }
+ } catch (NumberFormatException e1) {
+ }
+ }
+ CMS.debug("handleGetCACert selected chain=" + i);
+
+ if (mUseCA) {
+ bytes = chain[i].getEncoded();
+ } else {
+ CryptoContext cx = new CryptoContext();
+ bytes = cx.getSigningCert().getEncoded();
+ }
+
+ httpResp.setContentType("application/x-x509-ca-cert");
+
+
+// The following code may be used one day to encode
+// the RA/CA cert chain for RA mode, but it will need some
+// work.
+
+ /******
+ SET certs = new SET();
+ for (int i=0; i<chain.length; i++) {
+ ANY cert = new ANY(chain[i].getEncoded());
+ certs.addElement(cert);
+ }
+
+ SignedData crsd = new SignedData(
+ new SET(), // empty set of digestAlgorithmID's
+ new ContentInfo(
+ new OBJECT_IDENTIFIER(new long[] {1,2,840,113549,1,7,1}),
+ null), //empty content
+ certs,
+ null, // no CRL's
+ new SET() // empty SignerInfos
+ );
+
+ ContentInfo wrap = new ContentInfo(ContentInfo.SIGNED_DATA, crsd);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ wrap.encode(baos);
+
+ bytes = baos.toByteArray();
+
+ httpResp.setContentType("application/x-x509-ca-ra-cert");
+ *****/
+
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.getOutputStream().flush();
+
+ CMS.debug("Output certificate chain:");
+ CMS.debug(bytes);
+ }
+ catch (Exception e) {
+ CMS.debug("handleGetCACert exception " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_SENDING_DER_ENCODE_CERT",e.getMessage()));
+ throw new ServletException("Failed sending DER encoded version of CA cert to client");
+ }
+
+ }
+
+ public String getPasswordFromP10(PKCS10 p10)
+ {
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ try {
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ return (String)attr.get(ChallengePassword.PASSWORD);
+ }
+ }
+ }
+ } catch(Exception e1) {
+ // do nothing
+ }
+ return null;
+ }
+
+ /**
+ * If the 'operation' is 'PKIOperation', the 'message' part of the URL is a
+ * PKIMessage structure. We decode it to see what type message it is.
+ */
+
+ /**
+ * Decodes the PKI message and return information to RA.
+ */
+ public void decodePKIMessage(HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ String msg)
+ throws ServletException {
+
+ CryptoContext cx=null;
+
+ CRSPKIMessage req=null;
+
+ byte[] decodedPKIMessage;
+ byte[] response=null;
+ String responseData = "";
+
+ decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg);
+
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage);
+
+ // We make two CRSPKIMessages. One of them, is the request, so we initialize
+ // it from the DER given to us from the router.
+ // The second is the response, and we'll fill this in as we go.
+
+ if (decodedPKIMessage.length < 50) {
+ throw new ServletException("CRS request is too small to be a real request ("+
+ decodedPKIMessage.length+" bytes)");
+ }
+ try {
+ req = new CRSPKIMessage(is);
+ String ea = req.getEncryptionAlgorithm();
+ if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) {
+ CMS.debug("CRSEnrollment: decodePKIMessage: Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ throw new ServletException("Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ }
+ String da = req.getDigestAlgorithmName();
+ if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) {
+ CMS.debug("CRSEnrollment: decodePKIMessage: Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ throw new ServletException("Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ }
+ if (ea != null) {
+ mEncryptionAlgorithm = ea;
+ }
+ }
+ catch (Exception e) {
+ CMS.debug(e);
+ throw new ServletException("Could not decode the request.");
+ }
+
+ // Create a new crypto context for doing all the crypto operations
+ cx = new CryptoContext();
+
+ // Verify Signature on message (throws exception if sig bad)
+ verifyRequest(req,cx);
+ unwrapPKCS10(req,cx);
+
+ IProfile profile = mProfileSubsystem.getProfile(mProfileId);
+ if (profile == null) {
+ CMS.debug("Profile '" + mProfileId + "' not found.");
+ throw new ServletException("Profile '" + mProfileId + "' not found.");
+ } else {
+ CMS.debug("Found profile '" + mProfileId + "'.");
+ }
+
+ IProfileAuthenticator authenticator = null;
+ try {
+ CMS.debug("Retrieving authenticator");
+ authenticator = profile.getAuthenticator();
+ if (authenticator == null) {
+ CMS.debug("Authenticator not found.");
+ throw new ServletException("Authenticator not found.");
+ } else {
+ CMS.debug("Got authenticator=" + authenticator.getClass().getName());
+ }
+ } catch (EProfileException e) {
+ throw new ServletException("Authenticator not found.");
+ }
+ AuthCredentials credentials = new AuthCredentials();
+ IAuthToken authToken = null;
+ // for ssl authentication; pass in servlet for retrieving
+ // ssl client certificates
+ SessionContext context = SessionContext.getContext();
+
+ // insert profile context so that input parameter can be retrieved
+ context.put("sslClientCertProvider", new SSLClientCertProvider(httpReq));
+
+ try {
+ authToken = authenticate(credentials, authenticator, httpReq);
+ } catch (Exception e) {
+ CMS.debug("Authentication failure: "+ e.getMessage());
+ throw new ServletException("Authentication failure: "+ e.getMessage());
+ }
+ if (authToken == null) {
+ CMS.debug("Authentication failure.");
+ throw new ServletException("Authentication failure.");
+ }
+
+ // Deal with Transaction ID
+ String transactionID = req.getTransactionID();
+ responseData = responseData +
+ "<TransactionID>" + transactionID + "</TransactionID>";
+
+ // End-User or RA's IP address
+ responseData = responseData +
+ "<RemoteAddr>" + httpReq.getRemoteAddr() + "</RemoteAddr>";
+
+ responseData = responseData +
+ "<RemoteHost>" + httpReq.getRemoteHost() + "</RemoteHost>";
+
+ // Deal with Nonces
+ byte[] sn = req.getSenderNonce();
+
+ // Deal with message type
+ String mt = req.getMessageType();
+ responseData = responseData +
+ "<MessageType>" + mt + "</MessageType>";
+
+ PKCS10 p10 = (PKCS10)req.getP10();
+ X500Name p10subject = p10.getSubjectName();
+ responseData = responseData +
+ "<SubjectName>" + p10subject.toString() + "</SubjectName>";
+
+ String pkcs10Attr = "";
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ pkcs10Attr = pkcs10Attr +
+ "<ChallengePassword><Password>" + (String)attr.get(ChallengePassword.PASSWORD) + "</Password></ChallengePassword>";
+ }
+
+ }
+ String extensionsStr = "";
+ if (attr.getName().equals(ExtensionsRequested.NAME)) {
+
+ Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = (Extension) exts.nextElement();
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) {
+ DerOutputStream dos = new DerOutputStream();
+ SubjectAlternativeNameExtension sane = new SubjectAlternativeNameExtension(
+ Boolean.valueOf(false), // noncritical
+ ext.getExtensionValue());
+
+
+ Vector v =
+ (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME);
+
+ Enumeration gne = v.elements();
+
+ StringBuffer subjAltNameStr = new StringBuffer();
+ while (gne.hasMoreElements()) {
+ GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement();
+ if (gni instanceof GeneralName) {
+ GeneralName genName = (GeneralName) gni;
+
+ String gn = genName.toString();
+ int colon = gn.indexOf(':');
+ String gnType = gn.substring(0,colon).trim();
+ String gnValue = gn.substring(colon+1).trim();
+
+ subjAltNameStr.append("<");
+ subjAltNameStr.append(gnType);
+ subjAltNameStr.append(">");
+ subjAltNameStr.append(gnValue);
+ subjAltNameStr.append("</");
+ subjAltNameStr.append(gnType);
+ subjAltNameStr.append(">");
+ }
+ } // while
+ extensionsStr = "<SubjAltName>" +
+ subjAltNameStr.toString() + "</SubjAltName>";
+ } // if
+ } // while
+ pkcs10Attr = pkcs10Attr +
+ "<Extensions>" + extensionsStr + "</Extensions>";
+ } // if extensions
+ } // while
+ responseData = responseData +
+ "<PKCS10>" + pkcs10Attr + "</PKCS10>";
+
+ } catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ } catch (CRSInvalidSignatureException e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ } catch (Exception e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage());
+ }
+
+ // We have now processed the request, and need to make the response message
+
+ try {
+
+ responseData = "<XMLResponse>" + responseData + "</XMLResponse>";
+ // Get the response coding
+ response = responseData.getBytes();
+
+ // Encode the httpResp into B64
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(response.length);
+ httpResp.getOutputStream().write(response);
+ httpResp.getOutputStream().flush();
+
+ int i1 = responseData.indexOf("<Password>");
+ if (i1 > -1) {
+ i1 += 10; // 10 is a length of "<Password>"
+ int i2 = responseData.indexOf("</Password>", i1);
+ if (i2 > -1) {
+ responseData = responseData.substring(0, i1) + "********" +
+ responseData.substring(i2, responseData.length());
+ }
+ }
+
+ CMS.debug("Output (decoding) PKIOperation response:");
+ CMS.debug(responseData);
+ }
+ catch (Exception e) {
+ throw new ServletException("Failed to create response for CEP message"+e.getMessage());
+ }
+
+ }
+
+
+ /**
+ * finds a request with this transaction ID.
+ * If could not find any request - return null
+ * If could only find 'rejected' or 'cancelled' requests, return null
+ * If found 'pending' or 'completed' request - return that request
+ */
+
+
+ public void handlePKIOperation(HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ String msg)
+ throws ServletException {
+
+
+ CryptoContext cx=null;
+
+ CRSPKIMessage req=null;
+ CRSPKIMessage crsResp=null;
+
+ byte[] decodedPKIMessage;
+ byte[] response=null;
+ X509CertImpl cert = null;
+
+ decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg);
+
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage);
+
+ // We make two CRSPKIMessages. One of them, is the request, so we initialize
+ // it from the DER given to us from the router.
+ // The second is the response, and we'll fill this in as we go.
+
+ if (decodedPKIMessage.length < 50) {
+ throw new ServletException("CRS request is too small to be a real request ("+
+ decodedPKIMessage.length+" bytes)");
+ }
+ try {
+ req = new CRSPKIMessage(is);
+ String ea = req.getEncryptionAlgorithm();
+ if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) {
+ CMS.debug("CRSEnrollment: handlePKIOperation: Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ throw new ServletException("Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ }
+ String da = req.getDigestAlgorithmName();
+ if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) {
+ CMS.debug("CRSEnrollment: handlePKIOperation: Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ throw new ServletException("Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ }
+ if (ea != null) {
+ mEncryptionAlgorithm = ea;
+ }
+ crsResp = new CRSPKIMessage();
+ }
+ catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (Exception e) {
+ CMS.debug(e);
+ throw new ServletException("Could not decode the request.");
+ }
+ crsResp.setMessageType(crsResp.mType_CertRep);
+
+ // Create a new crypto context for doing all the crypto operations
+ cx = new CryptoContext();
+
+ // Verify Signature on message (throws exception if sig bad)
+ verifyRequest(req,cx);
+
+ // Deal with Transaction ID
+ String transactionID = req.getTransactionID();
+ if (transactionID == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing transactionID");
+ }
+ else {
+ crsResp.setTransactionID(transactionID);
+ }
+
+ // Deal with Nonces
+ byte[] sn = req.getSenderNonce();
+ if (sn == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing sendernonce");
+ }
+ else {
+ if (mNonceSizeLimit > 0 && sn.length > mNonceSizeLimit) {
+ byte[] snLimited = (mNonceSizeLimit > 0)? new byte[mNonceSizeLimit]: null;
+ System.arraycopy(sn, 0, snLimited, 0, mNonceSizeLimit);
+ crsResp.setRecipientNonce(snLimited);
+ } else {
+ crsResp.setRecipientNonce(sn);
+ }
+ byte[] serverNonce = new byte[16];
+ mRandom.nextBytes(serverNonce);
+ crsResp.setSenderNonce(serverNonce);
+ // crsResp.setSenderNonce(new byte[] {0});
+ }
+
+ // Deal with message type
+ String mt = req.getMessageType();
+ if (mt == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing messageType");
+ }
+
+ // now run appropriate code, depending on message type
+ if (mt.equals(req.mType_PKCSReq)) {
+ CMS.debug("Processing PKCSReq");
+ try {
+ // Check if there is an existing request. If this returns non-null,
+ // then the request is 'active' (either pending or completed) in
+ // which case, we compare the hash of the new request to the hash of the
+ // one in the queue - if they are the same, I return the state of the
+ // original request - as if it was 'getCertInitial' message.
+ // If the hashes are different, then the user attempted to enroll
+ // for a new request with the same txid, which is not allowed -
+ // so we return 'failure'.
+
+ IRequest cmsRequest= findRequestByTransactionID(req.getTransactionID(),true);
+
+ // If there was no request (with a cert) with this transaction ID,
+ // process it as a new request
+
+ cert = handlePKCSReq(httpReq, cmsRequest,req,crsResp,cx);
+
+ }
+ catch (CRSFailureException e) {
+ throw new ServletException("Couldn't handle CEP request (PKCSReq) - "+e.getMessage());
+ }
+ }
+ else if (mt.equals(req.mType_GetCertInitial)) {
+ CMS.debug("Processing GetCertInitial");
+ cert = handleGetCertInitial(req,crsResp);
+ } else {
+ CMS.debug("Invalid request type " + mt);
+ }
+ }
+ catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (CRSInvalidSignatureException e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ }
+ catch (Exception e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage());
+ }
+
+ // We have now processed the request, and need to make the response message
+
+ try {
+ // make the response
+ processCertRep(cx, cert,crsResp, req);
+
+ // Get the response coding
+ response = crsResp.getResponse();
+
+ // Encode the crsResp into B64
+ httpResp.setContentType("application/x-pki-message");
+ httpResp.setContentLength(response.length);
+ httpResp.getOutputStream().write(response);
+ httpResp.getOutputStream().flush();
+
+ CMS.debug("Output PKIOperation response:");
+ CMS.debug(CMS.BtoA(response));
+ }
+ catch (Exception e) {
+ throw new ServletException("Failed to create response for CEP message"+e.getMessage());
+ }
+
+ }
+
+
+ /**
+ * finds a request with this transaction ID.
+ * If could not find any request - return null
+ * If could only find 'rejected' or 'cancelled' requests, return null
+ * If found 'pending' or 'completed' request - return that request
+ */
+
+ public IRequest findRequestByTransactionID(String txid, boolean ignoreRejected)
+ throws EBaseException {
+
+ /* Check if certificate request has been completed */
+
+ IRequestQueue rq = ca.getRequestQueue();
+ IRequest foundRequest = null;
+
+ Enumeration rids = rq.findRequestsBySourceId(txid);
+ if (rids == null) { return null; }
+
+ int count=0;
+ while (rids.hasMoreElements()) {
+ RequestId rid = (RequestId) rids.nextElement();
+ if (rid == null) {
+ continue;
+ }
+
+ IRequest request = rq.findRequest(rid);
+ if (request == null) {
+ continue;
+ }
+ if ( !ignoreRejected ||
+ request.getRequestStatus().equals(RequestStatus.PENDING) ||
+ request.getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ if (foundRequest != null) {
+ }
+ foundRequest = request;
+ }
+ }
+ return foundRequest;
+ }
+
+ /**
+ * Called if the router is requesting us to send it its certificate
+ * Examine request queue for a request matching the transaction ID.
+ * Ignore any rejected or cancelled requests.
+ *
+ * If a request is found in the pending state, the response should be
+ * 'pending'
+ *
+ * If a request is found in the completed state, the response should be
+ * to return the certificate
+ *
+ * If no request is found, the response should be to return null
+ *
+ */
+
+ public X509CertImpl handleGetCertInitial(CRSPKIMessage req,CRSPKIMessage resp)
+ {
+ IRequest foundRequest=null;
+
+ // already done by handlePKIOperation
+ // resp.setRecipientNonce(req.getSenderNonce());
+ // resp.setSenderNonce(null);
+
+ try {
+ foundRequest = findRequestByTransactionID(req.getTransactionID(),false);
+ } catch (EBaseException e) {
+ }
+
+ if (foundRequest == null) {
+ resp.setFailInfo(resp.mFailInfo_badCertId);
+ resp.setPKIStatus(resp.mStatus_FAILURE);
+ return null;
+ }
+
+ return makeResponseFromRequest(req,resp,foundRequest);
+ }
+
+
+ public void verifyRequest(CRSPKIMessage req, CryptoContext cx)
+ throws CRSInvalidSignatureException {
+
+ // Get Signed Data
+
+ byte[] reqAAbytes = req.getAA();
+ byte[] reqAAsig = req.getAADigest();
+
+ }
+
+
+ /**
+ * Create an entry for this user in the publishing directory
+ *
+ */
+
+ private boolean createEntry(String dn)
+ {
+ boolean result = false;
+
+ IPublisherProcessor ldapPub = mAuthority.getPublisherProcessor();
+ if (ldapPub == null || !ldapPub.enabled()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_CREATE_ENTRY_FROM_CEP"));
+
+ return result;
+ }
+
+ ILdapConnFactory connFactory = ((IPublisherProcessor)ldapPub).getLdapConnModule().getLdapConnFactory();
+ if (connFactory == null) {
+ return result;
+ }
+
+ LDAPConnection connection=null;
+ try {
+ connection = connFactory.getConn();
+ String[] objectclasses = { "top", mEntryObjectclass };
+ LDAPAttribute ocAttrs = new LDAPAttribute("objectclass",objectclasses);
+
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+ attrSet.add(ocAttrs);
+
+ LDAPEntry newEntry = new LDAPEntry(dn, attrSet);
+ connection.add(newEntry);
+ result=true;
+ }
+ catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAIL_CREAT_ENTRY_EXISTS",dn));
+ }
+ finally {
+ try {
+ connFactory.returnConn(connection);
+ }
+ catch (Exception f) {}
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Here we decrypt the PKCS10 message from the client
+ *
+ */
+
+ public void unwrapPKCS10(CRSPKIMessage req, CryptoContext cx)
+ throws ServletException,
+ CryptoManager.NotInitializedException,
+ CryptoContext.CryptoContextException,
+ CRSFailureException {
+
+ byte[] decryptedP10bytes = null;
+ SymmetricKey sk;
+ SymmetricKey skinternal;
+ SymmetricKey.Type skt;
+ KeyWrapper kw;
+ Cipher cip;
+ EncryptionAlgorithm ea;
+ boolean errorInRequest = false;
+
+ // Unwrap the session key with the Cert server key
+ try {
+ kw = cx.getKeyWrapper();
+
+ kw.initUnwrap(cx.getPrivateKey(),null);
+
+ skt = SymmetricKey.Type.DES;
+ ea = EncryptionAlgorithm.DES_CBC;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ skt = SymmetricKey.Type.DES3;
+ ea = EncryptionAlgorithm.DES3_CBC;
+ }
+
+ sk = kw.unwrapSymmetric(req.getWrappedKey(),
+ skt,
+ SymmetricKey.Usage.DECRYPT,
+ 0); // keylength is ignored
+
+ skinternal = cx.getDESKeyGenerator().clone(sk);
+
+ cip = skinternal.getOwningToken().getCipherContext(ea);
+
+ cip.initDecrypt(skinternal,(new IVParameterSpec(req.getIV())));
+
+ decryptedP10bytes = cip.doFinal(req.getEncryptedPkcs10());
+ CMS.debug("decryptedP10bytes:");
+ CMS.debug(decryptedP10bytes);
+
+ req.setP10(new PKCS10(decryptedP10bytes));
+ } catch (Exception e) {
+ CMS.debug("failed to unwrap PKCS10 " + e);
+ throw new CRSFailureException("Could not unwrap PKCS10 blob: "+e.getMessage());
+ }
+
+ }
+
+
+
+private void getDetailFromRequest(CRSPKIMessage req, CRSPKIMessage crsResp)
+ throws CRSFailureException {
+
+ IRequest issueReq = null;
+ X509CertImpl issuedCert=null;
+ Vector extensionsRequested = null;
+ SubjectAlternativeNameExtension sane = null;
+ CertAttrSet requested_ext = null;
+
+ try {
+ PKCS10 p10 = (PKCS10)req.getP10();
+
+ if (p10 == null) {
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ throw new CRSFailureException("Failed to decode pkcs10 from CEP request");
+ }
+
+ AuthCredentials authCreds = new AuthCredentials();
+
+ String challengePassword = null;
+ // Here, we make a new CertInfo - it's a new start for a certificate
+
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ // get some stuff out of the request
+ X509Key key = p10.getSubjectPublicKeyInfo();
+ X500Name p10subject = p10.getSubjectName();
+
+ X500Name subject=null;
+
+ // The following code will copy all the attributes
+ // into the AuthCredentials so they can be used for
+ // authentication
+ //
+ // Optionally, you can re-map the subject name from:
+ // one RDN, with many AVA's to
+ // many RDN's with one AVA in each.
+
+ Enumeration rdne = p10subject.getRDNs();
+ Vector rdnv = new Vector();
+
+ Hashtable sanehash = new Hashtable();
+
+ X500NameAttrMap xnap = X500NameAttrMap.getDefault();
+ while (rdne.hasMoreElements()) {
+ RDN rdn = (RDN) rdne.nextElement();
+ int i=0;
+ AVA[] oldavas = rdn.getAssertion();
+ for (i=0; i<rdn.getAssertionLength(); i++) {
+ AVA[] newavas = new AVA[1];
+ newavas[0] = oldavas[i];
+
+ authCreds.set(xnap.getName(oldavas[i].getOid()),
+ oldavas[i].getValue().getAsString());
+
+ if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDNAME)) {
+
+ sanehash.put(SANE_DNSNAME,oldavas[i].getValue().getAsString());
+ }
+ if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDADDRESS)) {
+ sanehash.put(SANE_IPADDRESS,oldavas[i].getValue().getAsString());
+ }
+
+ RDN newrdn = new RDN(newavas);
+ if (mFlattenDN) {
+ rdnv.addElement(newrdn);
+ }
+ }
+ }
+
+ if (mFlattenDN) subject = new X500Name(rdnv);
+ else subject = p10subject;
+
+
+ // create default key usage extension
+ KeyUsageExtension kue = new KeyUsageExtension();
+ kue.set(KeyUsageExtension.DIGITAL_SIGNATURE, Boolean.valueOf(true));
+ kue.set(KeyUsageExtension.KEY_ENCIPHERMENT, Boolean.valueOf(true));
+
+
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ req.put(AUTH_PASSWORD,
+ (String)attr.get(ChallengePassword.PASSWORD));
+ req.put(ChallengePassword.NAME,
+ hashPassword(
+ (String)attr.get(ChallengePassword.PASSWORD)));
+ }
+ }
+
+ if (attr.getName().equals(ExtensionsRequested.NAME)) {
+
+ Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = (Extension) exts.nextElement();
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(KeyUsageExtension.IDENT)) ) {
+
+ kue = new KeyUsageExtension(
+ new Boolean(false), // noncritical
+ ext.getExtensionValue());
+ }
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) {
+ DerOutputStream dos = new DerOutputStream();
+ sane = new SubjectAlternativeNameExtension(
+ new Boolean(false), // noncritical
+ ext.getExtensionValue());
+
+
+ Vector v =
+ (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME);
+
+ Enumeration gne = v.elements();
+
+ while (gne.hasMoreElements()) {
+ GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement();
+ if (gni instanceof GeneralName) {
+ GeneralName genName = (GeneralName) gni;
+
+ String gn = genName.toString();
+ int colon = gn.indexOf(':');
+ String gnType = gn.substring(0,colon).trim();
+ String gnValue = gn.substring(colon+1).trim();
+
+ authCreds.set(gnType,gnValue);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (authCreds != null) req.put(AUTH_CREDS,authCreds);
+
+ try {
+ if (sane == null) sane = makeDefaultSubjectAltName(sanehash);
+ } catch (Exception sane_e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME",
+ sane_e.getMessage()));
+ }
+
+
+
+ try {
+ if (mAppendDN != null && ! mAppendDN.equals("")) {
+
+ X500Name newSubject = new X500Name(subject.toString());
+ subject = new X500Name( subject.toString().concat(","+mAppendDN));
+ }
+
+ } catch (Exception sne) {
+ log(ILogger.LL_INFO, "Unable to use appendDN parameter: "+mAppendDN+". Error is "+sne.getMessage()+" Using unmodified subjectname");
+ }
+
+ if (subject != null) req.put(SUBJECTNAME, subject);
+
+ if (key == null || subject == null) {
+ // log
+ //throw new ERegistrationException(RegistrationResources.ERROR_MALFORMED_P10);
+ }
+
+
+
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+
+ certInfo.set(X509CertInfo.KEY,
+ new CertificateX509Key(key));
+
+ CertificateExtensions ext = new CertificateExtensions();
+
+ if (kue != null) {
+ ext.set(KeyUsageExtension.NAME, kue);
+ }
+
+ // add subjectAltName extension, if present
+ if (sane != null) {
+ ext.set(SubjectAlternativeNameExtension.NAME, sane);
+ }
+
+ certInfo.set(X509CertInfo.EXTENSIONS,ext);
+
+ req.put(CERTINFO, certInfo);
+ } catch (Exception e) {
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ return ;
+ } // NEED TO FIX
+ }
+
+
+ private SubjectAlternativeNameExtension makeDefaultSubjectAltName(Hashtable ht) {
+
+ // if no subjectaltname extension was requested, we try to make it up
+ // from some of the elements of the subject name
+
+ int itemCount = ht.size();
+ GeneralNameInterface[] gn = new GeneralNameInterface[ht.size()];
+
+ itemCount = 0;
+ Enumeration en = ht.keys();
+ while (en.hasMoreElements()) {
+ String key = (String) en.nextElement();
+ if (key.equals(SANE_DNSNAME)) {
+ gn[itemCount++] = new DNSName((String)ht.get(key));
+ }
+ if (key.equals(SANE_IPADDRESS)) {
+ gn[itemCount++] = new IPAddressName((String)ht.get(key));
+ }
+ }
+
+ try {
+ return new SubjectAlternativeNameExtension( new GeneralNames(gn) );
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME",
+ e.getMessage()));
+ return null;
+ }
+ }
+
+
+
+ // Perform authentication
+
+ /*
+ * if the authentication is set up for CEP, and the user provides
+ * some credential, an attempt is made to authenticate the user
+ * If this fails, this method will return true
+ * If it is sucessful, this method will return true and
+ * an authtoken will be in the request
+ *
+ * If authentication is not configured, this method will
+ * return false. The request will be processed in the usual
+ * way, but no authtoken will be in the request.
+ *
+ * In other word, this method returns true if the request
+ * should be aborted, false otherwise.
+ */
+
+ private boolean authenticateUser(CRSPKIMessage req) {
+ boolean authenticationFailed = true;
+
+ if (mAuthManagerName == null) {
+ return false;
+ }
+
+ String password = (String)req.get(AUTH_PASSWORD);
+
+ AuthCredentials authCreds = (AuthCredentials)req.get(AUTH_CREDS);
+
+ if (authCreds == null) {
+ authCreds = new AuthCredentials();
+ }
+
+ // authtoken starts as null
+ AuthToken token = null;
+
+ if (password != null && !password.equals("")) {
+ try {
+ authCreds.set(AUTH_PASSWORD,password);
+ } catch (Exception e) {}
+ }
+
+
+ try {
+ token = (AuthToken)mAuthSubsystem.authenticate(authCreds,mAuthManagerName);
+ authCreds.delete(AUTH_PASSWORD);
+ // if we got here, the authenticate call must not have thrown
+ // an exception
+ authenticationFailed = false;
+ }
+ catch (EInvalidCredentials ex) {
+ // Invalid credentials - we must reject the request
+ authenticationFailed = true;
+ }
+ catch (EMissingCredential mc) {
+ // Misssing credential - we'll log, and process manually
+ authenticationFailed = false;
+ }
+ catch (EBaseException ex) {
+ // If there's some other error, we'll reject
+ // So, we just continue on, - AUTH_TOKEN will not be set.
+ }
+
+ if (token != null) {
+ req.put(AUTH_TOKEN,token);
+ }
+
+ return authenticationFailed;
+ }
+
+ private boolean areFingerprintsEqual(IRequest req, Hashtable fingerprints)
+ {
+
+ Hashtable old_fprints = req.getExtDataInHashtable(IRequest.FINGERPRINTS);
+ if (old_fprints == null) { return false; }
+
+ byte[] old_md5 = CMS.AtoB((String) old_fprints.get("MD5"));
+ byte[] new_md5 = (byte[]) fingerprints.get("MD5");
+
+ if (old_md5.length != new_md5.length) return false;
+
+ for (int i=0;i<old_md5.length; i++) {
+ if (old_md5[i] != new_md5[i]) return false;
+ }
+ return true;
+ }
+
+ public X509CertImpl handlePKCSReq(HttpServletRequest httpReq,
+ IRequest cmsRequest, CRSPKIMessage req,
+ CRSPKIMessage crsResp, CryptoContext cx)
+ throws ServletException,
+ CryptoManager.NotInitializedException,
+ CRSFailureException {
+
+ try {
+ unwrapPKCS10(req,cx);
+ Hashtable fingerprints = makeFingerPrints(req);
+
+ if (cmsRequest != null) {
+ if (areFingerprintsEqual(cmsRequest, fingerprints)) {
+ CMS.debug("created response from request");
+ return makeResponseFromRequest(req,crsResp,cmsRequest);
+ }
+ else {
+ CMS.debug("duplicated transaction id");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_DUP_TRANS_ID"));
+ crsResp.setFailInfo(crsResp.mFailInfo_badRequest);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ return null;
+ }
+ }
+
+ getDetailFromRequest(req,crsResp);
+ boolean authFailed = authenticateUser(req);
+
+ if (authFailed) {
+ CMS.debug("authentication failed");
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_AUTH"));
+ crsResp.setFailInfo(crsResp.mFailInfo_badIdentity);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+
+
+ // perform audit log
+ String auditMessage = CMS.getLogMessage(
+ "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5",
+ httpReq.getRemoteAddr(),
+ ILogger.FAILURE,
+ req.getTransactionID(),
+ "CRSEnrollment",
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+ ILogger signedAuditLogger = CMS.getSignedAuditLogger();
+ if (signedAuditLogger != null) {
+ signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null, ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY, auditMessage);
+ }
+
+ return null;
+ }
+ else {
+ IRequest ireq = postRequest(httpReq, req,crsResp);
+
+
+ CMS.debug("created response");
+ return makeResponseFromRequest(req,crsResp, ireq);
+ }
+ } catch (CryptoContext.CryptoContextException e) {
+ CMS.debug("failed to decrypt the request " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_DECRYPT_PKCS10",
+ e.getMessage()));
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ } catch (EBaseException e) {
+ CMS.debug("operation failure - " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERNOLL_FAIL_NO_NEW_REQUEST_POSTED",
+ e.getMessage()));
+ crsResp.setFailInfo(crsResp.mFailInfo_internalCAError);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ }
+ return null;
+ }
+
+
+////// post the request
+
+/*
+ needed:
+
+ token (authtoken)
+ certInfo
+ fingerprints x
+ req.transactionID
+ crsResp
+*/
+
+private IRequest postRequest(HttpServletRequest httpReq, CRSPKIMessage req, CRSPKIMessage crsResp)
+throws EBaseException {
+ X500Name subject = (X500Name)req.get(SUBJECTNAME);
+
+ if (mCreateEntry) {
+ if (subject == null) {
+ CMS.debug( "CRSEnrollment::postRequest() - subject is null!" );
+ return null;
+ }
+ createEntry(subject.toString());
+ }
+
+ // use profile framework to handle SCEP
+ if (mProfileId != null) {
+ PKCS10 pkcs10data = (PKCS10)req.getP10();
+ String pkcs10blob = CMS.BtoA(pkcs10data.toByteArray());
+
+ // XXX authentication handling
+ CMS.debug("Found profile=" + mProfileId);
+ IProfile profile = mProfileSubsystem.getProfile(mProfileId);
+ if (profile == null) {
+ CMS.debug("profile " + mProfileId + " not found");
+ return null;
+ }
+ IProfileContext ctx = profile.createContext();
+
+ IProfileAuthenticator authenticator = null;
+ try {
+ CMS.debug("Retrieving authenticator");
+ authenticator = profile.getAuthenticator();
+ if (authenticator == null) {
+ CMS.debug("No authenticator Found");
+ } else {
+ CMS.debug("Got authenticator=" + authenticator.getClass().getName());
+ }
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ }
+
+ IAuthToken authToken = null;
+
+ // for ssl authentication; pass in servlet for retrieving
+ // ssl client certificates
+ SessionContext context = SessionContext.getContext();
+
+
+ // insert profile context so that input parameter can be retrieved
+ context.put("profileContext", ctx);
+ context.put("sslClientCertProvider",
+ new SSLClientCertProvider(httpReq));
+
+ String p10Password = getPasswordFromP10(pkcs10data);
+ AuthCredentials credentials = new AuthCredentials();
+ credentials.set("UID", httpReq.getRemoteAddr());
+ credentials.set("PWD", p10Password);
+
+ if (authenticator == null) {
+ // XXX - to help caRouterCert to work, we need to
+ // add authentication to caRouterCert
+ authToken = new AuthToken(null);
+ } else {
+ authToken = authenticate(credentials, authenticator, httpReq);
+ }
+
+ IRequest reqs[] = null;
+ CMS.debug("CRSEnrollment: Creating profile requests");
+ ctx.set(IEnrollProfile.CTX_CERT_REQUEST_TYPE, "pkcs10");
+ ctx.set(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob);
+ Locale locale = Locale.getDefault();
+ reqs = profile.createRequests(ctx, locale);
+ if (reqs == null) {
+ CMS.debug("CRSEnrollment: No request has been created");
+ return null;
+ } else {
+ CMS.debug("CRSEnrollment: Request (" + reqs.length + ") have been created");
+ }
+ // set transaction id
+ reqs[0].setSourceId(req.getTransactionID());
+ reqs[0].setExtData("profile", "true");
+ reqs[0].setExtData("profileId", mProfileId);
+ reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST_TYPE, IEnrollProfile.REQ_TYPE_PKCS10);
+ reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob);
+ reqs[0].setExtData("requestor_name", "");
+ reqs[0].setExtData("requestor_email", "");
+ reqs[0].setExtData("requestor_phone", "");
+ reqs[0].setExtData("profileRemoteHost", httpReq.getRemoteHost());
+ reqs[0].setExtData("profileRemoteAddr", httpReq.getRemoteAddr());
+ reqs[0].setExtData("profileApprovedBy", profile.getApprovedBy());
+
+ CMS.debug("CRSEnrollment: Populating inputs");
+ profile.populateInput(ctx, reqs[0]);
+ CMS.debug("CRSEnrollment: Populating requests");
+ profile.populate(reqs[0]);
+
+ CMS.debug("CRSEnrollment: Submitting request");
+ profile.submit(authToken, reqs[0]);
+ CMS.debug("CRSEnrollment: Done submitting request");
+ profile.getRequestQueue().markAsServiced(reqs[0]);
+ CMS.debug("CRSEnrollment: Request marked as serviced");
+
+ return reqs[0];
+
+ }
+
+ IRequestQueue rq = ca.getRequestQueue();
+ IRequest pkiReq = rq.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ AuthToken token = (AuthToken) req.get(AUTH_TOKEN);
+ if (token != null) {
+ pkiReq.setExtData(IRequest.AUTH_TOKEN,token);
+ }
+
+ pkiReq.setExtData(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE, IRequest.CEP_CERT);
+ X509CertInfo certInfo = (X509CertInfo) req.get(CERTINFO);
+ pkiReq.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { certInfo } );
+ pkiReq.setExtData("cepsubstore", mSubstoreName);
+
+ try {
+ String chpwd = (String)req.get(ChallengePassword.NAME);
+ if (chpwd != null) {
+ pkiReq.setExtData("challengePhrase",
+ chpwd );
+ }
+ } catch (Exception pwex) {
+ }
+
+ Hashtable fingerprints = (Hashtable)req.get(IRequest.FINGERPRINTS);
+ if (fingerprints.size() > 0) {
+ Hashtable encodedPrints = new Hashtable(fingerprints.size());
+ Enumeration e = fingerprints.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ byte[] value = (byte[])fingerprints.get(key);
+ encodedPrints.put(key, CMS.BtoA(value));
+ }
+ pkiReq.setExtData(IRequest.FINGERPRINTS, encodedPrints);
+ }
+
+ pkiReq.setSourceId(req.getTransactionID());
+
+ rq.processRequest(pkiReq);
+
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ pkiReq.getRequestId(),
+ AuditFormat.FROMROUTER,
+ mAuthManagerName == null ? AuditFormat.NOAUTH : mAuthManagerName,
+ "pending",
+ subject ,
+ ""}
+ );
+
+ return pkiReq;
+ }
+
+
+
+ public Hashtable makeFingerPrints(CRSPKIMessage req) {
+ Hashtable fingerprints = new Hashtable();
+
+ MessageDigest md;
+ String[] hashes = new String[] {"MD2", "MD5", "SHA1", "SHA256", "SHA512"};
+ PKCS10 p10 = (PKCS10)req.getP10();
+
+ for (int i=0;i<hashes.length;i++) {
+ try {
+ md = MessageDigest.getInstance(hashes[i]);
+ md.update(p10.getCertRequestInfo());
+ fingerprints.put(hashes[i],md.digest());
+ }
+ catch (NoSuchAlgorithmException nsa) {}
+ }
+
+ if (fingerprints != null) {
+ req.put(IRequest.FINGERPRINTS,fingerprints);
+ }
+ return fingerprints;
+ }
+
+
+ // Take a look to see if the request was successful, and fill
+ // in the response message
+
+
+ private X509CertImpl makeResponseFromRequest(CRSPKIMessage crsReq, CRSPKIMessage crsResp,
+ IRequest pkiReq)
+ {
+
+ X509CertImpl issuedCert=null;
+
+ RequestStatus status = pkiReq.getRequestStatus();
+
+ String profileId = pkiReq.getExtDataInString("profileId");
+ if (profileId != null) {
+ CMS.debug("CRSEnrollment: Found profile request");
+ X509CertImpl cert =
+ pkiReq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null) {
+ CMS.debug("CRSEnrollment: No certificate has been found");
+ } else {
+ CMS.debug("CRSEnrollment: Found certificate");
+ }
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+ return cert;
+ }
+
+
+ if ( status.equals(RequestStatus.COMPLETE)) {
+ Integer success = pkiReq.getExtDataInInteger(IRequest.RESULT);
+
+
+ if (success.equals(IRequest.RES_SUCCESS)) {
+ // The cert was issued, lets send it back to the router
+ X509CertImpl[] issuedCertBuf =
+ pkiReq.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ if (issuedCertBuf == null || issuedCertBuf.length == 0) {
+ // writeError("Internal Error: Bad operation",httpReq,httpResp);
+ CMS.debug( "CRSEnrollment::makeResponseFromRequest() - " +
+ "Bad operation" );
+ return null;
+ }
+ issuedCert = issuedCertBuf[0];
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+
+ }
+ else { // status is not 'success' - there must've been a problem
+
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ crsResp.setFailInfo(crsResp.mFailInfo_badAlg);
+ }
+ }
+ else if (status.equals(RequestStatus.REJECTED_STRING) ||
+ status.equals(RequestStatus.CANCELED_STRING)) {
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ crsResp.setFailInfo(crsResp.mFailInfo_badRequest);
+ }
+ else { // not complete
+ crsResp.setPKIStatus(crsResp.mStatus_PENDING);
+ }
+
+ return issuedCert;
+ }
+
+
+
+
+
+
+ /**
+ * This needs to be re-written to log the messages to the system log, since there
+ * will be no visual webpage feedback for the user. (he's using a router)
+ */
+
+ private void writeError(String errMsg, HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws IOException
+ {
+ }
+
+
+ protected String hashPassword(String pwd) {
+ String salt = "lala123";
+ byte[] pwdDigest = mSHADigest.digest((salt+pwd).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest);
+ return "{SHA}"+b64E;
+ }
+
+
+
+
+ /**
+ * Make the CRSPKIMESSAGE response
+ */
+
+
+ private void processCertRep(CryptoContext cx,
+ X509CertImpl issuedCert,
+ CRSPKIMessage crsResp,
+ CRSPKIMessage crsReq)
+ throws CRSFailureException {
+ byte[] msgdigest = null;
+ byte[] encryptedDesKey = null;
+
+ try {
+ if (issuedCert != null) {
+
+ SymmetricKey sk;
+ SymmetricKey skinternal;
+
+ KeyGenAlgorithm kga = KeyGenAlgorithm.DES;
+ EncryptionAlgorithm ea = EncryptionAlgorithm.DES_CBC;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ kga = KeyGenAlgorithm.DES3;
+ ea = EncryptionAlgorithm.DES3_CBC;
+ }
+
+ // 1. Make the Degenerated PKCS7 with the recipient's certificate in it
+
+ byte toBeEncrypted[] =
+ crsResp.makeSignedRep(1, // version
+ issuedCert.getEncoded()
+ );
+
+ // 2. Encrypt the above byte array with a new random DES key
+
+ sk = cx.getDESKeyGenerator().generate();
+
+ skinternal = cx.getInternalToken().getKeyGenerator(kga).clone(sk);
+
+ byte[] padded = Cipher.pad(toBeEncrypted, ea.getBlockSize());
+
+
+ // This should be changed to generate proper DES IV.
+
+ Cipher cipher = cx.getInternalToken().getCipherContext(ea);
+ IVParameterSpec desIV =
+ new IVParameterSpec(new byte[]{
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00 } );
+
+ cipher.initEncrypt(sk,desIV);
+ byte[] encryptedData = cipher.doFinal(padded);
+
+ crsResp.makeEncryptedContentInfo(desIV.getIV(),encryptedData, mEncryptionAlgorithm);
+
+ // 3. Extract the recipient's public key
+
+ PublicKey rcpPK = crsReq.getSignerPublicKey();
+
+
+ // 4. Encrypt the DES key with the public key
+
+ // we have to move the key onto the interal token.
+ //skinternal = cx.getInternalKeyStorageToken().cloneKey(sk);
+ skinternal = cx.getInternalToken().cloneKey(sk);
+
+ KeyWrapper kw = cx.getInternalKeyWrapper();
+ kw.initWrap(rcpPK, null);
+ encryptedDesKey = kw.wrap(skinternal);
+
+ crsResp.setRcpIssuerAndSerialNumber(crsReq.getSgnIssuerAndSerialNumber());
+ crsResp.makeRecipientInfo(0, encryptedDesKey );
+
+ }
+
+
+ byte[] ed = crsResp.makeEnvelopedData(0);
+
+ // 7. Make Digest of SignedData Content
+ MessageDigest md = MessageDigest.getInstance(mHashAlgorithm);
+ msgdigest = md.digest(ed);
+
+ crsResp.setMsgDigest(msgdigest);
+
+ }
+
+ catch (Exception e) {
+ throw new CRSFailureException("Failed to create inner response to CEP message: "+e.getMessage());
+ }
+
+
+ // 5. Make a RecipientInfo
+
+ // The issuer name & serial number here, should be that of
+ // the EE's self-signed Certificate
+ // [I can get it from the req blob, but later, I should
+ // store the recipient's self-signed certificate with the request
+ // so I can get at it later. I need to do this to support
+ // 'PENDING']
+
+
+ try {
+
+ // 8. Make Authenticated Attributes
+ // we can just pull the transaction ID out of the request.
+ // Later, we will have to put it out of the Request queue,
+ // so we can support PENDING
+ crsResp.setTransactionID(crsReq.getTransactionID());
+ // recipientNonce and SenderNonce have already been set
+
+ crsResp.makeAuthenticatedAttributes();
+ // crsResp.makeAuthenticatedAttributes_old();
+
+
+
+ // now package up the rest of the SignerInfo
+ {
+ byte[] signingcertbytes = cx.getSigningCert().getEncoded();
+
+
+ Certificate.Template sgncert_t = new Certificate.Template();
+ Certificate sgncert =
+ (Certificate) sgncert_t.decode(new ByteArrayInputStream(signingcertbytes));
+
+ IssuerAndSerialNumber sgniasn =
+ new IssuerAndSerialNumber(sgncert.getInfo().getIssuer(),
+ sgncert.getInfo().getSerialNumber());
+
+ crsResp.setSgnIssuerAndSerialNumber(sgniasn);
+
+ // 10. Make SignerInfo
+ crsResp.makeSignerInfo(1, cx.getPrivateKey(), mHashAlgorithm);
+
+ // 11. Make SignedData
+ crsResp.makeSignedData(1, signingcertbytes, mHashAlgorithm);
+
+ crsResp.debug();
+ }
+ }
+ catch (Exception e) {
+ throw new CRSFailureException("Failed to create outer response to CEP request: "+e.getMessage());
+ }
+
+
+ // if debugging, dump out the response into a file
+
+ }
+
+
+
+ class CryptoContext {
+ private CryptoManager cm;
+ private CryptoToken internalToken;
+ private CryptoToken keyStorageToken;
+ private CryptoToken internalKeyStorageToken;
+ private KeyGenerator DESkg;
+ private Enumeration externalTokens = null;
+ private org.mozilla.jss.crypto.X509Certificate signingCert;
+ private org.mozilla.jss.crypto.PrivateKey signingCertPrivKey;
+ private int signingCertKeySize = 0;
+
+
+ class CryptoContextException extends Exception {
+ public CryptoContextException() { super(); }
+ public CryptoContextException(String s) { super(s); }
+ }
+
+ public CryptoContext()
+ throws CryptoContextException
+ {
+ try {
+ KeyGenAlgorithm kga = KeyGenAlgorithm.DES;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ kga = KeyGenAlgorithm.DES3;
+ }
+ cm = CryptoManager.getInstance();
+ internalToken = cm.getInternalCryptoToken();
+ DESkg = internalToken.getKeyGenerator(kga);
+ if (mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) ||
+ mTokenName.equalsIgnoreCase("Internal Key Storage Token") ||
+ mTokenName.length() == 0) {
+ keyStorageToken = cm.getInternalKeyStorageToken();
+ internalKeyStorageToken = keyStorageToken;
+ CMS.debug("CRSEnrollment: CryptoContext: internal token name: '"+mTokenName+"'");
+ } else {
+ keyStorageToken = cm.getTokenByName(mTokenName);
+ internalKeyStorageToken = null;
+ mNickname = mTokenName + ":" + mNickname;
+ CMS.debug("CRSEnrollment: CryptoContext: token name: "+mTokenName+"'");
+ }
+ CMS.debug("CRSEnrollment: CryptoContext: mNickname: '"+mNickname+"'");
+ if (!mUseCA && internalKeyStorageToken == null) {
+ PasswordCallback cb = CMS.getPasswordCallback();
+ keyStorageToken.login(cb); // ONE_TIME by default.
+ }
+ signingCert = cm.findCertByNickname(mNickname);
+ signingCertPrivKey = cm.findPrivKeyByCert(signingCert);
+ byte[] encPubKeyInfo = signingCert.getPublicKey().getEncoded();
+ SEQUENCE.Template outer = SEQUENCE.getTemplate();
+ outer.addElement( ANY.getTemplate() ); // algid
+ outer.addElement( BIT_STRING.getTemplate() );
+ SEQUENCE outerSeq = (SEQUENCE) ASN1Util.decode(outer, encPubKeyInfo);
+ BIT_STRING bs = (BIT_STRING) outerSeq.elementAt(1);
+ byte[] encPubKey = bs.getBits();
+ if( bs.getPadCount() != 0) {
+ throw new CryptoContextException("Internal error: Invalid Public key. Not an integral number of bytes.");
+ }
+ SEQUENCE.Template inner = new SEQUENCE.Template();
+ inner.addElement( INTEGER.getTemplate());
+ inner.addElement( INTEGER.getTemplate());
+ SEQUENCE pubKeySeq = (SEQUENCE) ASN1Util.decode(inner, encPubKey);
+ INTEGER modulus = (INTEGER) pubKeySeq.elementAt(0);
+ signingCertKeySize = modulus.bitLength();
+
+ try {
+ FileOutputStream fos = new FileOutputStream("pubkey.der");
+ fos.write(signingCert.getPublicKey().getEncoded());
+ fos.close();
+ } catch (Exception e) {}
+
+ }
+ catch (InvalidBERException e) {
+ throw new CryptoContextException("Internal Error: Bad internal Certificate Representation. Not a valid RSA-signed certificate");
+ }
+ catch (CryptoManager.NotInitializedException e) {
+ throw new CryptoContextException("Crypto Manager not initialized");
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException("Cannot create DES key generator");
+ }
+ catch (ObjectNotFoundException e) {
+ throw new CryptoContextException("Certificate not found: "+ca.getNickname());
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchTokenException e) {
+ throw new CryptoContextException("Crypto Token not found: "+e.getMessage());
+ }
+ catch (IncorrectPasswordException e) {
+ throw new CryptoContextException("Incorrect Password.");
+ }
+ }
+
+
+ public KeyGenerator getDESKeyGenerator() {
+ return DESkg;
+ }
+
+ public CryptoToken getInternalToken() {
+ return internalToken;
+ }
+
+ public void setExternalTokens( Enumeration tokens ) {
+ externalTokens = tokens;
+ }
+
+ public Enumeration getExternalTokens() {
+ return externalTokens;
+ }
+
+ public CryptoToken getInternalKeyStorageToken() {
+ return internalKeyStorageToken;
+ }
+
+ public CryptoToken getKeyStorageToken() {
+ return keyStorageToken;
+ }
+
+ public CryptoManager getCryptoManager() {
+ return cm;
+ }
+
+ public KeyWrapper getKeyWrapper()
+ throws CryptoContextException {
+ try {
+ return signingCertPrivKey.getOwningToken().getKeyWrapper(KeyWrapAlgorithm.RSA);
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException(e.getMessage());
+ }
+ }
+
+ public KeyWrapper getInternalKeyWrapper()
+ throws CryptoContextException {
+ try {
+ return getInternalToken().getKeyWrapper(KeyWrapAlgorithm.RSA);
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException(e.getMessage());
+ }
+ }
+
+ public org.mozilla.jss.crypto.PrivateKey getPrivateKey() {
+ return signingCertPrivKey;
+ }
+
+ public org.mozilla.jss.crypto.X509Certificate getSigningCert() {
+ return signingCert;
+ }
+
+ }
+
+
+ /* General failure. The request/response cannot be processed. */
+
+
+ class CRSFailureException extends Exception {
+ public CRSFailureException() { super(); }
+ public CRSFailureException(String s) { super(s); }
+ }
+
+ class CRSInvalidSignatureException extends Exception {
+ public CRSInvalidSignatureException() { super(); }
+ public CRSInvalidSignatureException(String s) { super(s); }
+ }
+
+
+
+ class CRSPolicyException extends Exception {
+ public CRSPolicyException() { super(); }
+ public CRSPolicyException(String s) { super(s); }
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java
new file mode 100644
index 000000000..3e94228a1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java
@@ -0,0 +1,142 @@
+// --- 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.servlet.cert.scep;
+
+import java.io.*;
+import java.security.*;
+import java.util.Properties;
+import java.util.*;
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.cmsutil.scep.*;
+import java.security.cert.CertificateException;
+
+/**
+ * Class for handling the decoding of a SCEP Challenge Password
+ * object. Currently this class cannot be used for encoding
+ * thus some fo the methods are unimplemented
+ */
+public class ChallengePassword implements CertAttrSet {
+
+ public static final String NAME = "ChallengePassword";
+ public static final String PASSWORD = "password";
+
+ private String cpw;
+
+
+ /**
+ * Get the password marshalled in this object
+ * @return the challenge password
+ */
+ public String toString() {
+ return cpw;
+ }
+
+ /**
+ * Create a ChallengePassword object
+ * @param stuff (must be of type byte[]) a DER-encoded by array following
+ * The ASN.1 template for ChallenegePassword specified in the SCEP
+ * documentation
+ * @throws IOException if the DER encoded byt array was malformed, or if it
+ * did not match the template
+ */
+
+ public ChallengePassword(Object stuff)
+ throws IOException {
+
+ ByteArrayInputStream is = new ByteArrayInputStream((byte[])stuff);
+ try {
+ decode(is);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+
+ }
+
+ /**
+ * Currently Unimplemented
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException
+ { }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException
+ {
+ DerValue derVal = new DerValue(in);
+
+ construct(derVal);
+
+ }
+
+ private void construct(DerValue derVal) throws IOException {
+ try {
+ cpw = derVal.getPrintableString();
+ }
+ catch (NullPointerException e) {
+ cpw = "";
+ }
+ }
+
+
+ /**
+ * Currently Unimplemented
+ */
+ public void set(String name, Object obj)
+ throws CertificateException, IOException
+ { }
+
+ /**
+ * Get an attribute of this object.
+ * @param name the name of the attribute of this object to get. The only
+ * supported attribute is "password"
+ */
+ public Object get(String name)
+ throws CertificateException, IOException
+ {
+ if (name.equalsIgnoreCase(PASSWORD)) {
+ return cpw;
+ }
+ else {
+ throw new IOException("Attribute name not recognized by "+
+ "CertAttrSet: ChallengePassword");
+ }
+ }
+
+ /**
+ * Currently Unimplemented
+ */
+ public void delete(String name)
+ throws CertificateException, IOException
+ { }
+
+ /**
+ * @return an empty set of elements
+ */
+ public Enumeration getElements()
+ { return (new Hashtable()).elements();}
+
+ /**
+ * @return the String "ChallengePassword"
+ */
+ public String getName()
+ { return NAME;}
+
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
new file mode 100644
index 000000000..616eab27b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
@@ -0,0 +1,187 @@
+// --- 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.servlet.cert.scep;
+
+import java.io.*;
+import java.security.*;
+import java.util.Properties;
+import java.util.*;
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import java.security.cert.CertificateException;
+import com.netscape.cmsutil.scep.*;
+
+
+public class ExtensionsRequested implements CertAttrSet {
+
+
+ public static final String NAME = "EXTENSIONS_REQUESTED";
+
+ public static final String KUE_DIGITAL_SIGNATURE = "kue_digital_signature";
+ public static final String KUE_KEY_ENCIPHERMENT = "kue_key_encipherment";
+
+ private String kue_digital_signature = "false";
+ private String kue_key_encipherment = "false";
+
+ private Vector exts = new Vector();
+
+ public ExtensionsRequested(Object stuff) throws IOException {
+ ByteArrayInputStream is = new ByteArrayInputStream((byte[]) stuff);
+
+ try {
+ decode(is);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void encode(OutputStream out)
+ throws CertificateException, IOException
+ { }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException
+ {
+ DerValue derVal = new DerValue(in);
+
+ construct(derVal);
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException
+ { }
+
+ public Object get(String name)
+ throws CertificateException, IOException
+ {
+ if (name.equalsIgnoreCase(KUE_DIGITAL_SIGNATURE)) {
+ return kue_digital_signature;
+ }
+ if (name.equalsIgnoreCase(KUE_KEY_ENCIPHERMENT)) {
+ return kue_key_encipherment;
+ }
+
+ throw new IOException("Unsupported attribute queried");
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException
+ {
+ }
+
+ public Enumeration getElements()
+ { return (new Hashtable()).elements();}
+
+ public String getName()
+ { return NAME;}
+
+
+
+/**
+ construct - expects this in the inputstream (from the router):
+
+ 211 30 31: SEQUENCE {
+ 213 06 10: OBJECT IDENTIFIER '2 16 840 1 113733 1 9 8'
+ 225 31 17: SET {
+ 227 04 15: OCTET STRING, encapsulates {
+ 229 30 13: SEQUENCE {
+ 231 30 11: SEQUENCE {
+ 233 06 3: OBJECT IDENTIFIER keyUsage (2 5 29 15)
+ 238 04 4: OCTET STRING
+ : 03 02 05 A0
+ : }
+ : }
+ : }
+
+ or this (from IRE client):
+
+ 262 30 51: SEQUENCE {
+ 264 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 14)
+ 275 31 38: SET {
+ 277 30 36: SEQUENCE {
+ 279 30 34: SEQUENCE {
+ 281 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17)
+ 286 04 27: OCTET STRING
+ : 30 19 87 04 D0 0C 3E 6F 81 03 61 61 61 82 0C 61
+ : 61 61 2E 6D 63 6F 6D 2E 63 6F 6D
+ : }
+ : }
+ : }
+ : }
+
+
+ */
+ private void construct(DerValue dv) throws IOException {
+
+ DerInputStream stream = null;
+ DerValue[] dvs;
+
+ try { // try decoding as sequence first
+
+ stream = dv.toDerInputStream();
+
+ DerValue stream_dv = stream.getDerValue();
+ stream.reset();
+
+
+ dvs = stream.getSequence(2);
+ }
+ catch (IOException ioe) {
+ // if it failed, the outer sequence may be
+ // encapsulated in an octet string, as in the first
+ // example above
+
+ byte[] octet_string = dv.getOctetString();
+
+ // Make a new input stream from the byte array,
+ // and re-parse it as a sequence.
+
+ dv = new DerValue(octet_string);
+
+ stream = dv.toDerInputStream();
+ dvs = stream.getSequence(2);
+ }
+
+ // now, the stream will be in the correct format
+ stream.reset();
+
+ while (true) {
+ DerValue ext_dv=null;
+ try {
+ ext_dv = stream.getDerValue();
+ }
+ catch (IOException ex) {
+ break;
+ }
+
+ Extension ext = new Extension(ext_dv);
+ exts.addElement(ext);
+ }
+
+ }
+
+ public Vector getExtensions() {
+ return exts;
+ }
+
+}
+
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java b/pki/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java
new file mode 100644
index 000000000..7407a80cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java
@@ -0,0 +1,100 @@
+// --- 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.servlet.common;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * Authentication Credentials as input to the authMgr
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthCredentials implements IAuthCredentials {
+ private Hashtable authCreds = null;
+ // Inserted by bskim
+ private IArgBlock argblk = null;
+ // Insert end
+
+ public AuthCredentials() {
+ authCreds = new Hashtable();
+ }
+
+ /**
+ * sets a credential with credential name and the credential
+ * @param name credential name
+ * @param cred credential
+ * @exception com.netscape.certsrv.base.EBaseException NullPointerException
+ */
+ public void set(String name, Object cred)throws EBaseException {
+ if (cred == null) {
+ throw new EBaseException("AuthCredentials.set()");
+ }
+
+ authCreds.put(name, cred);
+ }
+
+ /**
+ * returns the credential to which the specified name is mapped in this
+ * credential set
+ * @param name credential name
+ * @return the named authentication credential
+ */
+ public Object get(String name) {
+ return ((Object) authCreds.get(name));
+ }
+
+ /**
+ * removes the name and its corresponding credential from this
+ * credential set. This method does nothing if the named
+ * credential is not in the credential set.
+ * @param name credential name
+ */
+ public void delete(String name) {
+ authCreds.remove(name);
+ }
+
+ /**
+ * returns an enumeration of the credentials in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ * @return an enumeration of the values in this credential set
+ * @see java.util.Enumeration
+ */
+ public Enumeration getElements() {
+ return (authCreds.elements());
+ }
+
+ // Inserted by bskim
+ public void setArgBlock(IArgBlock blk) {
+ argblk = blk;
+ return;
+ }
+
+ // Insert end
+
+ public IArgBlock getArgBlock() {
+ return argblk;
+ }
+ // Insert end
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
new file mode 100644
index 000000000..6cd9e7afb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
@@ -0,0 +1,1063 @@
+// --- 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.servlet.common;
+
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkix.cmmf.*;
+import org.mozilla.jss.pkix.primitive.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.base.SessionContext;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cert.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.security.*;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+
+/**
+ * Utility CMCOutputTemplate
+ *
+ * @version $ $, $Date$
+ */
+public class CMCOutputTemplate {
+ public CMCOutputTemplate() {
+ }
+
+ public void createFullResponseWithFailedStatus(HttpServletResponse resp,
+ SEQUENCE bpids, int code, UTF8String s) {
+ SEQUENCE controlSeq = new SEQUENCE();
+ SEQUENCE cmsSeq = new SEQUENCE();
+ SEQUENCE otherMsgSeq = new SEQUENCE();
+
+ int bpid = 1;
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(code), null);
+ CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(
+ new INTEGER(CMCStatusInfo.FAILED),
+ bpids, s, otherInfo);
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+
+ try {
+ ResponseBody respBody = new ResponseBody(controlSeq,
+ cmsSeq, otherMsgSeq);
+
+ SET certs = new SET();
+ ContentInfo contentInfo = getContentInfo(respBody, certs);
+ if (contentInfo == null)
+ return;
+ ByteArrayOutputStream fos = new ByteArrayOutputStream();
+ contentInfo.encode(fos);
+ fos.close();
+ byte[] contentBytes = fos.toByteArray();
+
+ resp.setContentType("application/pkcs7-mime");
+ resp.setContentLength(contentBytes.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(contentBytes);
+ os.flush();
+ } catch (Exception e) {
+ CMS.debug("CMCOutputTemplate createFullResponseWithFailedStatus Exception: "+e.toString());
+ return;
+ }
+ }
+
+ public void createFullResponse(HttpServletResponse resp, IRequest []reqs,
+ String cert_request_type, int[] error_codes) {
+
+ SEQUENCE controlSeq = new SEQUENCE();
+ SEQUENCE cmsSeq = new SEQUENCE();
+ SEQUENCE otherMsgSeq = new SEQUENCE();
+ SessionContext context = SessionContext.getContext();
+
+ // set status info control for simple enrollment request
+ // in rfc 2797: body list value is 1
+ int bpid = 1;
+ SEQUENCE pending_bpids = null;
+ SEQUENCE success_bpids = null;
+ SEQUENCE failed_bpids = null;
+ if (cert_request_type.equals("crmf") ||
+ cert_request_type.equals("pkcs10")) {
+ String reqId = reqs[0].getRequestId().toString();
+ OtherInfo otherInfo = null;
+ if (error_codes[0] == 2) {
+ PendInfo pendInfo = new PendInfo(reqId, new Date());
+ otherInfo = new OtherInfo(OtherInfo.PEND, null,
+ pendInfo);
+ } else {
+ otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_REQUEST), null);
+ }
+
+ SEQUENCE bpids = new SEQUENCE();
+ bpids.addElement(new INTEGER(1));
+ CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING,
+ bpids, (String)null, otherInfo);
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ } else if (cert_request_type.equals("cmc")) {
+ pending_bpids = new SEQUENCE();
+ success_bpids = new SEQUENCE();
+ failed_bpids = new SEQUENCE();
+ if (reqs != null) {
+ for (int i=0; i<reqs.length; i++) {
+ if (error_codes[i] == 0) {
+ success_bpids.addElement(new INTEGER(
+ reqs[i].getExtDataInBigInteger("bodyPartId")));
+ } else if (error_codes[i] == 2) {
+ pending_bpids.addElement(new INTEGER(
+ reqs[i].getExtDataInBigInteger("bodyPartId")));
+ } else {
+ failed_bpids.addElement(new INTEGER(
+ reqs[i].getExtDataInBigInteger("bodyPartId")));
+ }
+ }
+ }
+
+ TaggedAttribute tagattr = null;
+ CMCStatusInfo cmcStatusInfo = null;
+ SEQUENCE identityBpids = (SEQUENCE)context.get("identityProof");
+ if (identityBpids != null && identityBpids.size() > 0) {
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_IDENTITY), null);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED,
+ identityBpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ SEQUENCE POPLinkWitnessBpids = (SEQUENCE)context.get("POPLinkWitness");
+ if (POPLinkWitnessBpids != null && POPLinkWitnessBpids.size() > 0) {
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_REQUEST), null);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED,
+ POPLinkWitnessBpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ if (pending_bpids.size() > 0) {
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING,
+ pending_bpids, (String)null, null);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ if (success_bpids.size() > 0) {
+ boolean confirmRequired = false;
+ try {
+ confirmRequired =
+ CMS.getConfigStore().getBoolean("cmc.cert.confirmRequired",
+ false);
+ } catch (Exception e) {
+ }
+ if (confirmRequired) {
+ CMS.debug("CMCOutputTemplate: confirmRequired in the request");
+ cmcStatusInfo =
+ new CMCStatusInfo(CMCStatusInfo.CONFIRM_REQUIRED,
+ success_bpids, (String)null, null);
+ } else {
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS,
+ success_bpids, (String)null, null);
+ }
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ if (failed_bpids.size() > 0) {
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_REQUEST), null);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED,
+ failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+ }
+
+ SET certs = new SET();
+
+ try {
+ // deal with controls
+ Integer nums = (Integer)(context.get("numOfControls"));
+ if (nums != null && nums.intValue() > 0) {
+ TaggedAttribute attr =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
+ if (attr != null) {
+ try {
+ processGetCertControl(attr, certs);
+ } catch (EBaseException ee) {
+ CMS.debug("CMCOutputTemplate: "+ee.toString());
+ OtherInfo otherInfo1 = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_CERT_ID), null);
+ SEQUENCE bpids1 = new SEQUENCE();
+ bpids1.addElement(attr.getBodyPartID());
+ CMCStatusInfo cmcStatusInfo1 = new CMCStatusInfo(
+ new INTEGER(CMCStatusInfo.FAILED),
+ bpids1, null, otherInfo1);
+ TaggedAttribute tagattr1 = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo1);
+ controlSeq.addElement(tagattr1);
+ }
+ }
+
+ attr =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_dataReturn));
+ if (attr != null)
+ bpid = processDataReturnControl(attr, controlSeq, bpid);
+
+ attr =
+ (TaggedAttribute)context.get(OBJECT_IDENTIFIER.id_cmc_transactionId);
+ if (attr != null)
+ bpid = processTransactionControl(attr, controlSeq, bpid);
+
+ attr =
+ (TaggedAttribute)context.get(OBJECT_IDENTIFIER.id_cmc_senderNonce);
+ if (attr != null)
+ bpid = processSenderNonceControl(attr, controlSeq, bpid);
+
+ attr =
+ (TaggedAttribute)context.get(OBJECT_IDENTIFIER.id_cmc_QueryPending);
+ if (attr != null)
+ bpid = processQueryPendingControl(attr, controlSeq, bpid);
+
+ attr =
+ (TaggedAttribute)context.get(OBJECT_IDENTIFIER.id_cmc_idConfirmCertAcceptance);
+
+ if (attr != null)
+ bpid = processConfirmCertAcceptanceControl(attr, controlSeq,
+ bpid);
+
+ attr =
+ (TaggedAttribute)context.get(OBJECT_IDENTIFIER.id_cmc_revokeRequest);
+
+ if (attr != null)
+ bpid = processRevokeRequestControl(attr, controlSeq,
+ bpid);
+ }
+
+ if (success_bpids != null && success_bpids.size() > 0) {
+ for (int i=0; i<reqs.length; i++) {
+ if (error_codes[i] == 0) {
+ X509CertImpl impl =
+ (reqs[i].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT));
+ byte[] bin = impl.getEncoded();
+ Certificate.Template certTemplate = new Certificate.Template();
+ Certificate cert = (Certificate)certTemplate.decode(
+ new ByteArrayInputStream(bin));
+ certs.addElement(cert);
+ }
+ }
+ }
+
+ ResponseBody respBody = new ResponseBody(controlSeq,
+ cmsSeq, otherMsgSeq);
+
+ ContentInfo contentInfo = getContentInfo(respBody, certs);
+ ByteArrayOutputStream fos = new ByteArrayOutputStream();
+ contentInfo.encode(fos);
+ fos.close();
+ byte[] contentBytes = fos.toByteArray();
+
+ resp.setContentType("application/pkcs7-mime");
+ resp.setContentLength(contentBytes.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(contentBytes);
+ os.flush();
+ } catch (java.security.cert.CertificateEncodingException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ } catch (InvalidBERException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ } catch (IOException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ } catch (Exception e) {
+ CMS.debug("Exception: "+e.toString());
+ }
+ }
+
+ private ContentInfo getContentInfo(ResponseBody respBody, SET certs) {
+ try {
+ ICertificateAuthority ca = null;
+ // add CA cert chain
+ ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ CertificateChain certchains = ca.getCACertChain();
+ java.security.cert.X509Certificate[] chains = certchains.getChain();
+
+ for (int i=0; i<chains.length; i++) {
+ Certificate.Template certTemplate = new Certificate.Template();
+ Certificate cert = (Certificate)certTemplate.decode(
+ new ByteArrayInputStream(chains[i].getEncoded()));
+ certs.addElement(cert);
+ }
+
+ EncapsulatedContentInfo enContentInfo = new EncapsulatedContentInfo(
+ OBJECT_IDENTIFIER.id_cct_PKIResponse, respBody);
+ org.mozilla.jss.crypto.X509Certificate x509CAcert = null;
+ x509CAcert = ca.getCaX509Cert();
+ X509CertImpl caimpl = new X509CertImpl(x509CAcert.getEncoded());
+ X500Name issuerName = (X500Name)caimpl.getIssuerDN();
+ byte[] issuerByte = issuerName.getEncoded();
+ ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte);
+ Name issuer = (Name) Name.getTemplate().decode(istream);
+ IssuerAndSerialNumber ias = new IssuerAndSerialNumber(
+ issuer, new INTEGER(x509CAcert.getSerialNumber().toString()));
+ SignerIdentifier si = new SignerIdentifier(
+ SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+ // use CA instance's default signature and digest algorithm
+ SignatureAlgorithm signAlg = ca.getDefaultSignatureAlgorithm();
+ org.mozilla.jss.crypto.PrivateKey privKey =
+ CryptoManager.getInstance().findPrivKeyByCert(x509CAcert);
+/*
+ org.mozilla.jss.crypto.PrivateKey.Type keyType = privKey.getType();
+ if( keyType.equals( org.mozilla.jss.crypto.PrivateKey.RSA ) ) {
+ signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ } else if( keyType.equals( org.mozilla.jss.crypto.PrivateKey.DSA ) ) {
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ } else if( keyType.equals( org.mozilla.jss.crypto.PrivateKey.EC ) ) {
+ signAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest;
+ } else {
+ CMS.debug( "CMCOutputTemplate::getContentInfo() - "
+ + "signAlg is unsupported!" );
+ return null;
+ }
+*/
+ DigestAlgorithm digestAlg = signAlg.getDigestAlg();
+ MessageDigest msgDigest = null;
+ byte[] digest = null;
+
+ msgDigest = MessageDigest.getInstance(digestAlg.toString());
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ respBody.encode((OutputStream) ostream);
+ digest = msgDigest.digest(ostream.toByteArray());
+
+ SignerInfo signInfo = new
+ SignerInfo(si, null, null,
+ OBJECT_IDENTIFIER.id_cct_PKIResponse,
+ digest, signAlg, privKey);
+ SET signInfos = new SET();
+
+ signInfos.addElement(signInfo);
+
+ SET digestAlgs = new SET();
+
+ if (digestAlg != null) {
+ AlgorithmIdentifier ai = new
+ AlgorithmIdentifier(digestAlg.toOID(), null);
+
+ digestAlgs.addElement(ai);
+ }
+ SignedData signedData = new SignedData(digestAlgs,
+ enContentInfo, certs, null, signInfos);
+
+ ContentInfo contentInfo = new ContentInfo(signedData);
+ CMS.debug("CMCOutputTemplate::getContentInfo() - done");
+ return contentInfo;
+ } catch (Exception e) {
+ CMS.debug("CMCOutputTemplate: Failed to create CMCContentInfo. Exception: "+e.toString());
+ }
+ return null;
+ }
+
+ public void createSimpleResponse(HttpServletResponse resp, IRequest []reqs) {
+ SET certs = new SET();
+ SessionContext context = SessionContext.getContext();
+ try {
+ TaggedAttribute attr =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
+ processGetCertControl(attr, certs);
+ } catch (Exception e) {
+ CMS.debug("CMCOutputTemplate: No certificate is found.");
+ }
+
+ SET digestAlgorithms = new SET();
+ SET signedInfos = new SET();
+
+ // oid for id-data
+ OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.1");
+ EncapsulatedContentInfo enContentInfo = new EncapsulatedContentInfo(oid, null);
+
+ try {
+ if (reqs != null) {
+ for (int i=0; i<reqs.length; i++) {
+ X509CertImpl impl =
+ (reqs[i].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT));
+ byte[] bin = impl.getEncoded();
+ Certificate.Template certTemplate = new Certificate.Template();
+ Certificate cert =
+ (Certificate)certTemplate.decode(new ByteArrayInputStream(bin));
+
+ certs.addElement(cert);
+ }
+
+ // Get CA certs
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ CertificateChain certchains = ca.getCACertChain();
+ java.security.cert.X509Certificate[] chains = certchains.getChain();
+
+ for (int i=0; i<chains.length; i++) {
+ Certificate.Template certTemplate = new Certificate.Template();
+ Certificate cert = (Certificate)certTemplate.decode(
+ new ByteArrayInputStream(chains[i].getEncoded()));
+ certs.addElement(cert);
+ }
+ }
+
+ if (certs.size() == 0)
+ return;
+ SignedData signedData = new SignedData(digestAlgorithms,
+ enContentInfo, certs, null, signedInfos);
+
+ ContentInfo contentInfo = new ContentInfo(signedData);
+ ByteArrayOutputStream fos = new ByteArrayOutputStream();
+ contentInfo.encode(fos);
+ fos.close();
+ byte[] contentBytes = fos.toByteArray();
+
+ resp.setContentType("application/pkcs7-mime");
+ resp.setContentLength(contentBytes.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(contentBytes);
+ os.flush();
+ } catch (java.security.cert.CertificateEncodingException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ } catch (InvalidBERException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ } catch (IOException e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ }
+ }
+
+ private int processConfirmCertAcceptanceControl(
+ TaggedAttribute attr, SEQUENCE controlSeq, int bpid) {
+ if (attr != null) {
+ INTEGER bodyId = attr.getBodyPartID();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(bodyId);
+ SET values = attr.getValues();
+ if (values != null && values.size() > 0) {
+ try {
+ CMCCertId cmcCertId =
+ (CMCCertId)(ASN1Util.decode(CMCCertId.getTemplate(),
+ ASN1Util.encode(values.elementAt(0))));
+ BigInteger serialno = (BigInteger)(cmcCertId.getSerial());
+ SEQUENCE issuers = cmcCertId.getIssuer();
+ //ANY issuer = (ANY)issuers.elementAt(0);
+ ANY issuer =
+ (ANY)(ASN1Util.decode(ANY.getTemplate(),
+ ASN1Util.encode(issuers.elementAt(0))));
+ byte[] b = issuer.getEncoded();
+ X500Name n = new X500Name(b);
+ ICertificateAuthority ca = null;
+ ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ X500Name caName = ca.getX500Name();
+ boolean confirmAccepted = false;
+ if (n.toString().equalsIgnoreCase(caName.toString())) {
+ CMS.debug("CMCOutputTemplate: Issuer names are equal");
+ ICertificateRepository repository =
+ (ICertificateRepository)ca.getCertificateRepository();
+ X509CertImpl impl = null;
+ try {
+ repository.getX509Certificate(serialno);
+ } catch (EBaseException ee) {
+ CMS.debug("CMCOutputTemplate: Certificate in the confirm acceptance control was not found");
+ }
+ if (impl != null)
+ confirmAccepted = true;
+ }
+ CMCStatusInfo cmcStatusInfo = null;
+ if (confirmAccepted) {
+ CMS.debug("CMCOutputTemplate: Confirm Acceptance received. The certificate exists in the certificate repository.");
+ cmcStatusInfo =
+ new CMCStatusInfo(CMCStatusInfo.SUCCESS, seq,
+ (String)null, null);
+ } else {
+ CMS.debug("CMCOutputTemplate: Confirm Acceptance received. The certificate does not exist in the certificate repository.");
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
+ new INTEGER(OtherInfo.BAD_CERT_ID), null);
+ cmcStatusInfo =
+ new CMCStatusInfo(CMCStatusInfo.FAILED, seq,
+ (String)null, otherInfo);
+ }
+ TaggedAttribute statustagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(statustagattr);
+ } catch (Exception e) {
+ CMS.debug("CMCOutputTemplate exception: "+e.toString());
+ }
+ }
+ }
+ return bpid;
+ }
+
+ private void processGetCertControl(TaggedAttribute attr, SET certs)
+ throws InvalidBERException, java.security.cert.CertificateEncodingException,
+ IOException, EBaseException {
+ if (attr != null) {
+ SET vals = attr.getValues();
+
+ if (vals.size() == 1) {
+ GetCert getCert =
+ (GetCert)(ASN1Util.decode(GetCert.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ BigInteger serialno = (BigInteger)(getCert.getSerialNumber());
+ ANY issuer = (ANY)getCert.getIssuer();
+ byte b[] = issuer.getEncoded();
+ X500Name n = new X500Name(b);
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ X500Name caName = ca.getX500Name();
+ if (!n.toString().equalsIgnoreCase(caName.toString())) {
+ CMS.debug("CMCOutputTemplate: Issuer names are equal in the GetCert Control");
+ throw new EBaseException("Certificate is not found");
+ }
+ ICertificateRepository repository =
+ (ICertificateRepository)ca.getCertificateRepository();
+ X509CertImpl impl = repository.getX509Certificate(serialno);
+ byte[] bin = impl.getEncoded();
+ Certificate.Template certTemplate = new Certificate.Template();
+ Certificate cert =
+ (Certificate)certTemplate.decode(new ByteArrayInputStream(bin));
+ certs.addElement(cert);
+ }
+ }
+ }
+
+ private int processQueryPendingControl(TaggedAttribute attr,
+ SEQUENCE controlSeq, int bpid) {
+ if (attr != null) {
+ SET values = attr.getValues();
+ if (values != null && values.size() > 0) {
+ SEQUENCE pending_bpids = new SEQUENCE();
+ SEQUENCE success_bpids = new SEQUENCE();
+ SEQUENCE failed_bpids = new SEQUENCE();
+ for (int i=0; i<values.size(); i++) {
+ try {
+ INTEGER reqId = (INTEGER)
+ ASN1Util.decode(INTEGER.getTemplate(),
+ ASN1Util.encode(values.elementAt(i)));
+ String requestId = new String(reqId.toByteArray());
+
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ IRequestQueue queue = ca.getRequestQueue();
+ IRequest r = queue.findRequest(new RequestId(requestId));
+ if (r != null) {
+ Integer result = r.getExtDataInInteger(IRequest.RESULT);
+ RequestStatus status = r.getRequestStatus();
+ if (status.equals(RequestStatus.PENDING)) {
+ pending_bpids.addElement(reqId);
+ } else if (status.equals(RequestStatus.APPROVED)) {
+ success_bpids.addElement(reqId);
+ } else if (status.equals(RequestStatus.REJECTED)) {
+ failed_bpids.addElement(reqId);
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ if (pending_bpids.size() > 0) {
+ CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING,
+ pending_bpids, (String)null, null);
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+ if (success_bpids.size() > 0) {
+ CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS,
+ pending_bpids, (String)null, null);
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ if (failed_bpids.size() > 0) {
+ CMCStatusInfo cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED,
+ pending_bpids, (String)null, null);
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ }
+
+ }
+ }
+ return bpid;
+ }
+
+ private int processTransactionControl(TaggedAttribute attr,
+ SEQUENCE controlSeq, int bpid) {
+ if (attr != null) {
+ SET transIds = attr.getValues();
+ if (transIds != null) {
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_transactionId,
+ transIds);
+ controlSeq.addElement(tagattr);
+ }
+ }
+
+ return bpid;
+ }
+
+ private int processSenderNonceControl(TaggedAttribute attr,
+ SEQUENCE controlSeq, int bpid) {
+ if (attr != null) {
+ SET sNonce = attr.getValues();
+ if (sNonce != null) {
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_recipientNonce,
+ sNonce);
+ controlSeq.addElement(tagattr);
+ Date date = new Date();
+ String salt = "lala123"+date.toString();
+ byte[] dig;
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ dig = SHA1Digest.digest(salt.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ dig = salt.getBytes();
+ }
+
+ String b64E = CMS.BtoA(dig);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(b64E.getBytes()));
+ controlSeq.addElement(tagattr);
+ }
+ }
+
+ return bpid;
+ }
+
+ private int processDataReturnControl(TaggedAttribute attr,
+ SEQUENCE controlSeq, int bpid) throws InvalidBERException {
+
+ if (attr != null) {
+ SET vals = attr.getValues();
+
+ if (vals.size() > 0) {
+ OCTET_STRING str =
+ (OCTET_STRING)(ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ TaggedAttribute tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_dataReturn, str);
+ controlSeq.addElement(tagattr);
+ }
+ }
+
+ return bpid;
+ }
+
+ private int processRevokeRequestControl(TaggedAttribute attr,
+ SEQUENCE controlSeq, int bpid) throws InvalidBERException, EBaseException,
+ IOException {
+ boolean revoke = false;
+ SessionContext context = SessionContext.getContext();
+ if (attr != null) {
+ INTEGER attrbpid = attr.getBodyPartID();
+ CMCStatusInfo cmcStatusInfo = null;
+ SET vals = attr.getValues();
+ if (vals.size() > 0) {
+ RevRequest revRequest =
+ (RevRequest)(ASN1Util.decode(new RevRequest.Template(),
+ ASN1Util.encode(vals.elementAt(0))));
+ OCTET_STRING str = revRequest.getSharedSecret();
+ INTEGER pid = attr.getBodyPartID();
+ TaggedAttribute tagattr = null;
+ INTEGER revokeCertSerial = revRequest.getSerialNumber();
+ BigInteger revokeSerial = new BigInteger(revokeCertSerial.toByteArray());
+ if (str == null) {
+ boolean needVerify = true;
+ try {
+ needVerify = CMS.getConfigStore().getBoolean("cmc.revokeCert.verify", true);
+ } catch (Exception e) {
+ }
+
+ if (needVerify) {
+ Integer num1 = (Integer)context.get("numOfOtherMsgs");
+ int num = num1.intValue();
+ for (int i=0; i<num; i++) {
+ OtherMsg data = (OtherMsg)context.get("otherMsg"+i);
+ INTEGER dpid = data.getBodyPartID();
+ if (pid.longValue() == dpid.longValue()) {
+ ANY msgValue = data.getOtherMsgValue();
+ SignedData msgData =
+ (SignedData)msgValue.decodeWith(SignedData.getTemplate());
+ if (!verifyRevRequestSignature(msgData)) {
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+ }
+ }
+ }
+
+ revoke = true;
+ // check shared secret
+ } else {
+ ISharedToken tokenClass = null;
+ boolean sharedSecretFound = true;
+ String name = null;
+ try {
+ name = CMS.getConfigStore().getString("cmc.revokeCert.sharedSecret.class");
+ } catch (EPropertyNotFound e) {
+ CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
+ sharedSecretFound = false;
+ } catch (EBaseException e) {
+ CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
+ sharedSecretFound = false;
+ }
+
+ try {
+ tokenClass = (ISharedToken)Class.forName(name).newInstance();
+ } catch (ClassNotFoundException e) {
+ CMS.debug("EnrollProfile: Failed to find class name: "+name);
+ sharedSecretFound = false;
+ } catch (InstantiationException e) {
+ CMS.debug("EnrollProfile: Failed to instantiate class: "+name);
+ sharedSecretFound = false;
+ } catch (IllegalAccessException e) {
+ CMS.debug("EnrollProfile: Illegal access: "+name);
+ sharedSecretFound = false;
+ }
+
+ if (!sharedSecretFound) {
+ CMS.debug("CMCOutputTemplate: class for shared secret was not found.");
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+
+ byte[] bv = null;
+ String sharedSecret = null;
+ if (tokenClass != null) {
+ sharedSecret = tokenClass.getSharedToken(revokeSerial);
+ }
+
+ if (sharedSecret == null) {
+ CMS.debug("CMCOutputTemplate: class for shared secret was not found.");
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+
+ byte[] strb = str.toByteArray();
+ String clientSC = new String(strb);
+ if (clientSC.equals(sharedSecret)) {
+ CMS.debug("CMCOutputTemplate: Both client and server shared secret are the same, can go ahead to revoke certificate.");
+ revoke = true;
+ } else {
+ CMS.debug("CMCOutputTemplate: Both client and server shared secret are not the same, cant revoke certificate.");
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+ }
+
+ if (revoke) {
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ ICertificateRepository repository = (ICertificateRepository)ca.getCertificateRepository();
+ ICertRecord record = null;
+ try {
+ record = repository.readCertificateRecord(revokeSerial);
+ } catch (EBaseException ee) {
+ CMS.debug("CMCOutputTemplate: Exception: "+ee.toString());
+ }
+
+ if (record == null) {
+ CMS.debug("CMCOutputTemplate: The certificate is not found");
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_CERT_ID), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+
+ if (record.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ CMS.debug("CMCOutputTemplate: The certificate is already revoked.");
+ SEQUENCE success_bpids = new SEQUENCE();
+ success_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS,
+ success_bpids, (String)null, null);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+ X509CertImpl impl = record.getCertificate();
+ X509CertImpl[] impls = new X509CertImpl[1];
+ impls[0] = impl;
+ ENUMERATED n = revRequest.getReason();
+ RevocationReason reason = toRevocationReason(n);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(reason);
+ CRLExtensions entryExtn = new CRLExtensions();
+ GeneralizedTime t = revRequest.getInvalidityDate();
+ InvalidityDateExtension invalidityDateExtn = null;
+ if (t != null) {
+ invalidityDateExtn = new InvalidityDateExtension(t.toDate());
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+
+ RevokedCertImpl revCertImpl = new RevokedCertImpl(impl.getSerialNumber(), CMS.getCurrentDate(), entryExtn);
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[1];
+ revCertImpls[0] = revCertImpl;
+ IRequestQueue queue = ca.getRequestQueue();
+ IRequest revReq = queue.newRequest(IRequest.REVOCATION_REQUEST);
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REVOKED_REASON,
+ Integer.valueOf(reason.toInt()));
+ UTF8String utfstr = revRequest.getComment();
+ if (utfstr != null)
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, utfstr.toString());
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ queue.processRequest(revReq);
+ RequestStatus stat = revReq.getRequestStatus();
+ if (stat == RequestStatus.COMPLETE) {
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+ CMS.debug("CMCOutputTemplate: revReq result = "+result);
+ if (result.equals(IRequest.RES_ERROR)) {
+ CMS.debug("CMCOutputTemplate: revReq exception: " +
+ revReq.getExtDataInString(IRequest.ERROR));
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_REQUEST), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+ }
+
+ ILogger logger = CMS.getLogger();
+ String initiative = AuditFormat.FROMUSER;
+ logger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT, new Object[] {
+ revReq.getRequestId(), initiative, "completed",
+ impl.getSubjectDN(),
+ impl.getSerialNumber().toString(16),
+ reason.toString()});
+ CMS.debug("CMCOutputTemplate: Certificate get revoked.");
+ SEQUENCE success_bpids = new SEQUENCE();
+ success_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS,
+ success_bpids, (String)null, null);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ } else {
+ OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null);
+ SEQUENCE failed_bpids = new SEQUENCE();
+ failed_bpids.addElement(attrbpid);
+ cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String)null, otherInfo);
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
+ controlSeq.addElement(tagattr);
+ return bpid;
+ }
+ }
+ }
+
+ return bpid;
+ }
+
+ private RevocationReason toRevocationReason(ENUMERATED n) {
+ long code = n.getValue();
+ if (code == RevRequest.aACompromise.getValue())
+ return RevocationReason.UNSPECIFIED;
+ else if (code == RevRequest.affiliationChanged.getValue())
+ return RevocationReason.AFFILIATION_CHANGED;
+ else if (code == RevRequest.cACompromise.getValue())
+ return RevocationReason.CA_COMPROMISE;
+ else if (code == RevRequest.certificateHold.getValue())
+ return RevocationReason.CERTIFICATE_HOLD;
+ else if (code == RevRequest.cessationOfOperation.getValue())
+ return RevocationReason.CESSATION_OF_OPERATION;
+ else if (code == RevRequest.keyCompromise.getValue())
+ return RevocationReason.KEY_COMPROMISE;
+ else if (code == RevRequest.privilegeWithdrawn.getValue())
+ return RevocationReason.UNSPECIFIED;
+ else if (code == RevRequest.removeFromCRL.getValue())
+ return RevocationReason.REMOVE_FROM_CRL;
+ else if (code == RevRequest.superseded.getValue())
+ return RevocationReason.SUPERSEDED;
+ else if (code == RevRequest.unspecified.getValue())
+ return RevocationReason.UNSPECIFIED;
+ return RevocationReason.UNSPECIFIED;
+ }
+
+ private boolean verifyRevRequestSignature(SignedData msgData) {
+ try {
+ EncapsulatedContentInfo ci = msgData.getContentInfo();
+ OCTET_STRING content = ci.getContent();
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ TaggedAttribute tattr = (TaggedAttribute)(new TaggedAttribute.Template()).decode(s);
+ SET values = tattr.getValues();
+ RevRequest revRequest = null;
+ if (values != null && values.size() > 0)
+ revRequest =
+ (RevRequest)(ASN1Util.decode(new RevRequest.Template(),
+ ASN1Util.encode(values.elementAt(0))));
+
+ SET dias = msgData.getDigestAlgorithmIdentifiers();
+ int numDig = dias.size();
+ Hashtable digs = new Hashtable();
+ for (int i=0; i<numDig; i++) {
+ AlgorithmIdentifier dai =
+ (AlgorithmIdentifier) dias.elementAt(i);
+ String name =
+ DigestAlgorithm.fromOID(dai.getOID()).toString();
+ MessageDigest md =
+ MessageDigest.getInstance(name);
+ byte[] digest = md.digest(content.toByteArray());
+ digs.put(name, digest);
+ }
+
+ SET sis = msgData.getSignerInfos();
+ int numSis = sis.size();
+ for (int i=0; i<numSis; i++) {
+ org.mozilla.jss.pkix.cms.SignerInfo si =
+ (org.mozilla.jss.pkix.cms.SignerInfo)sis.elementAt(i);
+ String name = si.getDigestAlgorithm().toString();
+ byte[] digest = (byte[]) digs.get(name);
+ if (digest == null) {
+ MessageDigest md = MessageDigest.getInstance(name);
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+ revRequest.encode((OutputStream) ostream);
+ digest = md.digest(ostream.toByteArray());
+ }
+ SignerIdentifier sid = si.getSignerIdentifier();
+ if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
+ org.mozilla.jss.pkix.cms.IssuerAndSerialNumber issuerAndSerialNumber =
+ sid.getIssuerAndSerialNumber();
+ java.security.cert.X509Certificate cert = null;
+ if (msgData.hasCertificates()) {
+ SET certs = msgData.getCertificates();
+ int numCerts = certs.size();
+ for (int j=0; j<numCerts; j++) {
+ org.mozilla.jss.pkix.cert.Certificate certJss =
+ (Certificate) certs.elementAt(j);
+ org.mozilla.jss.pkix.cert.CertificateInfo certI =
+ certJss.getInfo();
+ Name issuer = certI.getIssuer();
+ byte[] issuerB = ASN1Util.encode(issuer);
+ INTEGER sn = certI.getSerialNumber();
+ if (new String(issuerB).equalsIgnoreCase(new String(ASN1Util.encode(issuerAndSerialNumber.getIssuer()))) &&
+ sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString())) {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ certJss.encode(os);
+ cert = new X509CertImpl(os.toByteArray());
+ break;
+ }
+ }
+ }
+
+ if (cert != null) {
+ PublicKey pbKey = cert.getPublicKey();
+ String type = ((X509Key)pbKey).getAlgorithm();
+ PrivateKey.Type kType = PrivateKey.RSA;
+ if (type.equals("DSA"))
+ kType = PrivateKey.DSA;
+ PK11PubKey pubK = PK11PubKey.fromRaw(kType, ((X509Key)pbKey).getKey());
+ si.verify(digest, ci.getContentType(), pubK);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ } catch (Exception e) {
+ CMS.debug("CMCOutputTemplate: verifyRevRequestSignature. Exception: "+e.toString());
+ return false;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSFile.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSFile.java
new file mode 100644
index 000000000..523a1f94b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSFile.java
@@ -0,0 +1,104 @@
+// --- 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.servlet.common;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * CMSFile represents a file from the filesystem cached in memory
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSFile {
+ protected String mAbsPath;
+ protected long mLastModified;
+ protected byte[] mContent;
+ protected long mLastAccess = 0;
+
+ protected ILogger mLogger = CMS.getLogger();
+
+ protected CMSFile() {
+ }
+
+ public CMSFile(File file) throws IOException, EBaseException {
+ mAbsPath = file.getAbsolutePath();
+ mLastModified = file.lastModified();
+ fillContent(file);
+ }
+
+ private void fillContent(File file) throws IOException {
+ int fileSize = (int) file.length();
+
+ mContent = new byte[fileSize];
+ FileInputStream fileIn = new FileInputStream(file);
+ int actualSize = fileIn.read(mContent);
+ fileIn.close();
+
+ if (actualSize != fileSize) {
+ byte[] actualContent = new byte[actualSize];
+
+ System.arraycopy(mContent, 0, actualContent, 0, actualSize);
+ mContent = actualContent;
+ }
+ }
+
+ public String getAbsPath() {
+ return mAbsPath;
+ }
+
+ public byte[] getContent() {
+ return mContent;
+ }
+
+ public long getLastModified() {
+ return mLastModified;
+ }
+
+ public synchronized long getLastAccess() {
+ return mLastAccess;
+ }
+
+ public synchronized void setLastAccess(long lastAccess) {
+ mLastAccess = lastAccess;
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, level, ILogger.S_OTHER, "CMSgateway:" + msg);
+ }
+
+ public String toString() {
+ try {
+ return new String(mContent, "UTF8");
+ } catch (UnsupportedEncodingException e) {
+ return new String(mContent);
+ }
+ }
+
+ public String toString(String enc) throws UnsupportedEncodingException {
+ return new String(mContent, enc);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java
new file mode 100644
index 000000000..4a5b767ef
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java
@@ -0,0 +1,163 @@
+// --- 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.servlet.common;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+
+
+/**
+ * CMSFileLoader - file cache.
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class CMSFileLoader {
+ // default max size
+ public final int MAX_SIZE = 200;
+ // default number of files to clear when max is reached.
+ public final int CLEAR_SIZE = 50;
+ // max size property
+ public final String PROP_MAX_SIZE = "maxSize";
+ // clear size property
+ public final String PROP_CLEAR_SIZE = "clearSize";
+ // property to cache templates only
+ public final String PROP_CACHE_TEMPLATES_ONLY = "cacheTemplatesOnly";
+
+ // hash of files to their content.
+ private Hashtable mLoadedFiles = new Hashtable();
+
+ // max number of files
+ private int mMaxSize = MAX_SIZE;
+
+ // number of files to clear when max is reached.
+ private int mClearSize = CLEAR_SIZE;
+
+ // whether to cache templates and forms only.
+ private boolean mCacheTemplatesOnly = true;
+
+ public CMSFileLoader() {
+ }
+
+ public void init(IConfigStore config) throws EBaseException {
+ mMaxSize = config.getInteger(PROP_MAX_SIZE, MAX_SIZE);
+ mClearSize = config.getInteger(PROP_CLEAR_SIZE, CLEAR_SIZE);
+ mCacheTemplatesOnly =
+ config.getBoolean(PROP_CACHE_TEMPLATES_ONLY, true);
+ }
+
+ // Changed by bskim
+ //public byte[] get(String absPath) throws EBaseException, IOException {
+ // File file = new File(absPath);
+ // return get(file);
+ //}
+ public byte[] get(String absPath, String enc) throws EBaseException, IOException {
+ File file = new File(absPath);
+
+ return get(file, enc);
+ }
+
+ // Change end
+
+ // Changed by bskim
+ //public byte[] get(File file) throws EBaseException, IOException {
+ // CMSFile cmsFile = getCMSFile(file);
+ public byte[] get(File file, String enc) throws EBaseException, IOException {
+ CMSFile cmsFile = getCMSFile(file, enc);
+
+ // Change end
+ return cmsFile.getContent();
+ }
+
+ // Changed by bskim
+ //public CMSFile getCMSFile(File file) throws EBaseException, IOException {
+ public CMSFile getCMSFile(File file, String enc) throws EBaseException, IOException {
+ // Change end
+ String absPath = file.getAbsolutePath();
+ long modified = file.lastModified();
+ CMSFile cmsFile = (CMSFile) mLoadedFiles.get(absPath);
+ long lastModified = (cmsFile == null ? 0 : cmsFile.getLastModified());
+
+ // new file.
+ if (cmsFile == null || modified != lastModified) {
+ // Changed by bskim
+ //cmsFile = updateFile(absPath, file);
+ cmsFile = updateFile(absPath, file, enc);
+ // Change end
+ }
+ cmsFile.setLastAccess(System.currentTimeMillis());
+ return cmsFile;
+ }
+
+ // Changed by bskim
+ //private CMSFile updateFile(String absPath, File file)
+ private CMSFile updateFile(String absPath, File file, String enc)
+ // Change end
+ throws EBaseException, IOException {
+ // clear if cache size exceeded.
+ if (mLoadedFiles.size() >= mMaxSize) {
+ clearSomeFiles();
+ }
+
+ CMSFile cmsFile = null;
+
+ // check if file is a js template or plain template by its first String
+ if (absPath.endsWith(CMSTemplate.SUFFIX)) {
+ // Changed by bskim
+ //cmsFile = new CMSTemplate(file);
+ cmsFile = new CMSTemplate(file, enc);
+ // End of Change
+ } else {
+ cmsFile = new CMSFile(file);
+ }
+ mLoadedFiles.put(absPath, cmsFile); // replace old one if any.
+ return cmsFile;
+ }
+
+ private synchronized void clearSomeFiles() {
+
+ // recheck this in case some other thread has cleared it.
+ if (mLoadedFiles.size() < mMaxSize)
+ return;
+
+ // remove the LRU files.
+ // XXX could be optimized more.
+ Enumeration elements = mLoadedFiles.elements();
+
+ for (int i = mClearSize; i > 0; i--) {
+ long lru = java.lang.Long.MAX_VALUE;
+ CMSFile lruFile = null;
+
+ while (elements.hasMoreElements()) {
+ CMSFile cmsFile = (CMSFile) elements.nextElement();
+
+ if (cmsFile.getLastAccess() < lru) {
+ lruFile = cmsFile;
+ }
+ mLoadedFiles.remove(lruFile.getAbsPath());
+ }
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java
new file mode 100644
index 000000000..486e28276
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java
@@ -0,0 +1,46 @@
+// --- 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.servlet.common;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for cms gateway.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class CMSGWResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /*
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ static final Object[][] contents = {};
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java
new file mode 100644
index 000000000..d05f2cefa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java
@@ -0,0 +1,369 @@
+// --- 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.servlet.common;
+
+
+import java.io.*;
+import java.util.*;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletOutputStream;
+
+import java.security.cert.X509Certificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+
+
+/**
+ * This class is to hold some general method for servlets.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSGateway {
+ public final static String PROP_CMSGATEWAY = "cmsgateway";
+ private final static String PROP_ENABLE_ADMIN_ENROLL = "enableAdminEnroll";
+
+ private final static String PROP_SERVER_XML = "server.xml";
+ public static final String CERT_ATTR =
+ "javax.servlet.request.X509Certificate";
+
+ protected static CMSFileLoader mFileLoader = new CMSFileLoader();
+
+ protected static boolean mEnableFileServing;
+ private static boolean mEnableAdminEnroll = true;
+ private static IConfigStore mConfig = null;
+
+ // system logger.
+ protected static ILogger mLogger = CMS.getLogger();
+
+ static {
+ mEnableFileServing = true;
+ mConfig = CMS.getConfigStore().getSubStore(PROP_CMSGATEWAY);
+ try {
+ mEnableAdminEnroll =
+ mConfig.getBoolean(PROP_ENABLE_ADMIN_ENROLL, false);
+ } catch (EBaseException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_BAD_CONFIG_PARAM"));
+ }
+ }
+
+ public CMSGateway() {
+ }
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ httpReqHash.put(name, req.getParameter(name));
+ }
+
+ String ip = req.getRemoteAddr();
+ if (ip != null)
+ httpReqHash.put("clientHost", ip);
+ return httpReqHash;
+ }
+
+ public static boolean getEnableAdminEnroll() {
+ return mEnableAdminEnroll;
+ }
+
+ public static void setEnableAdminEnroll(boolean enableAdminEnroll)
+ throws EBaseException {
+ IConfigStore mainConfig = CMS.getConfigStore();
+
+ //!!! Is it thread safe? xxxx
+ mEnableAdminEnroll = enableAdminEnroll;
+ mConfig.putBoolean(PROP_ENABLE_ADMIN_ENROLL, enableAdminEnroll);
+ mainConfig.commit(true);
+ }
+
+ public static void disableAdminEnroll() throws EBaseException {
+ setEnableAdminEnroll(false);
+
+ /* need to do this in web.xml and restart ws
+ removeServlet("/ca/adminEnroll", "AdminEnroll");
+ initGateway();
+ */
+ }
+
+ /**
+ * construct a authentication credentials to pass into authentication
+ * manager.
+ */
+ public static AuthCredentials getAuthCreds(
+ IAuthManager authMgr, IArgBlock argBlock, X509Certificate clientCert)
+ throws EBaseException {
+ // get credentials from http parameters.
+ if (authMgr == null)
+ return null;
+ String[] reqCreds = authMgr.getRequiredCreds();
+ AuthCredentials creds = new AuthCredentials();
+
+ if (clientCert instanceof java.security.cert.X509Certificate) {
+ try {
+ clientCert = new netscape.security.x509.X509CertImpl(clientCert.getEncoded());
+ } catch (Exception e) {
+ CMS.debug("CMSGateway: getAuthCreds " + e.toString());
+ }
+ }
+
+ for (int i = 0; i < reqCreds.length; i++) {
+ String reqCred = reqCreds[i];
+
+ if (reqCred.equals(IAuthManager.CRED_SSL_CLIENT_CERT)) {
+ // cert could be null;
+ creds.set(reqCred, new X509Certificate[] { clientCert}
+ );
+ } else {
+ String value = argBlock.getValueAsString(reqCred);
+
+ creds.set(reqCred, value); // value could be null;
+ }
+ }
+
+ creds.set("clientHost", argBlock.getValueAsString("clientHost"));
+ // Inserted by bskim
+ creds.setArgBlock(argBlock);
+ // Insert end
+ return creds;
+ }
+
+ protected final static String AUTHMGR_PARAM = "authenticator";
+
+ public static AuthToken checkAuthManager(
+ HttpServletRequest httpReq, IArgBlock httpParams,
+ X509Certificate cert, String authMgrName)
+ throws EBaseException {
+ IArgBlock httpArgs = httpParams;
+
+ if (httpArgs == null)
+ httpArgs = CMS.createArgBlock(toHashtable(httpReq));
+
+ IAuthSubsystem authSub = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+
+ String authMgr_http = httpArgs.getValueAsString(
+ AUTHMGR_PARAM, null);
+
+ if (authMgr_http != null) {
+ authMgrName = authMgr_http;
+ }
+
+ if (authMgrName == null || authMgrName.length() == 0) {
+ throw new EBaseException(CMS.getLogMessage("BASE_INTERNAL_ERROR_1",
+ CMS.getLogMessage("CMSGW_AUTH_MAN_EXPECTED")));
+ }
+
+ IAuthManager authMgr =
+ authSub.getAuthManager(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID);
+
+ authMgr = authSub.getAuthManager(authMgrName);
+ if (authMgr == null)
+ return null;
+ IAuthCredentials creds =
+ getAuthCreds(authMgr, CMS.createArgBlock(toHashtable(httpReq)), cert);
+ AuthToken authToken = null;
+
+ try {
+ authToken = (AuthToken) authMgr.authenticate(creds);
+ } catch (EBaseException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("CMSGateway: " + e);
+ // catch all errors from authentication manager.
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_AUTH_ERROR_2",
+ e.toString(), e.getMessage()));
+ }
+ return authToken;
+ }
+
+ public static void renderTemplate(
+ String templateName,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ ServletConfig servletConfig,
+ CMSFileLoader fileLoader)
+ throws EBaseException, IOException {
+ CMSTemplate template =
+ getTemplate(templateName, req,
+ servletConfig, fileLoader, new Locale[1]);
+ ServletOutputStream out = resp.getOutputStream();
+
+ template.renderOutput(out, new CMSTemplateParams(null, null));
+ }
+
+ // XXX TBD move this to a utility function too.
+
+ public static Locale getLocale(String lang) {
+ int dash = lang.indexOf('-');
+
+ if (dash == -1)
+ return new Locale(lang, "");
+ else
+ return new Locale(lang.substring(0, dash), lang.substring(dash + 1));
+ }
+
+ /**
+ * @param req http servlet request
+ * @param realpathFile the file to get.
+ * @param locale array of at least one to be filled with locale found.
+ */
+ public static File getLangFile(
+ HttpServletRequest req, File realpathFile, Locale[] locale)
+ throws IOException {
+ File file = null;
+ String acceptLang = req.getHeader("accept-language");
+
+ if (acceptLang != null && !acceptLang.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(acceptLang, ",");
+ int numLangs = tokenizer.countTokens();
+
+ if (numLangs > 0) {
+ // languages are searched in order.
+ String parent = realpathFile.getParent();
+
+ if (parent == null) {
+ parent = "." + File.separatorChar;
+ }
+ String name = realpathFile.getName();
+
+ if (name == null) { // filename should never be null.
+ throw new IOException("file has no name");
+ }
+ int i;
+
+ for (i = 0; i < numLangs; i++) {
+ String lang = null;
+ String token = tokenizer.nextToken();
+
+ int semicolon = token.indexOf(';');
+
+ if (semicolon == -1) {
+ lang = token.trim();
+ } else {
+ if (semicolon < 2)
+ continue; // protocol error.
+ lang = token.substring(0, semicolon).trim();
+ }
+ // if browser locale is the same as default locale,
+ // use the default form. (is this the right thing to do ?)
+ Locale l = getLocale(lang);
+
+ if (Locale.getDefault().equals(l)) {
+ locale[0] = l;
+ file = realpathFile;
+ break;
+ }
+
+ String langfilepath =
+ parent + File.separatorChar +
+ lang + File.separatorChar + name;
+
+ file = new File(langfilepath);
+ if (file.exists()) {
+ locale[0] = getLocale(lang);
+ break;
+ }
+ }
+ // if no file for lang was found use default
+ if (i == numLangs) {
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ }
+ } else {
+ // use default if accept-language is not availabe
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ return file;
+ }
+
+ /**
+ * get a template
+ */
+ protected static CMSTemplate getTemplate(
+ String templateName,
+ HttpServletRequest httpReq,
+ ServletConfig servletConfig,
+ CMSFileLoader fileLoader,
+ Locale[] locale)
+ throws EBaseException, IOException {
+ // this converts to system dependent file seperator char.
+ if (servletConfig == null) {
+ CMS.debug( "CMSGateway:getTemplate() - servletConfig is null!" );
+ return null;
+ }
+ if (servletConfig.getServletContext() == null) {
+ }
+ if (templateName == null) {
+ }
+ String realpath =
+ servletConfig.getServletContext().getRealPath("/" + templateName);
+ File realpathFile = new File(realpath);
+ File templateFile =
+ getLangFile(httpReq, realpathFile, locale);
+ CMSTemplate template =
+ //(CMSTemplate)fileLoader.getCMSFile(templateFile);
+ (CMSTemplate) fileLoader.getCMSFile(templateFile, httpReq.getCharacterEncoding());
+
+ return template;
+ }
+
+ /**
+ * Get the If-Modified-Since header and compare it to the millisecond
+ * epoch value passed in. If there is no header, or there is a problem
+ * parsing the value, or if the file has been modified this will return
+ * true, indicating the file has changed.
+ *
+ * @param lastModified The time value in milliseconds past the epoch to
+ * compare the If-Modified-Since header to.
+ */
+ public static boolean modifiedSince(HttpServletRequest req, long lastModified) {
+ long ifModSinceStr;
+
+ try {
+ ifModSinceStr = req.getDateHeader("If-Modified-Since");
+ }catch (IllegalArgumentException e) {
+ return true;
+ }
+
+ if (ifModSinceStr < 0) {
+ return true;
+ }
+
+ if (ifModSinceStr < lastModified) {
+ return true; // Data must be resent
+ }
+
+ return false; // Data has not been modified
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java
new file mode 100644
index 000000000..0f13f9d74
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java
@@ -0,0 +1,64 @@
+// --- 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.servlet.common;
+
+
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * handy class containing cms templates to load & fill.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSLoadTemplate {
+ public String mPropName;
+ public String mFillerPropName;
+ public String mTemplateName;
+ public ICMSTemplateFiller mFiller;
+
+ public CMSLoadTemplate() {
+ }
+
+ public CMSLoadTemplate(
+ String propName, String fillerPropName,
+ String templateName, ICMSTemplateFiller filler) {
+
+ mPropName = propName;
+ mFillerPropName = fillerPropName;
+ mTemplateName = templateName;
+ mFiller = filler;
+ }
+
+ public String getPropName() {
+ return mPropName;
+ }
+
+ public String getFillerPropName() {
+ return mFillerPropName;
+ }
+
+ public String getTemplateName() {
+ return mTemplateName;
+ }
+
+ public ICMSTemplateFiller getTemplateFiller() {
+ return mFiller;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java
new file mode 100644
index 000000000..61c77287c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java
@@ -0,0 +1,298 @@
+// --- 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.servlet.common;
+
+
+import java.util.Vector;
+import java.util.Hashtable;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletConfig;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.apps.*;
+
+/**
+ * This represents a user request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSRequest {
+ // statuses. the first two are out of band.
+ public static final Integer UNAUTHORIZED = Integer.valueOf(1);
+ public static final Integer SUCCESS = Integer.valueOf(2);
+ public static final Integer PENDING = Integer.valueOf(3);
+ public static final Integer SVC_PENDING = Integer.valueOf(4);
+ public static final Integer REJECTED = Integer.valueOf(5);
+ public static final Integer ERROR = Integer.valueOf(6);
+ public static final Integer EXCEPTION = Integer.valueOf(7); // unexpected error.
+
+ private static final String RESULT = "cmsRequestResult";
+
+ // Reason message for request failure
+ private String reason = null;
+
+ // http parameters - handier than getting directly from http request.
+ private IArgBlock mHttpParams = null;
+
+ // http headers & other info.
+ private HttpServletRequest mHttpReq = null;
+
+ // http response.
+ private HttpServletResponse mHttpResp = null;
+
+ // http servlet config.
+ private ServletConfig mServletConfig = null;
+
+ // http servlet context.
+ private ServletContext mServletContext = null;
+
+ // permanent request in request queue.
+ private IRequest mRequest = null;
+
+ // whether request processed successfully
+ private Integer mStatus = SUCCESS;
+
+ // exception message containing error that occured.
+ // note exception could also be thrown seperately.
+ private String mError = null;
+
+ // any error description.
+ private Vector mErrorDescr = null;
+
+ // any request resulting data;
+ Object mResult = null;
+ Hashtable mResults = new Hashtable();
+
+ /**
+ * Constructor
+ */
+ public CMSRequest() {
+ }
+
+ // set methods use by servlets.
+
+ /**
+ * set the HTTP parameters
+ */
+ public void setHttpParams(IArgBlock httpParams) {
+ mHttpParams = httpParams;
+ }
+
+ /**
+ * set the Request aobject associated with this session
+ */
+ public void setIRequest(IRequest request) {
+ mRequest = request;
+ }
+
+ /**
+ * set the HTTP Request object associated with this session
+ */
+ public void setHttpReq(HttpServletRequest httpReq) {
+ mHttpReq = httpReq;
+ }
+
+ /**
+ * set the HTTP Response object which is used to create the
+ * HTTP response which is sent back to the user
+ */
+ public void setHttpResp(HttpServletResponse httpResp) {
+ mHttpResp = httpResp;
+ }
+
+ /**
+ * set the servlet configuration. The servlet configuration is
+ * read from the WEB-APPS/web.xml file under the &lt;servlet&gt;
+ * XML definition. The parameters are delimited by init-param
+ * param-name/param-value options as described in the servlet
+ * documentation.
+ */
+ public void setServletConfig(ServletConfig servletConfig) {
+ mServletConfig = servletConfig;
+ }
+
+ /*
+ * set the servlet context. the servletcontext has detail
+ * about the currently running request
+ */
+ public void setServletContext(ServletContext servletContext) {
+ mServletContext = servletContext;
+ }
+
+ /**
+ * Set request status.
+ * @param status request status. Allowed values are
+ * UNAUTHORIZED, SUCCESS, REJECTED, PENDING, ERROR, SVC_PENDING
+ * @throws IllegalArgumentException if status is not one of the above values
+ */
+ public void setStatus(Integer status) {
+ if ( !status.equals( UNAUTHORIZED ) &&
+ !status.equals( SUCCESS ) &&
+ !status.equals( REJECTED ) &&
+ !status.equals( PENDING ) &&
+ !status.equals( ERROR ) &&
+ !status.equals( SVC_PENDING ) &&
+ !status.equals( EXCEPTION ) ) {
+ throw new IllegalArgumentException(CMS.getLogMessage("CMSGW_BAD_REQ_STATUS"));
+ }
+ mStatus = status;
+ }
+
+ public void setError(EBaseException error) {
+ mError = error.toString();
+ }
+
+ public void setError(String error) {
+ mError = error;
+ }
+
+ public void setErrorDescription(String descr) {
+ if (mErrorDescr == null)
+ mErrorDescr = new Vector();
+ mErrorDescr.addElement(descr);
+ }
+
+ public void setResult(Object result) {
+ mResult = result;
+ mResults.put(RESULT, result);
+ }
+
+ public void setResult(String name, Object result) {
+ mResults.put(name, result);
+ }
+
+ public IArgBlock getHttpParams() {
+ return mHttpParams;
+ }
+
+ public HttpServletRequest getHttpReq() {
+ return mHttpReq;
+ }
+
+ public HttpServletResponse getHttpResp() {
+ return mHttpResp;
+ }
+
+ public ServletConfig getServletConfig() {
+ return mServletConfig;
+ }
+
+ public ServletContext getServletContext() {
+ return mServletContext;
+ }
+
+ public IRequest getIRequest() {
+ return mRequest;
+ }
+
+ public Integer getStatus() {
+ return mStatus;
+ }
+
+ public String getError() {
+ return mError;
+ }
+
+ public Vector getErrorDescr() {
+ return mErrorDescr;
+ }
+
+ public Object getResult() {
+ return mResult;
+ }
+
+ public Object getResult(String name) {
+ return mResults.get(name);
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ // handy routines for IRequest.
+
+ public void setExtData(String type, String value) {
+ if (mRequest != null) {
+ mRequest.setExtData(type, value);
+ }
+ }
+
+ public String getExtData(String type) {
+ if (mRequest != null) {
+ return mRequest.getExtDataInString(type);
+ } else {
+ return null;
+ }
+ }
+
+ // policy errors; set on rejection or possibly deferral.
+ public Vector getPolicyMessages() {
+ if (mRequest != null) {
+ return mRequest.getExtDataInStringVector(IRequest.ERRORS);
+ }
+ return null;
+ }
+
+ /**
+ * set default CMS status according to IRequest status.
+ */
+ public void setIRequestStatus() throws EBaseException {
+ if (mRequest == null) {
+ EBaseException e =
+ new ECMSGWException(CMS.getLogMessage("CMSGW_MISSING_REQUEST"));
+
+ throw e;
+ }
+
+ RequestStatus status = mRequest.getRequestStatus();
+
+ // completed equivalent to success by default.
+ if (status == RequestStatus.COMPLETE) {
+ mStatus = CMSRequest.SUCCESS;
+ return;
+ }
+ // unexpected resulting request status.
+ if (status == RequestStatus.REJECTED) {
+ mStatus = CMSRequest.REJECTED;
+ return;
+ } // pending or service pending.
+ else if (status == RequestStatus.PENDING) {
+ mStatus = CMSRequest.PENDING;
+ return;
+ } else if (status == RequestStatus.SVC_PENDING) {
+ mStatus = CMSRequest.SVC_PENDING;
+ return;
+ } else {
+ RequestId reqId = mRequest.getRequestId();
+
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_UNEXPECTED_REQUEST_STATUS_2",
+ status.toString(), reqId.toString()));
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java
new file mode 100644
index 000000000..ef250ebf9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java
@@ -0,0 +1,596 @@
+// --- 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.servlet.common;
+
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * File templates. This implementation will take
+ * an HTML file with a special customer tag
+ * &lt;CMS_TEMPLATE&gt; and replace the tag with
+ * a series of javascript variable definitions
+ * (depending on the servlet)
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSTemplate extends CMSFile {
+
+ public static final String SUFFIX = ".template";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ /* private variables */
+ private String mTemplateFileName = "";
+ private ILogger mLogger = CMS.getLogger();
+ private long mTimeStamp;
+
+ /* public vaiables */
+ public String mPreOutput;
+ public String mPostOutput;
+ public static final String TEMPLATE_TAG = "<CMS_TEMPLATE>";
+
+ /* Character set for i18n */
+
+ /* Will be set by CMSServlet.getTemplate() */
+ private String mCharset = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Constructor
+ * @param file template file to load
+ * @param charset character set
+ * @throws IOException if the there was an error opening the file
+ */
+ public CMSTemplate(File file, String charset) throws IOException, EBaseException {
+ mCharset = charset;
+ mAbsPath = file.getAbsolutePath();
+ mLastModified = file.lastModified();
+ try {
+ init(file);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_LOAD_TEMPLATE", mAbsPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_LOADING_TEMPLATE"));
+ }
+ String content = mPreOutput + mPostOutput;
+
+ mContent = content.getBytes(mCharset);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /* *
+ * Load the form from the file and setup the
+ * pre/post output buffer if it is a template
+ * file. Otherwise, only post output buffer is
+ * filled.
+ * @param template the template file to load
+ * @return true if successful
+ */
+ public boolean init(File template) throws EBaseException, IOException {
+ StringBuffer buf = new StringBuffer();
+
+ /* load template */
+ String content = loadFile(template);
+
+ if (content == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_TEMPLATE_EMPTY", mAbsPath));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_TEMPLATE_NO_CONTENT_1", mAbsPath));
+ }
+
+ /* time stamp */
+ Date now = CMS.getCurrentDate();
+
+ mTimeStamp = now.getTime();
+
+ /* if template file, find template tag substring and set
+ * pre/post output string
+ */
+ int location = content.indexOf(TEMPLATE_TAG);
+
+ if (location == -1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage(
+ "CMSGW_TEMPLATE_MISSING", mAbsPath, TEMPLATE_TAG));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_MISSING_TEMPLATE_TAG_2",
+ TEMPLATE_TAG, mAbsPath));
+ }
+ mPreOutput = content.substring(0, location);
+ mPostOutput = content.substring(TEMPLATE_TAG.length() + location);
+
+ return true;
+ }
+
+ /**
+ * Write a javascript representation of 'input'
+ * surrounded by SCRIPT tags to the outputstream
+ * @param rout the outputstream to write to
+ * @param input the parameters to write
+ */
+ public void renderOutput(OutputStream rout, CMSTemplateParams input)
+ throws IOException {
+ Enumeration e = null, q = null;
+ IArgBlock r = null;
+ boolean headerBlock = false, fixedBlock = false, queryBlock = false;
+ CMSTemplateParams data = (CMSTemplateParams) input;
+ HTTPOutputStreamWriter http_out = null;
+
+ if (mCharset == null)
+ http_out = new HTTPOutputStreamWriter(rout);
+ else
+ http_out = new HTTPOutputStreamWriter(rout, mCharset);
+
+ try {
+ templateLine out = new templateLine();
+
+ // Output the prolog
+ out.print(mPreOutput);
+
+ // Output the header data
+ out.println("<SCRIPT LANGUAGE=\"JavaScript\">");
+ out.println("var header = new Object();");
+ out.println("var fixed = new Object();");
+ out.println("var recordSet = new Array;");
+ out.println("var result = new Object();");
+
+ // hack
+ out.println("var httpParamsCount = 0;");
+ out.println("var httpHeadersCount = 0;");
+ out.println("var authTokenCount = 0;");
+ out.println("var serverAttrsCount = 0;");
+ out.println("header.HTTP_PARAMS = new Array;");
+ out.println("header.HTTP_HEADERS = new Array;");
+ out.println("header.AUTH_TOKEN = new Array;");
+ out.println("header.SERVER_ATTRS = new Array;");
+
+ r = data.getHeader();
+ if (r != null) {
+ e = r.elements();
+ while (e.hasMoreElements()) {
+ headerBlock = true;
+ String n = (String) e.nextElement();
+ Object v = r.getValue(n);
+
+ out.println("header." + n + " = " + renderValue(v) + ";");
+ }
+ }
+
+ // Output the fixed data
+ r = data.getFixed();
+ if (r != null) {
+ e = r.elements();
+ while (e.hasMoreElements()) {
+ fixedBlock = true;
+ String n = (String) e.nextElement();
+ Object v = r.getValue(n);
+
+ out.println("fixed." + n + " = " + renderValue(v) + ";");
+ }
+ }
+
+ // Output the query data
+ q = data.queryRecords();
+ if (q != null && q.hasMoreElements()) {
+ queryBlock = true;
+ out.println("var recordCount = 0;");
+ out.println("var record;");
+ while (q.hasMoreElements()) {
+ out.println("record = new Object;");
+ out.println("record.HTTP_PARAMS = new Array;");
+ out.println("record.HTTP_HEADERS = new Array;");
+ out.println("record.AUTH_TOKEN = new Array;");
+ out.println("record.SERVER_ATTRS = new Array;");
+
+ // Get a query record
+ r = (IArgBlock) q.nextElement();
+ e = r.elements();
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ Object v = r.getValue(n);
+
+ out.println("record." + n + "=" + renderValue(v) + ";");
+ }
+ out.println("recordSet[recordCount++] = record;");
+ }
+ out.println("record.recordSet = recordSet;");
+ }
+
+ //if (headerBlock)
+ out.println("result.header = header;");
+ //if (fixedBlock)
+ out.println("result.fixed = fixed;");
+ //if (queryBlock)
+ out.println("result.recordSet = recordSet;");
+ out.println("</SCRIPT>");
+ out.println(mPostOutput);
+ http_out.print(out.toString());
+
+ } catch (EBaseException ex) {
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Ouput the pre-amble HTML Header including
+ * the pre-output buffer.
+ *
+ * @param out output stream specified
+ * @return success or error
+ */
+ public boolean outputProlog(PrintWriter out) {
+
+ //Debug.trace("FormCache:outputProlog");
+
+ /* output pre-output buffer */
+ out.print(mPreOutput);
+
+ /* output JavaScript variables and objects */
+ out.println("<SCRIPT LANGUAGE=\"JavaScript\">");
+ out.println("var header = new Object();");
+ out.println("var result = new Object();");
+
+ return true;
+ }
+
+ /**
+ * Output the post HTML tags and post-output
+ * buffer.
+ *
+ * @param out output stream specified
+ * @return success or error
+ */
+ public boolean outputEpilog(PrintWriter out) {
+
+ out.println("</SCRIPT>");
+ out.println(mPostOutput);
+
+ return true;
+ }
+
+ /**
+ * @return full path of template
+ */
+ public String getTemplateName() {
+ return mAbsPath;
+ }
+
+ // inherit getabspath, getContent, get last access and set last access
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /* load file into string */
+ private String loadFile(File template) throws IOException {
+
+ // Debug.trace("FormCache:loadFile");
+
+ /* create input stream, can throw IOException */
+ FileInputStream inStream = new FileInputStream(template);
+ InputStreamReader inReader = new InputStreamReader(inStream, mCharset);;
+ BufferedReader in = new BufferedReader(inReader);
+ StringBuffer buf = new StringBuffer();
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ buf.append(line);
+ buf.append('\n');
+ }
+ try {
+ in.close();
+ inStream.close();
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERR_CLOSE_TEMPL_FILE", mAbsPath, e.getMessage()));
+ }
+ return buf.toString();
+ }
+
+ private String renderValue(Object v) {
+ String s = null;
+
+ // Figure out the type of object
+ if (v instanceof IRawJS) {
+ s = v.toString();
+ } else if (v instanceof String) {
+ if (v.equals(""))
+ s = "null";
+ else
+ s = "\"" + escapeJavaScriptString((String) v) + "\"";
+ } else if (v instanceof Integer) {
+ s = ((Integer) v).toString();
+ } else if (v instanceof Boolean) {
+
+ if (((Boolean) v).booleanValue() == true) {
+ s = "true";
+ } else {
+ s = "false";
+ }
+ } else if (v instanceof BigInteger) {
+ s = ((BigInteger) v).toString(10);
+ } else if (v instanceof Character &&
+ ((Character) v).equals(Character.valueOf((char) 0))) {
+ s = "null";
+ } else {
+ s = "\"" + v.toString() + "\"";
+ }
+
+ return s;
+ }
+
+ /**
+ * Escape the contents of src string in preparation to be enclosed in
+ * double quotes as a JavaScript String Literal within an <script>
+ * portion of an HTML document.
+ * stevep - performance improvements - about 4 times faster than before.
+ */
+ public static String escapeJavaScriptString(String v) {
+ int l = v.length();
+ char in[] = new char[l];
+ char out[] = new char[l * 4];
+ int j = 0;
+
+ v.getChars(0, l, in, 0);
+
+ for (int i = 0; i < l; i++) {
+ char c = in[i];
+
+ if ((c > 0x23) && (c!= 0x5c) && (c!= 0x3c) && (c!= 0x3e)) {
+ out[j++] = c;
+ continue;
+ }
+
+ if ((c == 0x5c) && ((i+1)<l) && (in[i+1] == 'n' ||
+ in[i+1] == 'n' || in[i+1] == 'f' || in[i+1] == 't' ||
+ in[i+1] == '\"' || in[i+1] == '\'' || in[i+1] == '\\')) {
+ out[j++] = '\\';
+ out[j++] = in[i+1];
+ i++;
+ continue;
+ }
+
+ switch (c) {
+ case '\n':
+ out[j++] = '\\';
+ out[j++] = 'n';
+ break;
+
+ case '\\':
+ out[j++] = '\\';
+ out[j++] = '\\';
+ break;
+
+ case '\"':
+ out[j++] = '\\';
+ out[j++] = '\"';
+ break;
+
+ case '\r':
+ out[j++] = '\\';
+ out[j++] = 'r';
+ break;
+
+ case '\f':
+ out[j++] = '\\';
+ out[j++] = 'f';
+ break;
+
+ case '\t':
+ out[j++] = '\\';
+ out[j++] = 't';
+ break;
+
+ case '<':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'c';
+ break;
+
+ case '>':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'e';
+ break;
+
+ default:
+ out[j++] = c;
+ }
+ }
+ return new String(out, 0, j);
+ }
+
+ /**
+ * Like escapeJavaScriptString(String s) but also escape '[' for
+ * HTML processing.
+ */
+ public static String escapeJavaScriptStringHTML(String v) {
+ int l = v.length();
+ char in[] = new char[l];
+ char out[] = new char[l * 4];
+ int j = 0;
+
+ v.getChars(0, l, in, 0);
+
+ for (int i = 0; i < l; i++) {
+ char c = in[i];
+
+ if (c > 0x5B) {
+ out[j++] = c;
+ continue;
+ }
+
+ if ((c == 0x5c) && ((i+1)<l) && (in[i+1] == 'n' ||
+ in[i+1] == 'n' || in[i+1] == 'f' || in[i+1] == 't')) {
+ out[j++] = '\\';
+ out[j++] = in[i+1];
+ i++;
+ continue;
+ }
+
+ switch (c) {
+ case '\n':
+ out[j++] = '\\';
+ out[j++] = 'n';
+ break;
+
+ case '\\':
+ out[j++] = '\\';
+ out[j++] = '\\';
+ break;
+
+ case '\"':
+ out[j++] = '\\';
+ out[j++] = '\"';
+ break;
+
+ case '\r':
+ out[j++] = '\\';
+ out[j++] = 'r';
+ break;
+
+ case '\f':
+ out[j++] = '\\';
+ out[j++] = 'f';
+ break;
+
+ case '\t':
+ out[j++] = '\\';
+ out[j++] = 't';
+ break;
+
+ case '<':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'c';
+ break;
+ case '>':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'e';
+ break;
+
+ default:
+ out[j++] = c;
+ }
+ }
+ return new String(out, 0, j);
+ }
+
+ /**
+ * for debugging, return contents that would've been outputed.
+ */
+ public String getOutput(CMSTemplateParams input)
+ throws IOException {
+ debugOutputStream out = new debugOutputStream();
+
+ renderOutput(out, input);
+ return out.toString();
+ }
+
+ private
+ class HTTPOutputStreamWriter extends OutputStreamWriter {
+ public HTTPOutputStreamWriter(OutputStream out)
+ throws UnsupportedEncodingException {
+ super(out);
+ }
+
+ public HTTPOutputStreamWriter(OutputStream out, String enc)
+ throws UnsupportedEncodingException {
+ super(out, enc);
+ }
+
+ public void print(String s) throws IOException {
+ write(s, 0, s.length());
+ flush();
+ return;
+ }
+
+ public void println(String s) throws IOException {
+ print(s);
+ write('\n');
+ flush();
+ return;
+ }
+ }
+
+
+ private class templateLine {
+ private StringBuffer s = new StringBuffer();
+ void templateLine() {
+ }
+
+ void println(String p) {
+ s.append('\n');
+ s.append(p);
+ }
+
+ void print(String p) {
+ s.append(p);
+ }
+
+ public String toString() {
+ return s.toString();
+ }
+
+ }
+
+
+ private static class debugOutputStream extends ServletOutputStream {
+ private StringWriter mStringWriter = new StringWriter();
+
+ public debugOutputStream() {
+ super();
+ }
+
+ public void write(int b) throws IOException {
+ mStringWriter.write(b);
+ }
+
+ public String toString() {
+ return mStringWriter.toString();
+ }
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java b/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java
new file mode 100644
index 000000000..d64e21755
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java
@@ -0,0 +1,73 @@
+// --- 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.servlet.common;
+
+
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Holds template parameters
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSTemplateParams {
+ private IArgBlock mHeader = null;
+ private IArgBlock mFixed = null;
+ private Vector mRepeat = new Vector();
+
+ public CMSTemplateParams() {
+ }
+
+ public CMSTemplateParams(IArgBlock header, IArgBlock fixed) {
+ mHeader = header;
+ mFixed = fixed;
+ }
+
+ public void setHeader(IArgBlock h) {
+ mHeader = h;
+ }
+
+ public IArgBlock getHeader() {
+ return mHeader;
+ }
+
+ public void setFixed(IArgBlock f) {
+ mFixed = f;
+ }
+
+ public IArgBlock getFixed() {
+ return mFixed;
+ }
+
+ public void addRepeatRecord(IArgBlock r) {
+ mRepeat.addElement(r);
+ }
+
+ public void clearRepeatRecords() {
+ mRepeat = new Vector();
+ }
+
+ public Enumeration queryRecords() {
+ return mRepeat.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java b/pki/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java
new file mode 100644
index 000000000..eda5a6dc2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java
@@ -0,0 +1,74 @@
+// --- 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.servlet.common;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A class represents a CMS gateway exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ECMSGWException extends EBaseException {
+
+ /**
+ * CA resource class name.
+ */
+ private static final String CMSGW_RESOURCES = CMSGWResources.class.getName();
+
+ /**
+ * Constructs a CMS Gateway exception.
+ * <P>
+ */
+ public ECMSGWException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a CMSGW exception.
+ * <P>
+ */
+ public ECMSGWException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a CMSGW exception.
+ * <P>
+ */
+ public ECMSGWException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a CMSGW exception.
+ * <P>
+ */
+ public ECMSGWException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ protected String getBundleName() {
+ return CMSGW_RESOURCES;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java
new file mode 100644
index 000000000..a9db8ec6d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java
@@ -0,0 +1,102 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import java.util.Vector;
+import java.util.Enumeration;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Default error template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenErrorTemplateFiller implements ICMSTemplateFiller {
+ public GenErrorTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq the CMS Request.
+ * @param authority the authority
+ * @param locale the locale of template.
+ * @param e unexpected error. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // request status if any.
+ if (cmsReq != null) {
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+ } else {
+ CMS.debug( "GenErrorTemplateFiller::getTemplateParams() - " +
+ "cmsReq is null!" );
+ return null;
+ }
+
+ // error
+ String ex = cmsReq.getError();
+
+ // Changed by beomsuk
+ /*if (ex == null)
+ ex = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR"));
+ fixed.set(ICMSTemplateFiller.ERROR, ex.toString(locale));
+ */
+ if ((ex == null) && (cmsReq.getReason() == null))
+ ex = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR")).toString();
+ else if (ex != null)
+ fixed.set(ICMSTemplateFiller.ERROR, ex);
+ else if (cmsReq.getReason() != null)
+ fixed.set(ICMSTemplateFiller.ERROR, cmsReq.getReason());
+ // Change end
+
+ // error description if any.
+ Vector descr = cmsReq.getErrorDescr();
+
+ if (descr != null) {
+ Enumeration num = descr.elements();
+
+ while (num.hasMoreElements()) {
+ String elem = (String) num.nextElement();
+ //System.out.println("Setting description "+elem.toString());
+ IArgBlock argBlock = CMS.createArgBlock();
+
+ argBlock.set(ICMSTemplateFiller.ERROR_DESCR,
+ elem);
+ params.addRepeatRecord(argBlock);
+ }
+ }
+
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
new file mode 100644
index 000000000..4157b320a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
@@ -0,0 +1,270 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import java.util.Date;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import netscape.security.x509.*;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cert.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.asn1.*;
+import java.io.*;
+import java.security.*;
+
+
+/**
+ * default Pending template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenPendingTemplateFiller implements ICMSTemplateFiller {
+ public static String FULL_RESPONSE = "cmcFullEnrollmentResponse";
+
+ public GenPendingTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ if( cmsReq == null ) {
+ return null;
+ }
+
+ // request status if any.
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+
+ // request id
+ IRequest req = cmsReq.getIRequest();
+
+ if (req != null) {
+ RequestId reqId = req.getRequestId();
+
+ fixed.set(ICMSTemplateFiller.REQUEST_ID, reqId);
+ // set pendInfo, CMCStatusInfo
+ IArgBlock httpParams = cmsReq.getHttpParams();
+
+ if (doFullResponse(httpParams)) {
+ SEQUENCE controlSeq = new SEQUENCE();
+ int bpid = 1;
+ PendInfo pendInfo = new PendInfo(reqId.toString(), new
+ Date());
+ OtherInfo otherInfo = new
+ OtherInfo(OtherInfo.PEND, null, pendInfo);
+ SEQUENCE bpids = new SEQUENCE();
+ String[] reqIdArray =
+ req.getExtDataInStringArray(IRequest.CMC_REQIDS);
+
+ for (int i = 0; i < reqIdArray.length; i++) {
+ bpids.addElement(new INTEGER(reqIdArray[i]));
+ }
+ CMCStatusInfo cmcStatusInfo = new
+ CMCStatusInfo(CMCStatusInfo.PENDING, bpids,
+ (String) null, otherInfo);
+ TaggedAttribute ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo,
+ cmcStatusInfo);
+
+ controlSeq.addElement(ta);
+ // copy transactionID, senderNonce,
+ // create recipientNonce
+ // create responseInfo if regInfo exist
+ String[] transIds =
+ req.getExtDataInStringArray(IRequest.CMC_TRANSID);
+ SET ids = new SET();
+
+ for (int i = 0; i < transIds.length; i++) {
+ ids.addElement(new INTEGER(transIds[i]));
+ }
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_transactionId,
+ ids);
+ controlSeq.addElement(ta);
+
+ String[] senderNonce = req.getExtDataInStringArray(IRequest.CMC_SENDERNONCE);
+ SET nonces = new SET();
+
+ for (int i = 0; i < senderNonce.length; i++) {
+ nonces.addElement(new OCTET_STRING(senderNonce[i].getBytes()));
+ }
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_recipientNonce,
+ nonces);
+ controlSeq.addElement(ta);
+ req.setExtData(IRequest.CMC_RECIPIENTNONCE, senderNonce);
+
+ Date date = CMS.getCurrentDate();
+ String salt = "lala123" + date.toString();
+ byte[] dig;
+
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+
+ dig = SHA1Digest.digest(salt.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ dig = salt.getBytes();
+ }
+ String b64E = CMS.BtoA(dig);
+ String[] newNonce = {b64E};
+
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(newNonce[0].getBytes()));
+ controlSeq.addElement(ta);
+ req.setExtData(IRequest.CMC_SENDERNONCE, newNonce);
+
+ ResponseBody rb = new ResponseBody(controlSeq, new
+ SEQUENCE(), new
+ SEQUENCE());
+ EncapsulatedContentInfo ci = new
+ EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIResponse,
+ rb);
+ org.mozilla.jss.crypto.X509Certificate x509cert = null;
+
+ if (authority instanceof ICertificateAuthority) {
+ x509cert = ((ICertificateAuthority) authority).getCaX509Cert();
+ }else if (authority instanceof IRegistrationAuthority) {
+ x509cert = ((IRegistrationAuthority) authority).getRACert();
+ }
+ if (x509cert == null)
+ return params;
+ try {
+ X509CertImpl cert = new X509CertImpl(x509cert.getEncoded());
+ ByteArrayInputStream issuer1 = new
+ ByteArrayInputStream(((X500Name) cert.getIssuerDN()).getEncoded());
+ Name issuer = (Name) Name.getTemplate().decode(issuer1);
+ IssuerAndSerialNumber ias = new
+ IssuerAndSerialNumber(issuer, new INTEGER(cert.getSerialNumber().toString()));
+ SignerIdentifier si = new
+ SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+
+ // SHA1 is the default digest Alg for now.
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = null;
+ org.mozilla.jss.crypto.PrivateKey privKey = CryptoManager.getInstance().findPrivKeyByCert(x509cert);
+ org.mozilla.jss.crypto.PrivateKey.Type keyType = privKey.getType();
+
+ if( keyType.equals(org.mozilla.jss.crypto.PrivateKey.RSA ) ) {
+ signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ } else if( keyType.equals(org.mozilla.jss.crypto.PrivateKey.DSA ) ) {
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ } else {
+ CMS.debug( "GenPendingTemplateFiller::getTemplateParams() - "
+ + "keyType " + keyType.toString()
+ + " is unsupported!" );
+ return null;
+ }
+
+ MessageDigest SHADigest = null;
+ byte[] digest = null;
+
+ try {
+ SHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg = DigestAlgorithm.SHA1;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ rb.encode((OutputStream) ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException ex) {
+ //log("digest fail");
+ }
+
+ SignerInfo signInfo = new
+ SignerInfo(si, null, null,
+ OBJECT_IDENTIFIER.id_cct_PKIResponse,
+ digest, signAlg,
+ privKey);
+ SET signInfos = new SET();
+
+ signInfos.addElement(signInfo);
+
+ SET digestAlgs = new SET();
+
+ if (digestAlg != null) {
+ AlgorithmIdentifier ai = new
+ AlgorithmIdentifier(digestAlg.toOID(),
+ null);
+
+ digestAlgs.addElement(ai);
+ }
+
+ SignedData fResponse = new
+ SignedData(digestAlgs, ci,
+ null, null, signInfos);
+ ContentInfo fullResponse = new
+ ContentInfo(ContentInfo.SIGNED_DATA, fResponse);
+ ByteArrayOutputStream ostream = new
+ ByteArrayOutputStream();
+
+ fullResponse.encode((OutputStream) ostream);
+ byte[] fr = ostream.toByteArray();
+
+ fixed.set(FULL_RESPONSE, CMS.BtoA(fr));
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+
+ /**
+ * handy routine to check if client want full enrollment response
+ */
+ public static boolean doFullResponse(IArgBlock httpParams) {
+ if (httpParams.getValueAsBoolean("fullResponse", false))
+ return true;
+ else
+ return false;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java
new file mode 100644
index 000000000..3329ce7ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java
@@ -0,0 +1,95 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import java.util.Vector;
+import java.util.Enumeration;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * default Service Pending template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenRejectedTemplateFiller implements ICMSTemplateFiller {
+ public final static String POLICY_MESSAGE = "policyMessage";
+
+ public GenRejectedTemplateFiller() {
+ }
+
+ /**
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // request status if any.
+ if (cmsReq != null) {
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+ } else {
+ CMS.debug( "GenRejectedTemplateFiller::getTemplateParams() - " +
+ "cmsReq is null!" );
+ return null;
+ }
+
+ // request id
+ IRequest req = cmsReq.getIRequest();
+
+ if (req != null) {
+ fixed.set(ICMSTemplateFiller.REQUEST_ID, req.getRequestId());
+
+ // policy errors (rejection reasons)
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+
+ while (msgs.hasMoreElements()) {
+ String ex = (String) msgs.nextElement();
+ IArgBlock messageArgBlock = CMS.createArgBlock();
+
+ messageArgBlock.set(POLICY_MESSAGE, ex);
+ params.addRepeatRecord(messageArgBlock);
+ }
+ }
+ }
+
+ // this authority
+
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java
new file mode 100644
index 000000000..1e0afb328
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java
@@ -0,0 +1,65 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * default Success template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenSuccessTemplateFiller implements ICMSTemplateFiller {
+
+ public GenSuccessTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // request status if any.
+ if (cmsReq != null) {
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+ }
+
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java
new file mode 100644
index 000000000..b3d2c493c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java
@@ -0,0 +1,80 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * default Service Pending template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenSvcPendingTemplateFiller implements ICMSTemplateFiller {
+ public static final String REMOTE_AUTHORITY = "remoteAuthority";
+
+ public GenSvcPendingTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // request status if any.
+ if (cmsReq != null) {
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+
+ // request id
+ IRequest req = cmsReq.getIRequest();
+
+ if (req != null) {
+ fixed.set(ICMSTemplateFiller.REQUEST_ID, req.getRequestId());
+
+ // remote authority we're waiting for
+ String remoteAuthority =
+ req.getExtDataInString(IRequest.REMOTE_SERVICE_AUTHORITY);
+
+ if (remoteAuthority != null)
+ fixed.set(REMOTE_AUTHORITY, remoteAuthority);
+ }
+ }
+
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java
new file mode 100644
index 000000000..eff3b073a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java
@@ -0,0 +1,69 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * default Unauthorized template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenUnauthorizedTemplateFiller implements ICMSTemplateFiller {
+
+ public GenUnauthorizedTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // request status if any.
+ if (cmsReq != null) {
+ Integer sts = cmsReq.getStatus();
+
+ if (sts != null)
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+ }
+
+ // set unauthorized error
+ fixed.set(ICMSTemplateFiller.ERROR,
+ new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")));
+
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java
new file mode 100644
index 000000000..6064880ce
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java
@@ -0,0 +1,78 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.BaseResources;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * default unexpected error template filler
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenUnexpectedErrorTemplateFiller implements ICMSTemplateFiller {
+
+ public GenUnexpectedErrorTemplateFiller() {
+ }
+
+ /**
+ * fill error details and description if any.
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e) {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // When an exception occurs the exit is non-local which probably
+ // will leave the requestStatus value set to something other
+ // than CMSRequest.EXCEPTION, so force the requestStatus to
+ // EXCEPTION since it must be that if we're here.
+ Integer sts = CMSRequest.EXCEPTION;
+ if (cmsReq != null) cmsReq.setStatus(sts);
+ fixed.set(ICMSTemplateFiller.REQUEST_STATUS, sts.toString());
+
+ // the unexpected error (exception)
+ if (e == null)
+ e = new EBaseException(CMS.getLogMessage("BASE_UNKNOWN_ERROR"));
+ String errMsg = null;
+
+ if (e instanceof EBaseException)
+ errMsg = ((EBaseException) e).toString(locale);
+ else
+ errMsg = e.toString();
+ fixed.set(ICMSTemplateFiller.EXCEPTION, errMsg);
+
+ // this authority
+ if (authority != null)
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ authority.getOfficialName());
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java
new file mode 100644
index 000000000..60dd865f0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java
@@ -0,0 +1,50 @@
+// --- 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.servlet.common;
+
+
+import java.util.Locale;
+import com.netscape.certsrv.authority.*;
+
+
+/**
+ * This interface represents a template filler.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface ICMSTemplateFiller {
+ // common template variables.
+ public final static String ERROR = "errorDetails";
+ public final static String ERROR_DESCR = "errorDescription";
+ public final static String EXCEPTION = "unexpectedError";
+
+ public static final String HOST = "host";
+ public static final String PORT = "port";
+ public static final String SCHEME = "scheme";
+
+ public static final String AUTHORITY = "authorityName";
+
+ public static final String REQUEST_STATUS = "requestStatus";
+
+ public static final String KEYREC_ID = "keyrecId";
+ public static final String REQUEST_ID = "requestId";
+
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority mAuthority, Locale locale, Exception e)
+ throws Exception;
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/IRawJS.java b/pki/base/common/src/com/netscape/cms/servlet/common/IRawJS.java
new file mode 100644
index 000000000..27ea5ec1b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/IRawJS.java
@@ -0,0 +1,27 @@
+// --- 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.servlet.common;
+
+
+/**
+ * This represents raw JS parameters.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IRawJS {
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java
new file mode 100644
index 000000000..cd82096a7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java
@@ -0,0 +1,121 @@
+// --- 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.servlet.common;
+
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a certificate server kernel. This
+ * kernel contains a list of resident subsystems such
+ * as logging, security, remote administration. Additional
+ * subsystems can be loaded into this kernel by specifying
+ * parameters in the configuration store.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class IndexTemplateFiller implements ICMSTemplateFiller {
+
+ private final static String INFO = "index";
+
+ // input parameters
+
+ // output parameters
+ private final static String OUT_TYPE = "type";
+ private final static String OUT_ID = "id";
+ private final static String OUT_TOTAL_COUNT = "totalCount";
+ private final static String OUT_ERROR = "errorDetails";
+
+ public IndexTemplateFiller() {
+ }
+
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority mAuthority, Locale locale, Exception e) {
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(header, ctx);
+
+ ISubsystem ca = CMS.getSubsystem("ca");
+ ISubsystem ra = CMS.getSubsystem("ra");
+ ISubsystem kra = CMS.getSubsystem("kra");
+ ISubsystem ocsp = CMS.getSubsystem("ocsp");
+ ISubsystem tks = CMS.getSubsystem("tks");
+
+ IArgBlock rarg = null;
+ int count = 0;
+
+ if (ca != null) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue(OUT_TYPE, "CertificateAuthority");
+ rarg.addStringValue(OUT_ID, "ca");
+ params.addRepeatRecord(rarg);
+ count++;
+ }
+ if (ra != null) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue(OUT_TYPE, "RegistrationAuthority");
+ rarg.addStringValue(OUT_ID, "ra");
+ params.addRepeatRecord(rarg);
+ count++;
+ }
+ if (ocsp != null) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue(OUT_TYPE, "OCSPAuthority");
+ rarg.addStringValue(OUT_ID, "ocsp");
+ params.addRepeatRecord(rarg);
+ count++;
+ }
+ if (kra != null) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue(OUT_TYPE, "KeyRecoveryAuthority");
+ rarg.addStringValue(OUT_ID, "kra");
+ params.addRepeatRecord(rarg);
+ count++;
+ }
+ if (tks != null) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue(OUT_TYPE, "TKSAuthority");
+ rarg.addStringValue(OUT_ID, "tks");
+ params.addRepeatRecord(rarg);
+ count++;
+ }
+ // information about what is selected is provided
+ // from the caller. This parameter (selected) is used
+ // by header servlet
+ try {
+ header.addStringValue("selected",
+ cmsReq.getHttpParams().getValueAsString("selected"));
+ } catch (EBaseException ex) {
+ }
+ header.addIntegerValue(OUT_TOTAL_COUNT, count);
+ return params;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/RawJS.java b/pki/base/common/src/com/netscape/cms/servlet/common/RawJS.java
new file mode 100644
index 000000000..fb31fec1c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/RawJS.java
@@ -0,0 +1,36 @@
+// --- 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.servlet.common;
+
+
+/**
+ * This represents raw JS parameters.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RawJS implements IRawJS {
+ private String mRawJSstr = null;
+
+ public RawJS(String s) {
+ mRawJSstr = s;
+ }
+
+ public String toString() {
+ return mRawJSstr;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/common/Utils.java b/pki/base/common/src/com/netscape/cms/servlet/common/Utils.java
new file mode 100644
index 000000000..9259a2c12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/common/Utils.java
@@ -0,0 +1,106 @@
+// --- 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.servlet.common;
+
+
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Utility class
+ *
+ * @version $Revision$, $Date$
+ */
+public class Utils {
+
+ public final static String AUTHZ_SRC_LDAP = "ldap";
+ public final static String AUTHZ_SRC_TYPE = "sourceType";
+ public final static String AUTHZ_CONFIG_STORE = "authz";
+ public final static String AUTHZ_SRC_XML = "web.xml";
+ public final static String PROP_AUTHZ_MGR = "AuthzMgr";
+ public final static String PROP_ACL = "ACLinfo";
+ public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz";
+ public final static String AUTHZ_MGR_LDAP = "DirAclAuthz";
+
+ public static String initializeAuthz(ServletConfig sc,
+ IAuthzSubsystem authz, String id) throws ServletException {
+ String srcType = AUTHZ_SRC_LDAP;
+
+ try {
+ IConfigStore authzConfig =
+ CMS.getConfigStore().getSubStore(AUTHZ_CONFIG_STORE);
+
+ srcType = authzConfig.getString(AUTHZ_SRC_TYPE, AUTHZ_SRC_LDAP);
+ } catch (EBaseException e) {
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_FAIL_SRC_TYPE"));
+ }
+
+ String aclMethod = null;
+
+ if (srcType.equalsIgnoreCase(AUTHZ_SRC_XML)) {
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_INITED", ""));
+ aclMethod = sc.getInitParameter(PROP_AUTHZ_MGR);
+ if (aclMethod != null &&
+ aclMethod.equalsIgnoreCase(AUTHZ_MGR_BASIC)) {
+ String aclInfo = sc.getInitParameter(PROP_ACL);
+
+ if (aclInfo != null) {
+ try {
+ addACLInfo(authz, aclMethod, aclInfo);
+ } catch (EBaseException ee) {
+ throw new ServletException(
+ "failed to init authz info from xml config file");
+ }
+
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE",
+ id));
+ } else {
+ CMS.debug(CMS.getLogMessage(
+ "ADMIN_SRVLT_PROP_ACL_NOT_SPEC", PROP_ACL, id,
+ AUTHZ_MGR_LDAP));
+ }
+ } else {
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_PROP_ACL_NOT_SPEC",
+ PROP_AUTHZ_MGR, id, AUTHZ_MGR_LDAP));
+ }
+ } else {
+ aclMethod = AUTHZ_MGR_LDAP;
+ CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTH_LDAP_NOT_XML", id));
+ }
+
+ return aclMethod;
+ }
+
+ public static void addACLInfo(IAuthzSubsystem authz, String aclMethod,
+ String aclInfo) throws EBaseException {
+
+ StringTokenizer tokenizer = new StringTokenizer(aclInfo, "#");
+
+ while (tokenizer.hasMoreTokens()) {
+ String acl = (String) tokenizer.nextToken();
+
+ authz.authzMgrAccessInit(aclMethod, acl);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java b/pki/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java
new file mode 100644
index 000000000..0b147c58d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java
@@ -0,0 +1,567 @@
+// --- 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.servlet.connector;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+
+import java.security.cert.*;
+
+import java.io.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.connector.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authentication.AuthCredentials;
+
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Clone servlet - part of the Clone Authority (CLA)
+ * processes Revoked certs from its dependant clone CAs
+ * service request and return status.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CloneServlet extends CMSServlet {
+ public static final String INFO = "Clone Servlet";
+ public final static String PROP_AUTHORITY = "authority";
+ protected ServletConfig mConfig = null;
+ protected IAuthority mAuthority = null;
+ protected IRequestEncoder mReqEncoder = null;
+ protected IAuthSubsystem mAuthSubsystem = null;
+ protected ILogger mLogger = CMS.getLogger();
+
+ public CloneServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mConfig = sc;
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+ mReqEncoder = CMS.getHttpRequestEncoder();
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ }
+
+ public void service(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException, IOException {
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CMS server is not ready to serve.");
+
+ ServletContext servletContext = mConfig.getServletContext();
+
+ CMSRequest cmsRequest = newCMSRequest();
+
+ // set argblock
+ cmsRequest.setHttpParams(CMS.createArgBlock(toHashtable(req)));
+
+ // set http request
+ cmsRequest.setHttpReq(req);
+
+ // set http response
+ cmsRequest.setHttpResp(resp);
+
+ // set servlet config.
+ cmsRequest.setServletConfig(mConfig);
+
+ // set servlet context.
+ cmsRequest.setServletContext(mConfig.getServletContext());
+
+ char[] content = null;
+ String encodedreq = null;
+ String method = null;
+ int len = -1;
+ IPKIMessage msg = null;
+ IPKIMessage replymsg = null;
+ IRequest r = null;
+ IRequest reply = null;
+
+ // NOTE must read all bufer before redoing handshake for
+ // ssl client auth for client auth to work.
+
+ // get request method
+ method = req.getMethod();
+
+ // get content length
+ len = req.getContentLength();
+
+ // get content, a base 64 encoded serialized request.
+ if (len > 0) {
+ InputStream in = req.getInputStream();
+ InputStreamReader inreader = new InputStreamReader(in, "UTF8");
+ BufferedReader reader = new BufferedReader(inreader, len);
+
+ content = new char[len];
+ int done = reader.read(content, 0, len);
+ int total = done;
+
+ while (done >= 0 && total < len) {
+ done = reader.read(content, total, len - total);
+ total += done;
+ }
+ reader.close();
+ encodedreq = new String(content);
+ }
+
+ // force client auth handshake, validate clone CA (CCA)
+ // and get CCA's Id.
+ // NOTE must do this after all contents are read for ssl
+ // redohandshake to work
+
+ X509Certificate peerCert;
+
+ try {
+ peerCert = getPeerCert(req);
+ }catch (EBaseException e) {
+ mAuthority.log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_HAS_NO_CLIENT_CERT"));
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ if (peerCert == null) {
+ // XXX log something here.
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // authenticate clone CA (CCA)
+
+ String CCA_Id = null;
+ String CCAUserId = null;
+ IAuthToken token = null;
+
+ try {
+ // cfu +++ authenticate checks both SUBJECT and Signer SUBJECT
+ CMS.debug("CloneServlet: about to authenticate");
+ token = authenticate(peerCert);
+ // cfu maybe don't need CCA_Id, because the above check
+ // was good enough
+ CCAUserId = token.getInString("userid");
+ CCA_Id = (String) peerCert.getSubjectDN().toString();
+ } catch (EInvalidCredentials e) {
+ // already logged.
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ } catch (EBaseException e) {
+ // already logged.
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ mAuthority.log(ILogger.LL_INFO,
+ "Clone Certificate Authority authenticated: " + peerCert.getSubjectDN());
+
+ // authorize, any authenticated user are authorized
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsRequest.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // after cert validated, check http request.
+ if (!method.equalsIgnoreCase("POST")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+ return;
+ }
+ if (len <= 0) {
+ resp.sendError(HttpServletResponse.SC_LENGTH_REQUIRED);
+ return;
+ }
+
+ // now process CCA request - should just be posting revoked
+ // certs for now
+
+ try {
+ // decode request.
+ CMS.debug("Cloneservlet: before decoding request, encodedreq= " + encodedreq);
+ msg = (IPKIMessage) mReqEncoder.decode(encodedreq);
+ // process request
+ CMS.debug("Cloneservlet: decoded request");
+ replymsg = processRequest(CCA_Id, CCAUserId, msg, token);
+ } catch (IOException e) {
+ e.printStackTrace();
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ } catch (EBaseException e) {
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ // encode reply
+ String encodedrep = mReqEncoder.encode(replymsg);
+
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/html");
+ resp.setContentLength(encodedrep.length());
+
+ // send reply
+ OutputStream out = resp.getOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(out, "UTF8");
+
+ writer.write(encodedrep);
+ writer.flush();
+ writer.close();
+ out.flush();
+ }
+
+ //cfu ++change this to just check the subject and signer
+ protected IAuthToken authenticate(
+ X509Certificate peerCert)
+ throws EBaseException {
+ try {
+ // XXX using agent authentication now since we're only
+ // verifying that the cert belongs to a user in the db.
+ // XXX change this to ACL in the future.
+
+ // build JAVA X509Certificate from peerCert.
+ X509CertImpl cert = new X509CertImpl(peerCert.getEncoded());
+
+ AuthCredentials creds = new AuthCredentials();
+
+ creds.set(IAuthManager.CRED_SSL_CLIENT_CERT,
+ new X509Certificate[] {cert}
+ );
+
+ IAuthToken token = mAuthSubsystem.authenticate(creds,
+ IAuthSubsystem.CERTUSERDB_AUTHMGR_ID);
+
+ return token;
+ } catch (CertificateException e) {
+ mAuthority.log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_REMOTE_AUTHORITY_AUTH_FAILURE", peerCert.getSubjectDN().toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (EInvalidCredentials e) {
+ mAuthority.log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_REMOTE_AUTHORITY_AUTH_FAILURE", peerCert.getSubjectDN().toString()));
+ throw e;
+ } catch (EBaseException e) {
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REMOTE_AUTHORITY_AUTH_FAILURE", peerCert.getSubjectDN().toString()));
+ throw e;
+ }
+ }
+
+ protected IPKIMessage processRequest(
+ String source, String sourceUserId, IPKIMessage msg, IAuthToken token)
+ throws EBaseException {
+ IPKIMessage replymsg = null;
+ IRequest r = null;
+ IRequestQueue queue = mAuthority.getRequestQueue();
+ String srcid = source + ":" + msg.getReqId();
+
+ mAuthority.log(ILogger.LL_INFO, "CFU: in CloneServlet processRequest");
+
+ // find request in request queue and return result.
+ RequestId thisreqid = queue.findRequestBySourceId(srcid);
+ IRequest thisreq = null;
+
+ if (thisreqid != null) {
+ thisreq = queue.findRequest(thisreqid);
+ if (thisreq == null) {
+ // strange case.
+ String errormsg = "Cannot find request in request queue " + thisreqid;
+
+ mAuthority.log(ILogger.LL_FAILURE, errormsg);
+ throw new EBaseException(errormsg);
+ } else {
+ mAuthority.log(ILogger.LL_INFO,
+ "Found request " + thisreqid + " for " + srcid);
+ replymsg = CMS.getHttpPKIMessage();
+ replymsg.fromRequest(thisreq);
+ return replymsg;
+ }
+ }
+
+ // if not found process request.
+ thisreq = queue.newRequest(msg.getReqType());
+ thisreq.setSourceId(srcid);
+ msg.toRequest(thisreq);
+ thisreq.setExtData(IRequest.AUTH_TOKEN, token);
+
+ // setting requestor type must come after copy contents. because
+ // requestor is a regular attribute.
+ thisreq.setExtData(IRequest.REQUESTOR_TYPE,
+ IRequest.REQUESTOR_RA);
+ mAuthority.log(ILogger.LL_INFO, "Processing remote request " + srcid);
+
+ // Set this so that request's updateBy is recorded
+ SessionContext s = SessionContext.getContext();
+
+ if (s.get(SessionContext.USER_ID) == null) {
+ s.put(SessionContext.USER_ID, sourceUserId);
+ }
+
+ queue.processRequest(thisreq);
+ replymsg = CMS.getHttpPKIMessage();
+ replymsg.fromRequest(thisreq);
+
+ //for audit log
+ String agentID = sourceUserId;
+ String initiative = AuditFormat.FROMRA + " trustedManagerID: " +
+ agentID + " remote reqID " + msg.getReqId();
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (token != null) {
+ authMgr =
+ token.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] = thisreq.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ try {
+ if (!thisreq.getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ thisreq.getRequestStatus(),
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ thisreq.getRequestStatus()}
+ );
+ }
+ } else {
+ if
+ (thisreq.getRequestType().equals(IRequest.CLA_CERT4CRL_REQUEST)) {
+ Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ CMS.debug("CloneServlet: error in CLA_CERT4CRL_REQUEST");
+ } else {
+ // the success.
+ CMS.debug("CloneServlet: success in CLA_CERT4CRL_REQUEST");
+ }
+ }
+
+ /* cfu ---
+ if (thisreq.getRequestType().equals(IRequest.ENROLLMENT_REQUEST)) {
+ // XXX make the repeat record.
+ // Get the certificate(s) from the request
+ X509CertImpl issuedCerts[] =
+ (X509CertImpl[])thisreq.get(IRequest.ISSUED_CERTS);
+ // return potentially more than one certificates.
+ if (issuedCerts != null) {
+ for (int i = 0; i < issuedCerts.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId() ,
+ initiative ,
+ authMgr ,
+ "completed",
+ issuedCerts[i].getSubjectDN() ,
+ "cert issued serial number: 0x" +
+ issuedCerts[i].getSerialNumber().toString(16)}
+ );
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId() ,
+ initiative ,
+ authMgr ,
+ "completed"}
+ );
+ }
+ } else if (thisreq.getRequestType().equals(IRequest.RENEWAL_REQUEST)) {
+ X509CertImpl[] certs = (X509CertImpl[])thisreq.get(IRequest.OLD_CERTS);
+ X509CertImpl old_cert = certs[0];
+ certs = (X509CertImpl[])thisreq.get(IRequest.ISSUED_CERTS);
+ X509CertImpl renewed_cert = certs[0];
+ if (old_cert != null && renewed_cert != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative ,
+ authMgr ,
+ "completed",
+ old_cert.getSubjectDN() ,
+ old_cert.getSerialNumber().toString(16) ,
+ "new serial number: 0x" +
+ renewed_cert.getSerialNumber().toString(16)}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId() ,
+ initiative ,
+ authMgr ,
+ "completed with error"}
+ );
+ }
+ } else if (thisreq.getRequestType().equals(IRequest.REVOCATION_REQUEST)) {
+ X509CertImpl[] oldCerts = (X509CertImpl[])thisreq.get(IRequest.OLD_CERTS);
+ RevokedCertImpl crlentries[] =
+ (RevokedCertImpl[])thisreq.get(IRequest.REVOKED_CERTS);
+ CRLExtensions crlExts = crlentries[0].getExtensions();
+ int reason = 0;
+ if (crlExts != null) {
+ Enumeration enum = crlExts.getElements();
+ while(enum.hasMoreElements()){
+ Extension ext = (Extension) enum.nextElement();
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension)ext).getReason().toInt
+ ();
+ break;
+ }
+ }
+ }
+
+ int count = oldCerts.length;
+ Integer result = (Integer)thisreq.get(IRequest.RESULT);
+ if (result.equals(IRequest.RES_ERROR)) {
+ EBaseException ex = (EBaseException)thisreq.get(IRequest.ERROR);
+ EBaseException[] svcErrors =
+ (EBaseException[])thisreq.get(IRequest.SVCERRORS);
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ EBaseException err = svcErrors[i];
+ if (err != null) {
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative ,
+ "completed with error: " +
+ err.toString() ,
+ oldCerts[j].getSubjectDN() ,
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative ,
+ "completed" ,
+ oldCerts[j].getSubjectDN() ,
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId() ,
+ initiative ,
+ authMgr ,
+ "completed"}
+ );
+ }
+ cfu */
+ }
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+
+ return replymsg;
+ }
+
+ protected X509Certificate
+ getPeerCert(HttpServletRequest req) throws EBaseException {
+ return getSSLClientCertificate(req);
+ }
+
+ public String getServletInfo() {
+ return INFO;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/pki/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
new file mode 100644
index 000000000..daf595f81
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -0,0 +1,1092 @@
+// --- 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.servlet.connector;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+//import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import java.io.*;
+import java.util.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.profile.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Connector servlet
+ * process requests from remote authority -
+ * service request or return status.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConnectorServlet extends CMSServlet {
+ public static final String INFO = "Connector Servlet";
+ public final static String PROP_AUTHORITY = "authority";
+ protected ServletConfig mConfig = null;
+ protected IAuthority mAuthority = null;
+ protected IRequestEncoder mReqEncoder = null;
+ protected IAuthSubsystem mAuthSubsystem = null;
+ protected ILogger mLogger = CMS.getLogger();
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String SIGNED_AUDIT_PROTECTION_METHOD_SSL = "ssl";
+ private final static String SIGNED_AUDIT_PROTECTION_METHOD_UNKNOWN =
+ "unknown";
+ private final static String LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS_5";
+ private final static String LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5";
+ private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+
+ public ConnectorServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mConfig = sc;
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+ mReqEncoder = CMS.getHttpRequestEncoder();
+
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ }
+
+ public void service(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CMS server is not ready to serve.");
+
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse resp = (HttpServletResponse) response;
+
+ ServletContext servletContext = mConfig.getServletContext();
+
+ CMSRequest cmsRequest = newCMSRequest();
+
+ // set argblock
+ cmsRequest.setHttpParams(CMS.createArgBlock(toHashtable(request)));
+
+ // set http request
+ cmsRequest.setHttpReq(request);
+
+ // set http response
+ cmsRequest.setHttpResp(response);
+
+ // set servlet config.
+ cmsRequest.setServletConfig(mConfig);
+
+ // set servlet context.
+ cmsRequest.setServletContext(mConfig.getServletContext());
+
+ char[] content = null;
+ String encodedreq = null;
+ String method = null;
+ int len = -1;
+ IPKIMessage msg = null;
+ IPKIMessage replymsg = null;
+ IRequest r = null;
+ IRequest reply = null;
+
+ // NOTE must read all bufer before redoing handshake for
+ // ssl client auth for client auth to work.
+
+ // get request method
+ method = req.getMethod();
+
+ // get content length
+ len = request.getContentLength();
+
+ // get content, a base 64 encoded serialized request.
+ if (len > 0) {
+ InputStream in = request.getInputStream();
+ InputStreamReader inreader = new InputStreamReader(in, "UTF8");
+ BufferedReader reader = new BufferedReader(inreader, len);
+
+ content = new char[len];
+ int done = reader.read(content, 0, len);
+ int total = done;
+
+ while (done >= 0 && total < len) {
+ done = reader.read(content, total, len - total);
+ total += done;
+ }
+ reader.close();
+ encodedreq = new String(content);
+ }
+
+ // force client auth handshake, validate RA and get RA's Id.
+ // NOTE must do this after all contents are read for ssl
+ // redohandshake to work
+
+ X509Certificate peerCert;
+
+ try {
+ peerCert = getPeerCert(req);
+ }catch (EBaseException e) {
+ mAuthority.log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_HAS_NO_CLIENT_CERT"));
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ if (peerCert == null) {
+ // XXX log something here.
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // authenticate RA
+
+ String RA_Id = null;
+ String raUserId = null;
+ IAuthToken token = null;
+
+ try {
+ token = authenticate(request);
+ raUserId = token.getInString("userid");
+ RA_Id = (String) peerCert.getSubjectDN().toString();
+ } catch (EInvalidCredentials e) {
+ // already logged.
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ } catch (EBaseException e) {
+ // already logged.
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ mAuthority.log(ILogger.LL_INFO,
+ "Remote Authority authenticated: " + peerCert.getSubjectDN());
+
+ // authorize
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsRequest.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // after cert validated, check http request.
+ if (!method.equalsIgnoreCase("POST")) {
+ resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+ return;
+ }
+ if (len <= 0) {
+ resp.sendError(HttpServletResponse.SC_LENGTH_REQUIRED);
+ return;
+ }
+
+ // now process request.
+
+ CMS.debug("ConnectorServlet: process request RA_Id=" + RA_Id);
+ try {
+ // decode request.
+ msg = (IPKIMessage) mReqEncoder.decode(encodedreq);
+ // process request
+ replymsg = processRequest(RA_Id, raUserId, msg, token);
+ } catch (IOException e) {
+ CMS.debug("ConnectorServlet: service " + e.toString());
+ CMS.debug(e);
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ } catch (EBaseException e) {
+ CMS.debug("ConnectorServlet: service " + e.toString());
+ CMS.debug(e);
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ } catch (Exception e) {
+ CMS.debug("ConnectorServlet: service " + e.toString());
+ CMS.debug(e);
+ }
+
+ CMS.debug("ConnectorServlet: done processRequest");
+
+ // encode reply
+ try {
+ String encodedrep = mReqEncoder.encode(replymsg);
+
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/html");
+ resp.setContentLength(encodedrep.length());
+
+ // send reply
+ OutputStream out = response.getOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(out, "UTF8");
+
+ writer.write(encodedrep);
+ writer.flush();
+ writer.close();
+ out.flush();
+ } catch (Exception e) {
+ CMS.debug("ConnectorServlet: error writing e=" + e.toString());
+ }
+ CMS.debug("ConnectorServlet: send response RA_Id=" + RA_Id);
+ }
+
+ public static boolean isProfileRequest(IRequest request) {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals(""))
+ return false;
+ else
+ return true;
+ }
+
+ public void normalizeProfileRequest(IRequest request) {
+ // if it is profile request, we need to normalize the
+ // x509certinfo from ra into request
+ X509CertInfo info = null;
+ ByteArrayOutputStream byteStream;
+
+ try {
+ info = request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ // request.set(IEnrollProfile.REQUEST_SEQ_NUM, new Integer("0"));
+ CertificateX509Key certKey = (CertificateX509Key)info.get(X509CertInfo.KEY);
+ if (certKey != null) {
+ byteStream = new ByteArrayOutputStream();
+ certKey.encode(byteStream);
+ request.setExtData(IEnrollProfile.REQUEST_KEY,
+ byteStream.toByteArray());
+ }
+
+ CertificateSubjectName certSubject = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ if (certSubject != null) {
+ request.setExtData(IEnrollProfile.REQUEST_SUBJECT_NAME,
+ certSubject);
+ }
+
+ CertificateValidity certValidity = (CertificateValidity)
+ info.get(X509CertInfo.VALIDITY);
+ if (certValidity != null) {
+ byteStream = new ByteArrayOutputStream();
+ certValidity.encode(byteStream);
+ request.setExtData(IEnrollProfile.REQUEST_VALIDITY,
+ byteStream.toByteArray());
+ }
+
+ CertificateExtensions extensions = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ if (extensions != null) {
+ request.setExtData(IEnrollProfile.REQUEST_EXTENSIONS,
+ extensions);
+ }
+
+ CertificateAlgorithmId certAlg = (CertificateAlgorithmId)
+ info.get(X509CertInfo.ALGORITHM_ID);
+ if (certAlg != null) {
+ ByteArrayOutputStream certAlgOut = new ByteArrayOutputStream();
+ certAlg.encode(certAlgOut);
+ request.setExtData(IEnrollProfile.REQUEST_SIGNING_ALGORITHM,
+ certAlgOut.toByteArray());
+ }
+ } catch (Exception e) {
+ CMS.debug("ConnectorServlet: profile normalization " +
+ e.toString());
+ }
+
+ String profileId = request.getExtDataInString("profileId");
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem("profile");
+ IEnrollProfile profile = null;
+
+ // profile subsystem may not be available. In case of KRA for
+ // example
+ if (ps == null) {
+ CMS.debug("ConnectorServlet: Profile Subsystem not found ");
+ return;
+ }
+ try {
+ profile = (IEnrollProfile) (ps.getProfile(profileId));
+ profile.setDefaultCertInfo(request);
+ } catch (EProfileException e) {
+ CMS.debug("ConnectorServlet: normalizeProfileRequest Exception: " + e.toString());
+ }
+ if (profile == null) {
+ CMS.debug("ConnectorServlet: Profile not found " + profileId);
+ return;
+ }
+ }
+
+ /**
+ * Process request
+ * <P>
+ *
+ * (Certificate Request - all "agent" profile cert requests made through a
+ * connector)
+ * <P>
+ *
+ * (Certificate Request Processed - all automated "agent" profile based
+ * cert acceptance made through a connector)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST used when a
+ * profile cert request is made (before approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS used when
+ * inter-CIMC_Boundary data transfer is successful (this is used when data
+ * does not need to be captured)
+ * </ul>
+ * @param source string containing source
+ * @param sourceUserId string containing source user ID
+ * @param msg PKI message
+ * @param token the authentication token
+ * @exception EBaseException an error has occurred
+ * @return PKI message
+ */
+ protected IPKIMessage processRequest(
+ String source, String sourceUserId, IPKIMessage msg, IAuthToken token)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = sourceUserId;
+ String auditProtectionMethod = SIGNED_AUDIT_PROTECTION_METHOD_SSL;
+ String auditRequestType = msg.getReqType();
+ String auditRequesterID = msg.getReqId();
+
+ // additional parms for LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ String auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String subject = null;
+
+ // additional parms for LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED
+ String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ // "normalize" the "auditSubjectID"
+ if (auditSubjectID != null) {
+ auditSubjectID = auditSubjectID.trim();
+ } else {
+ auditSubjectID = ILogger.UNIDENTIFIED;
+ }
+
+ // "normalize" the "auditRequestType"
+ if (auditRequestType != null) {
+ auditRequestType = auditRequestType.trim();
+ } else {
+ auditRequestType = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ // "normalize" the "auditRequesterID"
+ if (auditRequesterID != null) {
+ auditRequesterID = auditRequesterID.trim();
+ } else {
+ auditRequesterID = ILogger.UNIDENTIFIED;
+ }
+
+ IPKIMessage replymsg = null;
+
+ try {
+ IRequest r = null;
+ IRequestQueue queue = mAuthority.getRequestQueue();
+ String srcid = source + ":" + msg.getReqId();
+
+ // find request in request queue and return result.
+ RequestId thisreqid = queue.findRequestBySourceId(srcid);
+ IRequest thisreq = null;
+
+ if (thisreqid != null) {
+ thisreq = queue.findRequest(thisreqid);
+ if (thisreq == null) {
+ // strange case.
+ String errormsg = "Cannot find request in request queue " +
+ thisreqid;
+
+ mAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage(
+ "CMSGW_REQUEST_ID_NOT_FOUND_1",
+ thisreqid.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+
+ // NOTE: The signed audit event
+ // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ // does not yet matter at this point!
+
+ throw new EBaseException(errormsg);
+ } else {
+ mAuthority.log(ILogger.LL_INFO,
+ "Found request " + thisreqid + " for " + srcid);
+ replymsg = CMS.getHttpPKIMessage();
+ replymsg.fromRequest(thisreq);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+
+ // NOTE: The signed audit event
+ // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ // does not yet matter at this point!
+
+ return replymsg;
+ }
+ }
+
+ // if not found process request.
+ thisreq = queue.newRequest(msg.getReqType());
+ CMS.debug("ConnectorServlet: created requestId=" +
+ thisreq.getRequestId().toString());
+ thisreq.setSourceId(srcid);
+
+ // NOTE: For the following signed audit message, since we only
+ // care about the "msg.toRequest( thisreq );" command, and
+ // since this command does not throw an EBaseException
+ // (which is the only exception designated by this method),
+ // then this code does NOT need to be contained within its
+ // own special try/catch block.
+ msg.toRequest( thisreq );
+
+ if( isProfileRequest( thisreq ) ) {
+ X509CertInfo info =
+ thisreq.getExtDataInCertInfo(
+ IEnrollProfile.REQUEST_CERTINFO );
+
+ try {
+ CertificateSubjectName sn = ( CertificateSubjectName )
+ info.get( X509CertInfo.SUBJECT );
+
+ // if the cert subject name is NOT MISSING, retrieve the
+ // actual "auditCertificateSubjectName" and "normalize"
+ // it
+ if( sn != null ) {
+ subject = sn.toString();
+ if( subject != null ) {
+ // NOTE: This is ok even if the cert subject
+ // name is "" (empty)!
+ auditCertificateSubjectName = subject.trim();
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditProfileID(),
+ auditCertificateSubjectName );
+
+ audit( auditMessage );
+ } catch( CertificateException e ) {
+ CMS.debug( "ConnectorServlet: processRequest "
+ + e.toString() );
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditProfileID(),
+ auditCertificateSubjectName );
+
+ audit( auditMessage );
+ } catch( IOException e ) {
+ CMS.debug( "ConnectorServlet: processRequest "
+ + e.toString() );
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditProfileID(),
+ auditCertificateSubjectName );
+
+ audit( auditMessage );
+ }
+ }
+
+ thisreq.setExtData(IRequest.AUTH_TOKEN, token);
+
+ // setting requestor type must come after copy contents. because
+ // requestor is a regular attribute.
+ thisreq.setExtData(IRequest.REQUESTOR_TYPE,
+ IRequest.REQUESTOR_RA);
+ mAuthority.log(ILogger.LL_INFO, "Processing remote request " +
+ srcid);
+
+ // Set this so that request's updateBy is recorded
+ SessionContext s = SessionContext.getContext();
+
+ if (s.get(SessionContext.USER_ID) == null) {
+ s.put(SessionContext.USER_ID, sourceUserId);
+ }
+
+ if (s.get(SessionContext.REQUESTER_ID) == null) {
+ s.put(SessionContext.REQUESTER_ID, msg.getReqId());
+ }
+
+ CMS.debug("ConnectorServlet: calling processRequest instance=" +
+ thisreq);
+ if (isProfileRequest(thisreq)) {
+ normalizeProfileRequest(thisreq);
+ }
+
+ try {
+ queue.processRequest( thisreq );
+
+ if( isProfileRequest( thisreq ) ) {
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue( thisreq );
+
+ if( auditInfoCertValue != null ) {
+ if( !( auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE ) ) ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue );
+
+ audit( auditMessage );
+ }
+ }
+ }
+ } catch( EBaseException eAudit1 ) {
+ if( isProfileRequest( thisreq ) ) {
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue( thisreq );
+
+ if( auditInfoCertValue != null ) {
+ if( !( auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE ) ) ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue );
+
+ audit( auditMessage );
+ }
+ }
+ }
+
+ // rethrow EBaseException to primary catch clause
+ // within this method
+ throw eAudit1;
+ }
+
+ replymsg = CMS.getHttpPKIMessage();
+ replymsg.fromRequest(thisreq);
+
+ CMS.debug("ConnectorServlet: replymsg.reqStatus=" +
+ replymsg.getReqStatus());
+
+ //for audit log
+ String agentID = sourceUserId;
+ String initiative = AuditFormat.FROMRA + " trustedManagerID: " +
+ agentID + " remote reqID " + msg.getReqId();
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (token != null) {
+ authMgr =
+ token.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+
+ if (isProfileRequest(thisreq)) {
+ // XXX audit log
+ CMS.debug("ConnectorServlet: done requestId=" +
+ thisreq.getRequestId().toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+
+ // NOTE: The signed audit event
+ // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ // has already been logged at this point!
+
+ return replymsg;
+ }
+
+ // Get the certificate info from the request
+ X509CertInfo x509Info[] = thisreq.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ try {
+ if (!thisreq.getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ if (x509Info != null) {
+ for (int i = 0; i < x509Info.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ thisreq.getRequestStatus(),
+ x509Info[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ thisreq.getRequestStatus()}
+ );
+ }
+ } else {
+ if (thisreq.getRequestType().equals(IRequest.ENROLLMENT_REQUEST)) {
+ // XXX make the repeat record.
+ // Get the certificate(s) from the request
+ X509CertImpl x509Certs[] = null;
+
+ if (x509Info != null)
+ x509Certs =
+ thisreq.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ // return potentially more than one certificates.
+ if (x509Certs != null) {
+ for (int i = 0; i < x509Certs.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ x509Certs[i].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ x509Certs[i].getSerialNumber().toString(16)}
+ );
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ "completed"}
+ );
+ }
+ } else if (thisreq.getRequestType().equals(IRequest.RENEWAL_REQUEST)) {
+ X509CertImpl[] certs =
+ thisreq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ X509CertImpl old_cert = certs[0];
+
+ certs = thisreq.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ X509CertImpl renewed_cert = certs[0];
+
+ if (old_cert != null && renewed_cert != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "new serial number: 0x" +
+ renewed_cert.getSerialNumber().toString(16)}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error"}
+ );
+ }
+ } else if (thisreq.getRequestType().equals(IRequest.REVOCATION_REQUEST)) {
+ Certificate[] oldCerts =
+ thisreq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ RevokedCertImpl crlentries[] =
+ thisreq.getExtDataInRevokedCertArray(IRequest.REVOKED_CERTS);
+ CRLExtensions crlExts = crlentries[0].getExtensions();
+ int reason = 0;
+
+ if (crlExts != null) {
+ Enumeration enum1 = crlExts.getElements();
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = (Extension) enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ }
+
+ int count = oldCerts.length;
+ Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ thisreq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ thisreq.getRequestId(),
+ initiative,
+ "completed",
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ thisreq.getRequestType(),
+ thisreq.getRequestId(),
+ initiative,
+ authMgr,
+ "completed"}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+ } catch (IOException e) {
+ CMS.debug("ConnectorServlet: process " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+ } catch (CertificateException e) {
+ CMS.debug("ConnectorServlet: process " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+ } catch (Exception e) {
+ CMS.debug("ConnectorServlet: process " + e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+ } finally {
+ SessionContext.releaseContext();
+ }
+
+ // NOTE: The signed audit event
+ // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ // has already been logged at this point!
+
+ return replymsg;
+ } catch (EBaseException e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_INTER_BOUNDARY_SUCCESS,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProtectionMethod,
+ auditRequestType,
+ auditRequesterID);
+
+ audit(auditMessage);
+
+ // NOTE: The signed audit event
+ // LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST
+ // has either already been logged, or
+ // does not yet matter at this point!
+
+ return replymsg;
+ }
+ }
+
+ protected X509Certificate
+ getPeerCert(HttpServletRequest req) throws EBaseException {
+ return getSSLClientCertificate(req);
+ }
+
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Profile ID
+ *
+ * This method is inherited by all extended "EnrollProfile"s,
+ * and is called to obtain the "ProfileID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message ProfileID
+ */
+ protected String auditProfileID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String profileID = getId();
+
+ if (profileID != null) {
+ profileID = profileID.trim();
+ } else {
+ profileID = ILogger.UNIDENTIFIED;
+ }
+
+ return profileID;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param request a Request containing an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ X509CertImpl x509cert = request.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ StringBuffer sb = new StringBuffer();
+ // extract all line separators from the "base64Data"
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ sb.append(base64Data.substring(i, i));
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java b/pki/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
new file mode 100644
index 000000000..2f41efc14
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
@@ -0,0 +1,294 @@
+// --- 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.servlet.connector;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.io.*;
+
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+
+/**
+ * GenerateKeyPairServlet
+ * handles "server-side key pair generation" requests from the
+ * netkey RA.
+ *
+ * @author Christina Fu (cfu)
+ * @version $Revision$, $Date$
+ */
+//XXX add auditing later
+public class GenerateKeyPairServlet extends CMSServlet {
+
+ private final static String INFO = "GenerateKeyPairServlet";
+ public final static String PROP_AUTHORITY = "authority";
+ protected ServletConfig mConfig = null;
+ protected IAuthority mAuthority = null;
+ public static int ERROR = 1;
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+ protected IAuthSubsystem mAuthSubsystem = null;
+ protected ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs GenerateKeyPair servlet.
+ *
+ */
+ public GenerateKeyPairServlet() {
+ super();
+ }
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mConfig = config;
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ }
+
+ /**
+ * Returns serlvet information.
+ *
+ * @return name of this servlet
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /*
+ * processServerSideKeyGen -
+ * handles netkey DRM serverside keygen.
+ * netkey operations:
+ * 1. generate keypair (archive user priv key)
+ * 2. unwrap des key with transport key, then url decode it
+ * 3. wrap user priv key with des key
+ * 4. send the following to RA:
+ * * des key wrapped(user priv key)
+ * * user public key
+ * (note: RA should have kek-wrapped des key from TKS)
+ * * recovery blob (used for recovery)
+ */
+ private void processServerSideKeyGen(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException
+ {
+ IRequestQueue queue = mAuthority.getRequestQueue();
+ IRequest thisreq = null;
+
+ IConfigStore sconfig = CMS.getConfigStore();
+ boolean missingParam = false;
+ String status = "0";
+
+ CMS.debug("processServerSideKeyGen begins:");
+
+ String rCUID = req.getParameter("CUID");
+ String rUserid = req.getParameter("userid");
+ String rdesKeyString = req.getParameter("drm_trans_desKey");
+ String rArchive = req.getParameter("archive");
+ String rKeysize = req.getParameter("keysize");
+
+ if ((rCUID == null) || (rCUID.equals(""))) {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: CUID");
+ missingParam = true;
+ }
+
+ if ((rUserid == null) || (rUserid.equals(""))) {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: userid");
+ missingParam = true;
+ }
+
+ if ((rKeysize == null) || (rKeysize.equals(""))) {
+ rKeysize = "1024"; // default to 1024
+ }
+
+ if ((rdesKeyString == null) ||
+ (rdesKeyString.equals(""))) {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: DRM-transportKey-wrapped DES key");
+ missingParam = true;
+ }
+
+ if ((rArchive == null) || (rArchive.equals(""))) {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing key archival flag 'archive' ,default to true");
+ rArchive = "true";
+ }
+
+ String selectedToken = null;
+
+ if (!missingParam) {
+ thisreq = queue.newRequest(IRequest.NETKEY_KEYGEN_REQUEST);
+
+ thisreq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_NETKEY_RA);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_CUID, rCUID);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_USERID, rUserid);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY, rdesKeyString);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize);
+
+ queue.processRequest( thisreq );
+ Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
+ if (result != null) {
+ // sighs! tps thinks 0 is good, and DRM thinks 1 is good
+ if (result.intValue() == 1)
+ status = "0";
+ else
+ status = result.toString();
+ } else
+ status = "7";
+
+ CMS.debug("processServerSideKeygen finished");
+ } // ! missingParam
+
+ String value = "";
+
+ resp.setContentType("text/html");
+
+ String wrappedPrivKeyString = "";
+ String publicKeyString = "";
+
+ if( thisreq == null ) {
+ CMS.debug( "GenerateKeyPairServlet::processServerSideKeyGen() - "
+ + "thisreq is null!" );
+ throw new EBaseException( "thisreq is null" );
+ }
+
+ publicKeyString = thisreq.getExtDataInString("public_key");
+ wrappedPrivKeyString = thisreq.getExtDataInString("wrappedUserPrivate");
+
+ String ivString = thisreq.getExtDataInString("iv_s");
+
+ /*
+ if (selectedToken == null)
+ status = "4";
+ */
+ if (!status.equals("0"))
+ value = "status="+status;
+ else {
+ StringBuffer sb = new StringBuffer();
+ sb.append("status=0&");
+ sb.append("wrapped_priv_key=");
+ sb.append(wrappedPrivKeyString);
+ sb.append("&iv_param=");
+ sb.append(ivString);
+ sb.append("&public_key=");
+ sb.append(publicKeyString);
+ value = sb.toString();
+
+ }
+ CMS.debug("processServerSideKeyGen:outputString.encode " +value);
+
+ try{
+ resp.setContentLength(value.length());
+ CMS.debug("GenerateKeyPairServlet:outputString.length " +value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (IOException e) {
+ CMS.debug("GenerateKeyPairServlet: " + e.toString());
+ }
+ }
+
+
+ /*
+
+ * For GenerateKeyPair:
+ *
+ * input:
+ * CUID=value0
+ * trans-wrapped-desKey=value1
+ *
+ * output:
+ * status=value0
+ * publicKey=value1
+ * desKey-wrapped-userPrivateKey=value2
+ * proofOfArchival=value3
+ */
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "execute");
+ } catch (Exception e) {
+ }
+
+ if (authzToken == null) {
+
+ try{
+ resp.setContentType("text/html");
+ String value = "unauthorized=";
+ CMS.debug("GenerateKeyPairServlet: Unauthorized");
+
+ resp.setContentLength(value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ }catch (Exception e) {
+ CMS.debug("GenerateKeyPairServlet: " + e.toString());
+ }
+
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // begin Netkey serverSideKeyGen and archival
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeyGen would be called");
+ processServerSideKeyGen(req, resp);
+ return;
+ // end Netkey functions
+
+ }
+
+ /** XXX remember tocheck peer SSL cert and get RA id later
+ *
+ * Serves HTTP admin request.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ super.service(req, resp);
+
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java b/pki/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java
new file mode 100644
index 000000000..1e96bf948
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java
@@ -0,0 +1,341 @@
+// --- 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.servlet.connector;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.io.*;
+
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * TokenKeyRecoveryServlet
+ * handles "key recovery service" requests from the
+ * netkey TPS
+ *
+ * @author Christina Fu (cfu)
+ * @version $Revision$, $Date$
+ */
+//XXX add auditing later
+public class TokenKeyRecoveryServlet extends CMSServlet {
+
+ private final static String INFO = "TokenKeyRecoveryServlet";
+ public final static String PROP_AUTHORITY = "authority";
+ protected ServletConfig mConfig = null;
+ protected IAuthority mAuthority = null;
+ public static int ERROR = 1;
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+ protected IAuthSubsystem mAuthSubsystem = null;
+
+ /**
+ * Constructs TokenKeyRecovery servlet.
+ *
+ */
+ public TokenKeyRecoveryServlet() {
+ super();
+ }
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ mConfig = config;
+ String authority = config.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ }
+
+ /**
+ * Returns serlvet information.
+ *
+ * @return name of this servlet
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param s The URL to decode
+ */
+ protected String URLdecode(String s) {
+ if (s == null)
+ return null;
+ ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = (int) s.charAt(i);
+
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '%') {
+ int c1 = Character.digit(s.charAt(++i), 16);
+ int c2 = Character.digit(s.charAt(++i), 16);
+
+ out.write((char) (c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ } // end for
+ return out.toString();
+ }
+
+ /*
+ * processTokenKeyRecovery
+ * handles netkey key recovery requests
+ * input params are:
+ * CUID - the CUID of the old token where the keys/certs were initially for
+ * userid - the userid that belongs to both the old token and the new token
+ * drm_trans_desKey - the des key generated for the NEW token
+ * wrapped with DRM transport key
+ * cert - the user cert corresponding to the key to be recovered
+ *
+ * operations:
+ * 1. unwrap des key with transport key, then url decode it
+ * 2. retrieve user private key
+ * 3. wrap user priv key with des key
+ * 4. send the following to RA:
+ * * des key wrapped(user priv key)
+ * (note: RA should have kek-wrapped des key from TKS)
+ * * recovery blob (used for recovery)
+ *
+ * output params are:
+ * status=value0
+ * publicKey=value1
+ * desKey-wrapped-userPrivateKey=value2
+ */
+ private void processTokenKeyRecovery(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException
+ {
+ IRequestQueue queue = mAuthority.getRequestQueue();
+ IRequest thisreq = null;
+
+ // IConfigStore sconfig = CMS.getConfigStore();
+ boolean missingParam = false;
+ String status = "0";
+
+ CMS.debug("processTokenKeyRecovery begins:");
+
+ String rCUID = req.getParameter("CUID");
+ String rUserid = req.getParameter("userid");
+ String rdesKeyString = req.getParameter("drm_trans_desKey");
+ String rCert = req.getParameter("cert");
+
+ if ((rCUID == null) || (rCUID.equals(""))) {
+ CMS.debug("TokenKeyRecoveryServlet: processTokenKeyRecovery(): missing request parameter: CUID");
+ missingParam = true;
+ }
+
+ if ((rUserid == null) || (rUserid.equals(""))) {
+ CMS.debug("TokenKeyRecoveryServlet: processTokenKeyRecovery(): missing request parameter: userid");
+ missingParam = true;
+ }
+
+ if ((rdesKeyString == null) ||
+ (rdesKeyString.equals(""))) {
+ CMS.debug("TokenKeyRecoveryServlet: processTokenKeyRecovery(): missing request parameter: DRM-transportKey-wrapped des key");
+ missingParam = true;
+ }
+
+ if ((rCert == null) || (rCert.equals(""))) {
+ CMS.debug("TokenKeyRecoveryServlet: processTokenKeyRecovery(): missing request parameter: cert");
+ missingParam = true;
+ }
+
+ String selectedToken = null;
+
+ if (!missingParam) {
+ thisreq = queue.newRequest(IRequest.NETKEY_KEYRECOVERY_REQUEST);
+
+ thisreq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_NETKEY_RA);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_CUID, rCUID);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_USERID, rUserid);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY, rdesKeyString);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_USER_CERT, rCert);
+
+ //XXX auto process for netkey
+ queue.processRequest( thisreq );
+ // IService svc = (IService) new TokenKeyRecoveryService(kra);
+ // svc.serviceRequest(thisreq);
+
+ Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
+ if (result != null) {
+ // sighs! tps thinks 0 is good, and drm thinks 1 is good
+ if (result.intValue() == 1)
+ status ="0";
+ else
+ status = result.toString();
+ } else
+ status = "7";
+
+ CMS.debug("processTokenKeyRecovery finished");
+ } // ! missingParam
+
+ String value = "";
+
+ resp.setContentType("text/html");
+
+ String outputString = "";
+ String wrappedPrivKeyString = "";
+ String publicKeyString = "";
+ String ivString = "";
+ /* if is RECOVERY_PROTOTYPE
+ String recoveryBlobString = "";
+
+ IKeyRecord kr = (IKeyRecord) thisreq.get("keyRecord");
+ byte publicKey_b[] = kr.getPublicKeyData();
+
+ BigInteger serialNo = kr.getSerialNumber();
+
+ String serialNumberString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(serialNo.toByteArray());
+
+ recoveryBlobString = (String)
+ thisreq.get("recoveryBlob");
+ */
+
+ if( thisreq == null ) {
+ CMS.debug( "TokenKeyRecoveryServlet::processTokenKeyRecovery() - "
+ + "thisreq is null!" );
+ throw new EBaseException( "thisreq is null" );
+ }
+
+ publicKeyString = thisreq.getExtDataInString("public_key");
+ wrappedPrivKeyString = thisreq.getExtDataInString("wrappedUserPrivate");
+
+ ivString = thisreq.getExtDataInString("iv_s");
+ /*
+ if (selectedToken == null)
+ status = "4";
+ */
+ if (!status.equals("0"))
+ value = "status="+status;
+ else {
+ StringBuffer sb = new StringBuffer();
+ sb.append("status=0&");
+ sb.append("wrapped_priv_key=");
+ sb.append(wrappedPrivKeyString);
+ sb.append("&public_key=");
+ sb.append(publicKeyString);
+ sb.append("&iv_param=");
+ sb.append(ivString);
+ value = sb.toString();
+
+ }
+ CMS.debug("ProcessTokenKeyRecovery:outputString.encode " +value);
+
+ try{
+ resp.setContentLength(value.length());
+ CMS.debug("TokenKeyRecoveryServlet:outputString.length " +value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (IOException e) {
+ CMS.debug("TokenKeyRecoveryServlet: " + e.toString());
+ }
+ }
+
+
+ /*
+ * For TokenKeyRecovery
+ *
+ * input:
+ * CUID=value0
+ * trans-wrapped-desKey=value1
+ *
+ * output:
+ * status=value0
+ * publicKey=value1
+ * desKey-wrapped-userPrivateKey=value2
+ * proofOfArchival=value3
+ */
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ }
+
+ if (authzToken == null) {
+
+ try{
+ resp.setContentType("text/html");
+ String value = "unauthorized=";
+ CMS.debug("TokenKeyRecoveryServlet: Unauthorized");
+
+ resp.setContentLength(value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ }catch (Exception e) {
+ CMS.debug("TokenKeyRecoveryServlet: " + e.toString());
+ }
+
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // begin Netkey serverSideKeyGen and archival
+ CMS.debug("TokenKeyRecoveryServlet: processTokenKeyRecovery would be called");
+ processTokenKeyRecovery(req, resp);
+ return;
+ // end Netkey functions
+
+ }
+
+ /** XXX remember to check peer SSL cert and get RA id later
+ *
+ * Serves HTTP admin request.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ super.service(req, resp);
+
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java
new file mode 100644
index 000000000..876cd2a04
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java
@@ -0,0 +1,326 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class AdminAuthenticatePanel extends WizardPanelBase {
+
+ public AdminAuthenticatePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Admin Authentication");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Admin Authentication");
+ setId(id);
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ /**
+ * Should we skip this panel for the configuration.
+ */
+ public boolean shouldSkip() {
+ CMS.debug("AdminAuthenticatePanel: should skip");
+
+ IConfigStore cs = CMS.getConfigStore();
+ // if we are root, no need to get the certificate chain.
+
+ try {
+ String select = cs.getString("preop.subsystem.select","");
+ if (select.equals("new")) {
+ return true;
+ }
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ /* clean up if necessary */
+ try {
+ boolean done = cs.getBoolean("preop.AdminAuthenticate.done");
+ cs.putBoolean("preop.AdminAuthenticate.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.AdminAuthenticate.done", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Admin Authentication");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+
+ try {
+ String s = config.getString("preop.master.admin.uid", "");
+ String type = config.getString("preop.subsystem.select", "");
+ if (type.equals("clone"))
+ context.put("uid", s);
+ else
+ context.put("uid", "");
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("uid", "");
+ }
+
+ context.put("password", "");
+ context.put("panel", "admin/console/config/adminauthenticatepanel.vm");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String subsystemtype = "";
+ String cstype = "";
+ try {
+ subsystemtype = config.getString("preop.subsystem.select", "");
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+ cstype = toLowerCaseSubsystemType(cstype);
+
+ if (subsystemtype.equals("clone")) {
+ CMS.debug("AdminAuthenticatePanel: this is the clone subsystem");
+ String uid = HttpInput.getUID(request, "uid");
+ if (uid == null) {
+ context.put("errorString", "Uid is empty");
+ throw new IOException("Uid is empty");
+ }
+ context.put("uid", uid);
+ String pwd = HttpInput.getPassword(request, "__password");
+ config.putString("preop.master.admin.uid", uid);
+ config.putString("preop.master.admin.pwd", pwd);
+ String host = "";
+ int httpsport = -1;
+ try {
+ host = config.getString("preop.master.hostname");
+ } catch (Exception e) {
+ CMS.debug("AdminAuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing hostname for master");
+ throw new IOException("Missing hostname");
+ }
+
+ try {
+ httpsport = config.getInteger("preop.master.httpsadminport");
+ } catch (Exception e) {
+ CMS.debug("AdminAuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing port for master");
+ throw new IOException("Missing port");
+ }
+
+ String list = "";
+ try {
+ list = config.getString("preop.cert.list", "");
+ } catch (Exception e) {
+ }
+
+ StringBuffer c1 = new StringBuffer();
+ StringBuffer s1 = new StringBuffer();
+
+ StringTokenizer tok = new StringTokenizer(list, ",");
+ while (tok.hasMoreTokens()) {
+ String t1 = tok.nextToken();
+ c1.append(",");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".nickname,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".dn,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".keytype,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".keyalgorithm,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".privkey.id,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.exponent,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.modulus,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.encoded");
+
+ if (s1.length()!=0)
+ s1.append(",");
+
+ s1.append(cstype);
+ s1.append(".");
+ s1.append(t1);
+ }
+
+ if (!cstype.equals("ca")) {
+ c1.append(",preop.ca.hostname,preop.ca.httpport,preop.ca.httpsport,preop.ca.list,preop.ca.pkcs7,preop.ca.type");
+ }
+
+ String content = "uid="+uid+"&pwd="+pwd+"&op=get&names=cloning.module.token,instanceId,internaldb.basedn,internaldb.ldapauth.password,internaldb.replication.password,internaldb.ldapconn.host,internaldb.ldapconn.port,internaldb.ldapauth.bindDN"+c1.toString()+"&substores="+s1.toString();
+
+ boolean success = updateConfigEntries(host, httpsport, true,
+ "/"+cstype+"/admin/"+cstype+"/getConfigEntries", content, config,
+ response);
+
+ try {
+ config.commit(false);
+ } catch (Exception ee) {
+ }
+
+ if (!success) {
+ context.put("errorString", "Failed to get configuration entries from the master");
+ throw new IOException("Failed to get configuration entries from the master");
+ } else {
+ boolean cloneReady = isCertdbCloned(request, context);
+ if (!cloneReady) {
+ CMS.debug("AdminAuthenticatePanel update: clone does not have all the certificates.");
+ context.put("errorString", "Make sure you have copied the certificate database over to the clone");
+ throw new IOException("Clone is not ready");
+ }
+ }
+ } else {
+ CMS.debug("AdminAuthentication update: no authentication is required.");
+ }
+
+ config.putBoolean("preop.AdminAuthenticate.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ context.put("title", "Admin Authentication");
+ context.put("password", "");
+ context.put("panel", "admin/console/config/adminauthenticatepanel.vm");
+ }
+
+ private boolean isCertdbCloned(HttpServletRequest request,
+ Context context) {
+ IConfigStore config = CMS.getConfigStore();
+ String certList = "";
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ certList = config.getString("preop.cert.list");
+ StringTokenizer st = new StringTokenizer(certList, ",");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ String tokenname = config.getString("preop.module.token", "");
+ CryptoToken tok = cm.getTokenByName(tokenname);
+ CryptoStore store = tok.getCryptoStore();
+ String name1 = "preop.master."+token+".nickname";
+ String nickname = config.getString(name1, "");
+ if (!tokenname.equals("Internal Key Storage Token") &&
+ !tokenname.equals("internal"))
+ nickname = tokenname+":"+nickname;
+
+ CMS.debug("AdminAuthenticatePanel isCertdbCloned: "+nickname);
+ X509Certificate cert = cm.findCertByNickname(nickname);
+ if (cert == null)
+ return false;
+ }
+ } catch (Exception e) {
+ context.put("errorString", "Check your CS.cfg for cloning");
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java
new file mode 100644
index 000000000..c205dad95
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java
@@ -0,0 +1,687 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.cmsutil.http.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import java.net.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import com.netscape.cmsutil.xml.*;
+import org.xml.sax.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+import com.netscape.cms.servlet.wizard.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+public class AdminPanel extends WizardPanelBase {
+
+ private static final String ADMIN_UID = "admin";
+ private final static String CERT_TAG = "admin";
+
+ public AdminPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Administrator");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id) {
+ setPanelNo(panelno);
+ setName("Administrator");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.admin.email", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.admin.email", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (Exception e) {}
+
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ Descriptor emailDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "Email address for an administrator");
+
+ set.add("admin_email", emailDesc);
+
+ Descriptor pwdDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "Administrator's password");
+
+ set.add("pwd", pwdDesc);
+
+ Descriptor pwdAgainDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "Administrator's password again");
+
+ set.add("admin_password_again", pwdAgainDesc);
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("AdminPanel: display");
+
+ IConfigStore cs = CMS.getConfigStore();
+ String session_id = request.getParameter("session_id");
+ if (session_id != null) {
+ CMS.debug("NamePanel setting session id.");
+ CMS.setConfigSDSessionId(session_id);
+ }
+
+ String type = "";
+ String info = "";
+ context.put("import", "true");
+
+ String subsystemtype = "";
+ try {
+ type = cs.getString("preop.ca.type", "");
+ subsystemtype = cs.getString("cs.type", "");
+ } catch (Exception e) {}
+
+ if (isPanelDone()) {
+ try {
+ context.put("admin_email", cs.getString("preop.admin.email"));
+ context.put("admin_name", cs.getString("preop.admin.name"));
+ context.put("admin_pwd", "");
+ context.put("admin_pwd_again", "");
+ context.put("admin_uid", cs.getString("preop.admin.uid"));
+ } catch (Exception e) {}
+ } else {
+ String def_admin_name = "";
+ try {
+ def_admin_name = cs.getString("cs.type") + " Administrator of Instance " + cs.getString("instanceId");
+ } catch (EBaseException e) {
+ }
+ context.put("admin_name", def_admin_name);
+ context.put("admin_email", "");
+ context.put("admin_pwd", "");
+ context.put("admin_pwd_again", "");
+ context.put("admin_uid", ADMIN_UID);
+ }
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+
+ if (ca == null) {
+ context.put("ca", "false");
+ } else {
+ context.put("ca", "true");
+ }
+ context.put("caType", type);
+
+ String domainname = "";
+ try {
+ domainname = cs.getString("securitydomain.name", "");
+ } catch (EBaseException e1) {}
+ context.put("securityDomain", domainname);
+ context.put("title", "Administrator");
+ context.put("panel", "admin/console/config/adminpanel.vm");
+ context.put("errorString", "");
+ context.put("info", info);
+
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException
+ {
+ String pwd = HttpInput.getPassword(request, "__pwd");
+ String pwd_again = HttpInput.getPassword(request, "__admin_password_again");
+ String email = HttpInput.getEmail(request, "email");
+ String name = HttpInput.getName(request, "name");
+ String uid = HttpInput.getUID(request, "uid");
+ context.put("admin_email", email);
+ context.put("admin_name", name);
+ context.put("admin_pwd", pwd);
+ context.put("admin_pwd_again", pwd_again);
+ context.put("import", "true");
+
+ if (name == null || name.equals("")) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Name is empty");
+ }
+
+ if (email == null || email.equals("")) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Email is empty");
+ }
+
+ if (uid == null || uid.equals("")) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Uid is empty");
+ }
+
+ if (!pwd.equals(pwd_again)) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Password and password again are not the same.");
+ }
+
+ if (email == null || email.length() == 0) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Email address is empty string.");
+ }
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ context.put("info", "");
+ context.put("import", "true");
+
+ String type = "";
+ String subsystemtype = "";
+ String security_domain_type = "";
+ String selected_hierarchy = "";
+ try {
+ type = config.getString(PRE_CA_TYPE, "");
+ subsystemtype = config.getString("cs.type", "");
+ security_domain_type = config.getString("securitydomain.select","");
+ selected_hierarchy = config.getString("preop.hierarchy.select", "");
+ } catch (Exception e) {}
+
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+
+ if (ca == null) {
+ context.put("ca", "false");
+ } else {
+ context.put("ca", "true");
+ }
+ context.put("caType", type);
+ String uid = HttpInput.getUID(request, "uid");
+ String email = HttpInput.getEmail(request, "email");
+ String name = HttpInput.getName(request, "name");
+
+ CMS.debug("AdminPanel update: email address = " + email);
+ String pwd = HttpInput.getPassword(request, "__pwd");
+
+ config.putString("preop.admin.uid", uid);
+ config.putString("preop.admin.email", email);
+ config.putString("preop.admin.name", name);
+ try {
+ createAdmin(request);
+ } catch (IOException e) {
+ context.put("errorString", "Failed to create administrator.");
+ context.put("updateStatus", "failure");
+ throw e;
+ }
+
+ // REMINDER: This panel is NOT used by "clones"
+ if( ca != null ) {
+ if( selected_hierarchy.equals( "root" ) ) {
+ CMS.debug( "AdminPanel update: "
+ + "Root CA subsystem");
+ } else {
+ CMS.debug( "AdminPanel update: "
+ + "Subordinate CA subsystem");
+ }
+
+ try {
+ createAdminCertificate(request, response, context);
+ } catch (IOException e) {
+ CMS.debug("AdminPanel update: Exception: " + e.toString());
+ context.put("errorString",
+ "Failed to create administrator certificate.");
+ context.put("updateStatus", "failure");
+ throw e;
+ }
+ } else {
+ String ca_hostname = null;
+ int ca_port = -1;
+
+ // REMINDER: This panel is NOT used by "clones"
+ CMS.debug( "AdminPanel update: "
+ + subsystemtype
+ + " subsystem" );
+
+ if (type.equals("sdca")) {
+ try {
+ ca_hostname = config.getString("preop.ca.hostname");
+ ca_port = config.getInteger("preop.ca.httpsport");
+ } catch (Exception e) {
+ }
+ } else {
+ try {
+ ca_hostname = config.getString("securitydomain.host", "");
+ ca_port = config.getInteger("securitydomain.httpseeport");
+ } catch (Exception e) {
+ }
+ }
+
+ submitRequest(ca_hostname, ca_port, request, response, context);
+ }
+
+ try {
+ CMS.reinit(IUGSubsystem.ID);
+ } catch (Exception e) {
+ CMS.debug("AdminPanel update: " + e.toString());
+ }
+
+ try {
+ config.commit(false);
+ } catch (Exception e) {}
+
+ context.put("updateStatus", "success");
+
+ }
+
+ private void createAdmin(HttpServletRequest request) throws IOException {
+ IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+ IConfigStore config = CMS.getConfigStore();
+ String adminName = null;
+ String groupName = null;
+
+ try {
+ adminName = config.getString(PRE_CONF_ADMIN_NAME,
+ "Certificate System Administrator");
+ groupName = config.getString(PRE_CONF_AGENT_GROUP,
+ "Certificate Manager Agents");
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createAdmin: " + e.toString());
+ }
+
+ IUser user = null;
+ String uid = HttpInput.getUID(request, "uid");
+
+ try {
+ user = system.createUser(uid);
+ String email = HttpInput.getEmail(request, "email");
+ String name = HttpInput.getName(request, "name");
+ String pwd = HttpInput.getPassword(request, "__pwd");
+
+ user.setEmail(email);
+ user.setPassword(pwd);
+ user.setFullName(name);
+ user.setUserType("adminType");
+ user.setState("1");
+ user.setPhone("");
+ system.addUser(user);
+ } catch (LDAPException e) {
+ CMS.debug("AdminPanel createAdmin: addUser " + e.toString());
+ if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+ throw new IOException(e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createAdmin: addUser " + e.toString());
+ throw new IOException(e.toString());
+ }
+
+ IGroup group = null;
+
+ try {
+ group = system.getGroupFromName(groupName);
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+ group = system.getGroupFromName("Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ String select = config.getString("securitydomain.select", "");
+ if (select.equals("new")) {
+ group = system.getGroupFromName("Security Domain Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise CA Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise KRA Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise RA Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise TKS Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise OCSP Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+
+ group = system.getGroupFromName("Enterprise TPS Administrators");
+ if (!group.isMember(uid)) {
+ group.addMemberName(uid);
+ system.modifyGroup(group);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createAdmin: modifyGroup " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ private void submitRequest(String ca_hostname, int ca_port, HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String sd_hostname = null;
+ int sd_port = -1;
+
+ try {
+ sd_hostname = config.getString("securitydomain.host", "");
+ sd_port = config.getInteger("securitydomain.httpseeport");
+ } catch (Exception e) {}
+
+ String profileId = HttpInput.getID(request, "profileId");
+ if (profileId == null) {
+ try {
+ profileId = config.getString("preop.admincert.profile", "caAdminCert");
+ } catch (Exception e) {}
+ }
+
+ String cert_request_type = HttpInput.getID(request, "cert_request_type");
+ String cert_request = HttpInput.getCertRequest(request, "cert_request");
+ cert_request = URLEncoder.encode(cert_request, "UTF-8");
+ String session_id = CMS.getConfigSDSessionId();
+ String subjectDN = HttpInput.getString(request, "subject");
+
+ String content = "profileId="+profileId+"&cert_request_type="+cert_request_type+"&cert_request="+cert_request+"&xmlOutput=true&sessionID="+session_id+"&subject="+subjectDN;
+
+ HttpClient httpclient = new HttpClient();
+ String c = null;
+
+ try {
+ JssSSLSocketFactory factory = new JssSSLSocketFactory();
+
+ httpclient = new HttpClient(factory);
+ httpclient.connect(ca_hostname, ca_port);
+ HttpRequest httprequest = new HttpRequest();
+ httprequest.setMethod(HttpRequest.POST);
+ httprequest.setURI("/ca/ee/ca/profileSubmit");
+ httprequest.setHeader("user-agent", "HTTPTool/1.0");
+
+ httprequest.setHeader("content-length", "" + content.length());
+ httprequest.setHeader("content-type",
+ "application/x-www-form-urlencoded");
+ httprequest.setContent(content);
+ HttpResponse httpresponse = httpclient.send(httprequest);
+
+ c = httpresponse.getContent();
+ CMS.debug("AdminPanel submitRequest: content=" + c);
+
+ // retrieve the request Id ad admin certificate
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "AdminPanel::submitRequest() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+ String status = parser.getValue("Status");
+
+ CMS.debug("AdminPanel update: status=" + status);
+ if (status.equals("2")) {
+ //relogin to the security domain
+ reloginSecurityDomain(response);
+ return;
+ } else if (!status.equals("0")) {
+ String error = parser.getValue("Error");
+
+ context.put("errorString", error);
+ throw new IOException(error);
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+ String id = parser.getValue("Id");
+
+ cs.putString("preop.admincert.requestId.0", id);
+ String serial = parser.getValue("serialno");
+
+ cs.putString("preop.admincert.serialno.0", serial);
+ String b64 = parser.getValue("b64");
+ String instanceRoot = cs.getString("instanceRoot", "");
+ String dir = instanceRoot + File.separator + "conf"
+ + File.separator + "admin.b64";
+
+ cs.putString("preop.admincert.b64", dir);
+ PrintStream ps = new PrintStream(new FileOutputStream(dir));
+
+ ps.println(b64);
+ ps.flush();
+ ps.close();
+ } catch (IOException ee) {
+ context.put("errorString", ee.toString());
+ throw ee;
+ } catch (Exception ee) {
+ context.put("errorString", ee.toString());
+ throw new IOException(ee.toString());
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("AdminPanel submitRequest: " + e.toString());
+ }
+ }
+
+ private void createAdminCertificate(HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ String cert_request = HttpInput.getCertRequest(request, "cert_request");
+
+ String cert_request_type = HttpInput.getID(request, "cert_request_type");
+ IConfigStore cs = CMS.getConfigStore();
+
+ if( cs == null ) {
+ CMS.debug( "AdminPanel::createAdminCertificate() - cs is null!" );
+ throw new IOException( "cs is null" );
+ }
+
+ String subject = "";
+ X509Key x509key = null;
+ if (cert_request_type.equals("crmf")) {
+ try {
+ byte[] b = CMS.AtoB(cert_request);
+ SEQUENCE crmfMsgs = CryptoUtil.parseCRMFMsgs(b);
+ subject = CryptoUtil.getSubjectName(crmfMsgs);
+ x509key = CryptoUtil.getX509KeyFromCRMFMsgs(crmfMsgs);
+ } catch (Exception e) {
+ CMS.debug(
+ "AdminPanel createAdminCertificate: Exception="
+ + e.toString());
+ }
+ // this request is from IE. The VBScript has problem of generating
+ // certificate request if the subject name has E and UID components.
+ // For now, we always hardcoded the subject DN to be cn=NAME in
+ // the IE browser.
+ } else if (cert_request_type.equals("pkcs10")) {
+ try {
+ byte[] b = CMS.AtoB(cert_request);
+ PKCS10 pkcs10 = new PKCS10(b);
+ subject = request.getParameter("subject");
+ x509key = pkcs10.getSubjectPublicKeyInfo();
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createAdminCertificate: Exception="
+ + e.toString());
+ }
+ }
+
+ if( x509key == null ) {
+ CMS.debug( "AdminPanel::createAdminCertificate() - x509key is null!" );
+ throw new IOException( "x509key is null" );
+ }
+
+ try {
+ cs.putString(PCERT_PREFIX + CERT_TAG + ".dn", subject);
+ String caType = cs.getString(PCERT_PREFIX + CERT_TAG + ".type", "local");
+ X509CertImpl impl = CertUtil.createLocalCert(cs, x509key,
+ PCERT_PREFIX, CERT_TAG, caType, context);
+
+ // update the locally created request for renewal
+ CertUtil.updateLocalRequest(cs, CERT_TAG, cert_request,cert_request_type, subject);
+
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+ if (ca != null) {
+ createPKCS7(impl);
+ }
+ cs.putString("preop.admincert.serialno.0",
+ impl.getSerialNumber().toString(16));
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createAdminCertificate: Exception="
+ + e.toString());
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ context.put("title", "Administrator");
+ context.put("panel", "admin/console/config/adminpanel.vm");
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+ IConfigStore cs = CMS.getConfigStore();
+ String type = "";
+ String info = "";
+
+ try {
+ type = cs.getString("preop.ca.type", "");
+ } catch (Exception e) {}
+ if (ca == null && type.equals("otherca")) {
+ info = "Since you do not join the Redhat CA network, the administrator's certificate will not be generated automatically.";
+ }
+ context.put("info", info);
+ context.put("admin_email", request.getParameter("email"));
+ context.put("admin_name", request.getParameter("name"));
+ context.put("admin_pwd", "");
+ context.put("admin_pwd_again", "");
+ context.put("admin_uid", request.getParameter("uid"));
+ }
+
+ public boolean shouldSkip() {
+ try {
+ IConfigStore c = CMS.getConfigStore();
+ String s = c.getString("preop.subsystem.select",null);
+ if (s != null && s.equals("clone")) {
+ return true;
+ }
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+
+ private void createPKCS7(X509CertImpl cert) {
+ try {
+ IConfigStore cs = CMS.getConfigStore();
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) cacerts[n];
+ }
+
+ userChain[0] = cert;
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]), userChain, new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+ String p7Str = CMS.BtoA(p7Bytes);
+ cs.putString("preop.admincert.pkcs7", CryptoUtil.normalizeCertStr(p7Str));
+ } catch (Exception e) {
+ CMS.debug("AdminPanel createPKCS7: Failed to create pkcs7 file. Exception: "+e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java
new file mode 100644
index 000000000..18741bfb0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java
@@ -0,0 +1,229 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class AgentAuthenticatePanel extends WizardPanelBase {
+
+ public AgentAuthenticatePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Agent Authentication");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Agent Authentication");
+ setId(id);
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ /**
+ * Should we skip this panel for the configuration.
+ */
+ public boolean shouldSkip() {
+ CMS.debug("DisplayCertChainPanel: should skip");
+
+ IConfigStore cs = CMS.getConfigStore();
+ // if we are root, no need to get the certificate chain.
+
+ try {
+ String select = cs.getString("securitydomain.select","");
+ if (select.equals("new")) {
+ return true;
+ }
+
+ String catype = cs.getString("preop.ca.type", "");
+ if (catype.equals("otherca"))
+ return true;
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.ca.agent.uid", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.ca.agent.uid", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Agent Authentication");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+
+ try {
+ String s = config.getString("preop.ca.agent.uid", "");
+ String type = config.getString("preop.hierarchy.select", "");
+ if (type.equals("root"))
+ context.put("uid", "");
+ else
+ context.put("uid", s);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("uid", "");
+ }
+
+ context.put("password", "");
+ context.put("panel", "admin/console/config/agentauthenticatepanel.vm");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException
+ {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ context.put("panel", "admin/console/config/agentauthenticatepanel.vm");
+ context.put("title", "Agent Authentication");
+ String type = "";
+ String catype = "";
+ try {
+ type = config.getString("preop.hierarchy.select", "");
+ catype = config.getString("preop.ca.type", "");
+ } catch (Exception e) {
+ }
+
+ if (type.equals("root")) {
+ CMS.debug("AgentAuthenticatePanel: This is root, no need for authentication");
+ } else if (catype.equals("sdca")) {
+ CMS.debug("AgentAuthenticatePanel: This is not external CA");
+ String uid = HttpInput.getUID(request, "uid");
+ if (uid == null) {
+ context.put("errorString", "Uid is empty");
+ throw new IOException("Uid is empty");
+ }
+ context.put("uid", uid);
+ String pwd = HttpInput.getPassword(request, "__password");
+ config.putString("preop.ca.agent.uid", uid);
+ config.putString("preop.ca.agent.pwd", pwd);
+ String host = "";
+ int httpsport = -1;
+ try {
+ host = config.getString("preop.ca.hostname");
+ } catch (Exception e) {
+ CMS.debug("AgentAuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing hostname");
+ throw new IOException("Missing hostname");
+ }
+
+ try {
+ httpsport = config.getInteger("preop.ca.httpsport");
+ } catch (Exception e) {
+ CMS.debug("AgentAuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing port");
+ throw new IOException("Missing port");
+ }
+
+/*
+ // Bugzilla Bug #583825 - CC: Obsolete servlets to be removed from
+ // web.xml as part of CC interface review
+ boolean authenticated = authenticate(host, httpsport, true,
+ "/ca/ee/ca/checkIdentity", "uid="+uid+"&pwd="+pwd);
+
+ if (!authenticated) {
+ context.put("errorString", "Wrong user id or password");
+ throw new IOException("Wrong user id or password");
+ }
+*/
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {}
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ context.put("password", "");
+ context.put("title", "Agent Authentication");
+ context.put("panel", "admin/console/config/agentauthenticatepanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java
new file mode 100644
index 000000000..77aa5bda3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java
@@ -0,0 +1,193 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class AuthenticatePanel extends WizardPanelBase {
+
+ public AuthenticatePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Authentication");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Authentication");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.ca.agent.uid", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.ca.agent.uid","");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Authentication");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+
+ try {
+ String s = config.getString("preop.ca.agent.uid", "");
+ String type = config.getString("preop.hierarchy.select", "");
+ if (type.equals("root"))
+ context.put("uid", "");
+ else
+ context.put("uid", s);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("uid", "");
+ }
+
+ context.put("password", "");
+ context.put("panel", "admin/console/config/authenticatepanel.vm");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String type = "";
+ String catype = "";
+ try {
+ type = config.getString("preop.hierarchy.select", "");
+ catype = config.getString("preop.ca.type", "");
+ } catch (Exception e) {
+ }
+
+ if (type.equals("root")) {
+ CMS.debug("AuthenticatePanel: This is root, no need for authentication");
+ } else if (catype.equals("sdca")) {
+ CMS.debug("AuthenticatePanel: This is not external CA");
+ String uid = HttpInput.getUID(request, "uid");
+ if (uid == null) {
+ context.put("errorString", "Uid is empty");
+ throw new IOException("Uid is empty");
+ }
+ context.put("uid", uid);
+ String pwd = HttpInput.getPassword(request, "__password");
+ config.putString("preop.ca.agent.uid", uid);
+ config.putString("preop.ca.agent.pwd", pwd);
+ String host = "";
+ int httpsport = -1;
+ try {
+ host = config.getString("preop.ca.hostname");
+ } catch (Exception e) {
+ CMS.debug("AuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing hostname");
+ throw new IOException("Missing hostname");
+ }
+
+ try {
+ httpsport = config.getInteger("preop.ca.httpsport");
+ } catch (Exception e) {
+ CMS.debug("AuthenticatePanel update: "+e.toString());
+ context.put("errorString", "Missing port");
+ throw new IOException("Missing port");
+ }
+
+ boolean authenticated = authenticate(host, httpsport, true,
+ "/ca/ee/ca/configSubsystem", "uid="+uid+"&pwd="+pwd);
+
+ if (!authenticated) {
+ context.put("errorString", "Wrong user id or password");
+ throw new IOException("Wrong user id or password");
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {}
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ context.put("password", "");
+ context.put("panel", "admin/console/config/authenticatepanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java
new file mode 100644
index 000000000..7e2aedad2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java
@@ -0,0 +1,430 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.mozilla.jss.util.Password;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.KeyPair;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs12.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.crypto.PrivateKey;
+import com.netscape.cmsutil.crypto.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class BackupKeyCertPanel extends WizardPanelBase {
+
+ public BackupKeyCertPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Export Keys and Certificates");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Export Keys and Certificates");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ /* clean up if necessary */
+ try {
+ boolean done = cs.getBoolean("preop.backupkeycert.done");
+ cs.putBoolean("preop.backupkeycert.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean shouldSkip() {
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ String s = cs.getString("preop.module.token", "");
+ if (s.equals("Internal Key Storage Token"))
+ return false;
+ } catch (Exception e) {
+ }
+
+ return true;
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.backupkeycert.done", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Export Keys and Certificates");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+ try {
+ boolean enable = config.getBoolean("preop.backupkeys.enable");
+ if (enable) {
+ context.put("dobackup", "checked");
+ context.put("nobackup", "");
+ } else {
+ context.put("dobackup", "");
+ context.put("nobackup", "checked");
+ }
+ } catch (Exception e) {
+ }
+ } else {
+ context.put("dobackup", "");
+ context.put("nobackup", "checked");
+ }
+
+ context.put("panel", "admin/console/config/backupkeycertpanel.vm");
+ context.put("pwd", "");
+ context.put("pwdagain", "");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ String select = HttpInput.getID(request, "choice");
+ if (select.equals("backupkey")) {
+ String pwd = request.getParameter("__pwd");
+ String pwdAgain = request.getParameter("__pwdagain");
+ if (pwd == null || pwdAgain == null || pwd.equals("") || pwdAgain.equals("")) {
+ CMS.debug("BackupKeyCertPanel validate: Password is null");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("PK12 password is empty.");
+ }
+
+ if (!pwd.equals(pwdAgain)) {
+ CMS.debug("BackupKeyCertPanel validate: Password and password again are not the same.");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("PK12 password is different from the PK12 password again.");
+ }
+ }
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+
+ String select = HttpInput.getID(request, "choice");
+ if (select.equals("backupkey")) {
+ CMS.debug("BackupKeyCertPanel update: backup");
+ config.putBoolean("preop.backupkeys.enable", true);
+ backupKeysCerts(request);
+ } else {
+ CMS.debug("BackupKeyCertPanel update: no backup");
+ config.putBoolean("preop.backupkeys.enable", false);
+ }
+
+ config.putBoolean("preop.backupkeycert.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ String select = "";
+ try {
+ select = HttpInput.getID(request, "choice");
+ } catch (Exception e) {
+ }
+
+ if (select.equals("backupkey")) {
+ context.put("dobackup", "checked");
+ context.put("nobackup", "");
+ } else {
+ context.put("dobackup", "");
+ context.put("nobackup", "checked");
+ }
+
+ context.put("pwd", "");
+ context.put("pwdagain", "");
+ context.put("title", "Export Keys and Certificates");
+ context.put("panel", "admin/console/config/backupkeycertpanel.vm");
+ }
+
+ public void backupKeysCerts(HttpServletRequest request)
+ throws IOException {
+ CMS.debug("BackupKeyCertPanel backupKeysCerts: start");
+ IConfigStore cs = CMS.getConfigStore();
+ String certlist = "";
+ try {
+ certlist = cs.getString("preop.cert.list");
+ } catch (Exception e) {
+ }
+
+ StringTokenizer st = new StringTokenizer(certlist, ",");
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ } catch (Exception e) {
+ CMS.debug( "BackupKeyCertPanel::backupKeysCerts() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String pwd = request.getParameter("__pwd");
+ Password pass = new org.mozilla.jss.util.Password(pwd.toCharArray());
+ SEQUENCE encSafeContents = new SEQUENCE();
+ SEQUENCE safeContents = new SEQUENCE();
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ if (t.equals("sslserver"))
+ continue;
+ String nickname = "";
+ String modname = "";
+ try {
+ nickname = cs.getString("preop.cert."+t+".nickname");
+ modname = cs.getString("preop.module.token");
+ } catch (Exception e) {
+ }
+ if (!modname.equals("Internal Key Storage Token"))
+ nickname = modname+":"+nickname;
+
+ X509Certificate x509cert = null;
+ byte localKeyId[] = null;
+ try {
+ x509cert = cm.findCertByNickname(nickname);
+ localKeyId = addCertBag(x509cert, nickname, safeContents);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel: Exception="+e.toString());
+ throw new IOException("Failed to create pkcs12 file.");
+ }
+
+ try {
+ PrivateKey pkey = cm.findPrivKeyByCert(x509cert);
+ addKeyBag(pkey, x509cert, pass, localKeyId, encSafeContents);
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel: Exception="+e.toString());
+ throw new IOException("Failed to create pkcs12 file.");
+ }
+ } //while loop
+
+ X509Certificate[] cacerts = cm.getCACerts();
+
+ for (int i=0; i<cacerts.length; i++) {
+ //String nickname = cacerts[i].getSubjectDN().toString();
+ String nickname = null;
+ try {
+ byte[] localKeyId = addCertBag(cacerts[i], nickname, safeContents);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel backKeysCerts: Exception="+e.toString());
+ throw new IOException("Failed to create pkcs12 file.");
+ }
+ }
+
+ try {
+ AuthenticatedSafes authSafes = new AuthenticatedSafes();
+ authSafes.addSafeContents(safeContents);
+ authSafes.addSafeContents(encSafeContents);
+ PFX pfx = new PFX(authSafes);
+ pfx.computeMacData(pass, null, 5);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ pfx.encode(bos);
+ byte[] output = bos.toByteArray();
+ cs.putString("preop.pkcs12", CryptoUtil.byte2string(output));
+ pass.clear();
+ cs.commit(false);
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel backupKeysCerts: Exception="+e.toString());
+ }
+ }
+
+ private void addKeyBag(PrivateKey pkey, X509Certificate x509cert,
+ Password pass, byte[] localKeyId, SEQUENCE safeContents)
+ throws IOException {
+ try {
+ PasswordConverter passConverter = new PasswordConverter();
+
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ byte salt[] = random.generateSeed(4); // 4 bytes salt
+ byte[] priData = getEncodedKey(pkey);
+
+ PrivateKeyInfo pki = (PrivateKeyInfo)
+ ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData);
+ ASN1Value key = EncryptedPrivateKeyInfo.createPBE(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC,
+ pass, salt, 1, passConverter, pki);
+ SET keyAttrs = createBagAttrs(
+ x509cert.getSubjectDN().toString(), localKeyId);
+ SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG,
+ key, keyAttrs);
+ safeContents.addElement(keyBag);
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel getKeyBag: Exception="+e.toString());
+ throw new IOException("Failed to create pk12 file.");
+ }
+ }
+
+ private byte[] addCertBag(X509Certificate x509cert, String nickname,
+ SEQUENCE safeContents) throws IOException {
+ byte[] localKeyId = null;
+ try {
+ ASN1Value cert = new OCTET_STRING(x509cert.getEncoded());
+ localKeyId = createLocalKeyId(x509cert);
+ SET certAttrs = null;
+ if (nickname != null)
+ certAttrs = createBagAttrs(nickname, localKeyId);
+ SafeBag certBag = new SafeBag(SafeBag.CERT_BAG,
+ new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs);
+ safeContents.addElement(certBag);
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel addCertBag: "+e.toString());
+ throw new IOException("Failed to create pk12 file.");
+ }
+
+ return localKeyId;
+ }
+
+ private byte[] getEncodedKey(PrivateKey pkey) {
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey sk = kg.generate();
+ KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ byte iv[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
+ IVParameterSpec param = new IVParameterSpec(iv);
+ wrapper.initWrap(sk, param);
+ byte[] enckey = wrapper.wrap(pkey);
+ Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ c.initDecrypt(sk, param);
+ byte[] recovered = c.doFinal(enckey);
+ return recovered;
+ } catch (Exception e) {
+ CMS.debug("BackupKeyCertPanel getEncodedKey: Exception="+e.toString());
+ }
+
+ return null;
+ }
+
+ private byte[] createLocalKeyId(X509Certificate cert)
+ throws IOException {
+ try {
+ // SHA1 hash of the X509Cert der encoding
+ byte certDer[] = cert.getEncoded();
+
+ MessageDigest md = MessageDigest.getInstance("SHA");
+
+ md.update(certDer);
+ return md.digest();
+ } catch (CertificateEncodingException e) {
+ CMS.debug("BackupKeyCertPanel createLocalKeyId: Exception: "+e.toString());
+ throw new IOException("Failed to encode certificate.");
+ } catch (NoSuchAlgorithmException e) {
+ CMS.debug("BackupKeyCertPanel createLocalKeyId: Exception: "+e.toString());
+ throw new IOException("No such algorithm supported.");
+ }
+ }
+
+ private SET createBagAttrs(String nickName, byte localKeyId[])
+ throws IOException {
+ try {
+ SET attrs = new SET();
+ SEQUENCE nickNameAttr = new SEQUENCE();
+
+ nickNameAttr.addElement(SafeBag.FRIENDLY_NAME);
+ SET nickNameSet = new SET();
+
+ nickNameSet.addElement(new BMPString(nickName));
+ nickNameAttr.addElement(nickNameSet);
+ attrs.addElement(nickNameAttr);
+ SEQUENCE localKeyAttr = new SEQUENCE();
+
+ localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
+ SET localKeySet = new SET();
+
+ localKeySet.addElement(new OCTET_STRING(localKeyId));
+ localKeyAttr.addElement(localKeySet);
+ attrs.addElement(localKeyAttr);
+ return attrs;
+ } catch (CharConversionException e) {
+ CMS.debug("BackupKeyCertPanel createBagAttrs: Exception="+e.toString());
+ throw new IOException("Failed to create PKCS12 file.");
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java
new file mode 100644
index 000000000..9bbb09005
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java
@@ -0,0 +1,114 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.apps.*;
+
+
+public class BaseServlet extends VelocityServlet {
+
+ /**
+ * Returns usage of this servlet.
+ */
+ public String getUsage() {
+ return null;
+ }
+
+ public boolean authenticate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String pin = (String) request.getSession().getAttribute("pin");
+
+ if (pin == null) {
+ try {
+ response.sendRedirect("login");
+ } catch (IOException e) {}
+ return false;
+ }
+ return true;
+ }
+
+ public void outputHttpParameters(HttpServletRequest httpReq) {
+ CMS.debug("BaseServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String pn = (String) paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("BaseServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("BaseServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+ /**
+ * Processes request.
+ */
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ return null;
+ }
+
+ public Template handleRequest(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ if (CMS.debugOn()) {
+ outputHttpParameters(request);
+ }
+
+ /* XXX - authentication */
+ if (!authenticate(request, response, context)) {
+ return null;
+ }
+
+ /* XXX - authorization */
+
+ return process(request, response, context);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java
new file mode 100644
index 000000000..316c5706d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java
@@ -0,0 +1,328 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import org.xml.sax.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.crypto.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import com.netscape.cmsutil.http.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.asn1.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class CAInfoPanel extends WizardPanelBase {
+
+ public CAInfoPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("CA Information");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("CA Information");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.ca.type", "");
+ }
+
+ public boolean shouldSkip() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.subsystem.select", "");
+ if (s.equals("clone"))
+ return true;
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.ca.type", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (Exception e) {}
+
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("CAInfoPanel: display");
+
+ IConfigStore cs = CMS.getConfigStore();
+ String hostname = "";
+ String httpport = "";
+ String httpsport = "";
+
+ if (isPanelDone()) {
+ String type = "sdca";
+
+ try {
+ type = cs.getString("preop.ca.type");
+ } catch (Exception e) {
+ CMS.debug("CAInfoPanel exception: " + e.toString());
+ return;
+ }
+
+ try {
+ hostname = cs.getString("preop.ca.hostname");
+ } catch (Exception e) {}
+
+ try {
+ httpport = cs.getString("preop.ca.httpport");
+ } catch (Exception e) {}
+
+ try {
+ httpsport = cs.getString("preop.ca.httpsport");
+ } catch (Exception e) {}
+
+ if (type.equals("sdca")) {
+ context.put("check_sdca", "checked");
+ context.put("check_otherca", "");
+ } else if (type.equals("otherca")) {
+ context.put("check_sdca", "");
+ context.put("check_otherca", "checked");
+ }
+ } else {
+ context.put("check_sdca", "checked");
+ context.put("check_otherca", "");
+ }
+
+ String cstype = "CA";
+ String portType = "SecurePort";
+
+/*
+ try {
+ cstype = cs.getString("cs.type", "");
+ } catch (EBaseException e) {}
+*/
+
+ CMS.debug("CAInfoPanel: Ready to get url");
+ Vector v = getUrlListFromSecurityDomain(cs, cstype, portType);
+ v.addElement("External CA");
+ StringBuffer list = new StringBuffer();
+ int size = v.size();
+
+ for (int i = 0; i < size; i++) {
+ if (i == size - 1) {
+ list.append(v.elementAt(i));
+ } else {
+ list.append(v.elementAt(i));
+ list.append(",");
+ }
+ }
+
+ try {
+ cs.putString("preop.ca.list", list.toString());
+ cs.commit(false);
+ } catch (Exception e) {}
+
+ context.put("urls", v);
+
+ context.put("sdcaHostname", hostname);
+ context.put("sdcaHttpPort", httpport);
+ context.put("sdcaHttpsPort", httpsport);
+ context.put("title", "CA Information");
+ context.put("panel", "admin/console/config/cainfopanel.vm");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+
+ /*
+ String select = request.getParameter("choice");
+ if (select == null) {
+ CMS.debug("CAInfoPanel: choice not found");
+ throw new IOException("choice not found");
+ }
+ */
+ IConfigStore config = CMS.getConfigStore();
+
+ try {
+ String subsystemselect = config.getString("preop.subsystem.select", "");
+ if (subsystemselect.equals("clone"))
+ return;
+ } catch (Exception e) {
+ }
+
+ String select = null;
+ String index = request.getParameter("urls");
+ String url = "";
+ if (index.startsWith("http")) {
+ // user may submit url directlry
+ url = index;
+ } else {
+ try {
+ int x = Integer.parseInt(index);
+ String list = config.getString("preop.ca.list", "");
+ StringTokenizer tokenizer = new StringTokenizer(list, ",");
+ int counter = 0;
+
+ while (tokenizer.hasMoreTokens()) {
+ url = tokenizer.nextToken();
+ if (counter == x) {
+ break;
+ }
+ counter++;
+ }
+ } catch (Exception e) {}
+ }
+
+ URL urlx = null;
+
+ if (url.equals("External CA")) {
+ select = "otherca";
+ config.putString("preop.ca.pkcs7", "");
+ config.putInteger("preop.ca.certchain.size", 0);
+ } else {
+ select = "sdca";
+
+ // parse URL (CA1 - https://...)
+ url = url.substring(url.indexOf("https"));
+ urlx = new URL(url);
+ }
+
+ ISubsystem subsystem = CMS.getSubsystem(ICertificateAuthority.ID);
+
+ if (select.equals("sdca")) {
+ config.putString("preop.ca.type", "sdca");
+ CMS.debug("CAInfoPanel update: this is the CA in the security domain.");
+ context.put("check_sdca", "checked");
+ sdca(request, context, urlx.getHost(),
+ Integer.toString(urlx.getPort()));
+ if (subsystem != null) {
+ config.putString(PCERT_PREFIX + "signing.type", "remote");
+ config.putString(PCERT_PREFIX + "signing.profile",
+ "caInstallCACert");
+ }
+ } else if (select.equals("otherca")) {
+ config.putString("preop.ca.type", "otherca");
+ context.put("check_otherca", "checked");
+ if (subsystem != null) {
+ config.putString(PCERT_PREFIX + "signing.type", "remote");
+ }
+ CMS.debug("CAInfoPanel update: this is the other CA.");
+ }
+
+ try {
+ config.commit(false);
+ } catch (Exception e) {}
+ }
+
+ private void sdca(HttpServletRequest request, Context context, String hostname, String httpsPortStr) throws IOException {
+ CMS.debug("CAInfoPanel update: this is the CA in the security domain.");
+ IConfigStore config = CMS.getConfigStore();
+
+ context.put("sdcaHostname", hostname);
+ context.put("sdcaHttpsPort", httpsPortStr);
+
+ if (hostname == null || hostname.length() == 0) {
+ context.put("errorString", "Hostname is null");
+ throw new IOException("Hostname is null");
+ }
+
+ int httpsport = -1;
+
+ try {
+ httpsport = Integer.parseInt(httpsPortStr);
+ } catch (Exception e) {
+ CMS.debug(
+ "CAInfoPanel update: Https port is not valid. Exception: "
+ + e.toString());
+ throw new IOException("Http Port is not valid.");
+ }
+
+ config.putString("preop.ca.hostname", hostname);
+ config.putString("preop.ca.httpsport", httpsPortStr);
+ ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback();
+ updateCertChainUsingSecureEEPort( config, "ca", hostname,
+ httpsport, true, context,
+ certApprovalCallback );
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ /* This should never be called */
+ context.put("title", "CA Information");
+ context.put("panel", "admin/console/config/cainfopanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
new file mode 100644
index 000000000..4aca6cec7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
@@ -0,0 +1,184 @@
+// --- 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.servlet.csadmin;
+
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+
+public class Cert {
+ private String mNickname = "";
+ private String mTokenname = "";
+ private String mRequest = "";
+ private String mCert = "";
+ private String mType = ""; // "selfsign," "local," or "remote"
+ private String mDN = "";
+ private String mCertTag = "";
+ private String mCertpp = "";
+ private String mUserFriendlyName = "";
+ private String mKeyOption = "";
+ private String mCustomKeysize = "";
+ private String mCustomCurvename = "";
+ private boolean mEnable = true;
+ private boolean mSigningRequired = false;
+ private String mSubsystem = "";
+
+ public Cert(String tokenName, String nickName, String certTag) {
+ mTokenname = tokenName;
+ mNickname = nickName;
+ mCertTag = certTag;
+ }
+
+ public void setEnable(boolean enable) {
+ mEnable = enable;
+ }
+
+ public boolean isEnable() {
+ return mEnable;
+ }
+
+ public void setSigningRequired(boolean required) {
+ mSigningRequired = required;
+ }
+
+ public boolean isSigningRequired() {
+ return mSigningRequired;
+ }
+
+ public void setNickname(String s) {
+ mNickname = s;
+ }
+
+ public String getNickname() {
+ return mNickname;
+ }
+
+ public void setSubsystem(String s) {
+ mSubsystem = s;
+ }
+
+ public String getSubsystem() {
+ return mSubsystem;
+ }
+
+ public String getUserFriendlyName() {
+ return mUserFriendlyName;
+ }
+
+ public void setUserFriendlyName(String name) {
+ mUserFriendlyName = name;
+ }
+
+ public String getTokenname() {
+ return mTokenname;
+ }
+
+ public String getRequest() {
+ return mRequest;
+ }
+
+ public void setRequest(String req) {
+ mRequest = req;
+ }
+
+ public String getEscapedCert() {
+ return escapeForHTML(mCert);
+ }
+
+ public String getCert() {
+ return mCert;
+ }
+
+ public void setCert(String cert) {
+ mCert = cert;
+ }
+
+ public String getType() {
+ return mType;
+ }
+
+ public void setType(String type) {
+ mType = type;
+ }
+
+ public String escapeForHTML(String s) {
+ s = s.replaceAll("\"", "&quot;");
+ return s;
+ }
+
+ public String getEscapedDN() {
+ // Need to escape "
+ return escapeForHTML(mDN);
+ }
+
+ public String getDN() {
+ return mDN;
+ }
+
+ public void setDN(String dn) {
+ mDN = dn;
+ }
+
+ public String getCertTag() {
+ return mCertTag;
+ }
+
+ public String getEscapedCertpp() {
+ return escapeForHTML(mCertpp);
+ }
+
+ public String getCertpp() {
+ return mCertpp;
+ }
+
+ public void setCertpp(String pp) {
+ mCertpp = pp;
+ }
+
+ public String getKeyOption() {
+ return mKeyOption;
+ }
+
+ /*
+ * "default" or "custom"
+ */
+ public void setKeyOption(String option) {
+ mKeyOption = option;
+ }
+
+ public boolean useDefaultKey() {
+ return (mKeyOption.equals("default"));
+ }
+
+ public String getCustomKeysize() {
+ return mCustomKeysize;
+ }
+
+ public void setCustomKeysize(String size) {
+ mCustomKeysize = size;
+ }
+
+ public String getCustomCurvename() {
+ return mCustomCurvename;
+ }
+
+ public void setCustomCurvename(String curve) {
+ mCustomCurvename = curve;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java
new file mode 100644
index 000000000..bd4893915
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java
@@ -0,0 +1,216 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmsutil.crypto.*;
+
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs11.*;
+
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class CertPrettyPrintPanel extends WizardPanelBase {
+ private Vector mCerts = null;
+
+ public CertPrettyPrintPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Certificates");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Certificates");
+ setId(id);
+ }
+
+ public PropertySet getUsage() {
+ // expects no input from client
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putBoolean("preop.CertPrettyPrintPanel.done", false);
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.CertPrettyPrintPanel.done",
+ false);
+
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ public void getCert(HttpServletRequest req, IConfigStore config,
+ Context context, String certTag, Cert cert) {
+ CMS.debug("CertPrettyPrintPanel: in getCert()");
+ try {
+ // String cert = config.getString(CONF_CA_CERT);
+ String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem");
+ String certs = config.getString(subsystem + "." + certTag + ".cert");
+ byte[] certb = CryptoUtil.base64Decode(certs);
+
+ if (cert != null) {
+ CertPrettyPrint pp = new CertPrettyPrint(certb);
+ cert.setCertpp(pp.toString(Locale.getDefault()));
+ String certf = CryptoUtil.certFormat(certs);
+
+ // String canickname = config.getString(CONF_CA_CERTNICKNAME);
+ // context.put("cert", certf);
+ // context.put("nickname", nickname);
+ cert.setCert(certf);
+ }
+ } catch (Exception e) {
+ CMS.debug("CertPrettyPrintPanel:getCert" + e.toString());
+ } // try
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ CMS.debug("CertPrettyPrintPanel: display()");
+ context.put("title", "Certificates Pretty Print");
+
+ try {
+ mCerts = new Vector();
+
+ IConfigStore config = CMS.getConfigStore();
+
+ String certTags = config.getString("preop.cert.list");
+ StringTokenizer st = new StringTokenizer(certTags, ",");
+
+ while (st.hasMoreTokens()) {
+ String certTag = st.nextToken();
+
+ try {
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+
+ String nickname = config.getString(
+ subsystem + "." + certTag + ".nickname");
+ String tokenname = config.getString(
+ subsystem + "." + certTag + ".tokenname");
+ Cert c = new Cert(tokenname, nickname, certTag);
+
+ String type = config.getString(
+ PCERT_PREFIX + certTag + ".type");
+
+ c.setType(type);
+ getCert(request, config, context, certTag, c);
+
+ mCerts.addElement(c);
+ } catch (Exception e) {
+ CMS.debug(
+ "CertPrettyPrintPanel: display() certTag " + certTag
+ + " Exception caught: " + e.toString());
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(
+ "CertPrettyPrintPanel:display() Exception caught: "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+
+ } // try
+
+ context.put("ppcerts", mCerts);
+ context.put("status", "display");
+ // context.put("status_token", "None");
+ context.put("panel", "admin/console/config/certprettyprintpanel.vm");
+
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ CMS.debug("CertPrettyPrintPanel: in update()");
+ IConfigStore config = CMS.getConfigStore();
+ config.putBoolean("preop.CertPrettyPrintPanel.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug(
+ "CertPrettyPrintPanel: update() Exception caught at config commit: "
+ + e.toString());
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Certificates Pretty Print");
+ context.put("panel", "admin/console/config/certprettyprintpanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
new file mode 100644
index 000000000..842f87b5f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
@@ -0,0 +1,757 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.math.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs11.*;
+
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class CertRequestPanel extends WizardPanelBase {
+ private Vector mCerts = null;
+ private WizardServlet mServlet = null;
+
+ public CertRequestPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Requests & Certificates");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Requests and Certificates");
+ mServlet = servlet;
+ setId(id);
+ }
+
+ // XXX how do you do this? There could be multiple certs.
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ Descriptor certDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameters */
+ null);
+
+ set.add("cert", certDesc);
+
+ return set;
+ }
+
+ /**
+ * Show "Apply" button on frame?
+ */
+ public boolean showApplyButton() {
+ if (isPanelDone())
+ return false;
+ else
+ return true;
+ }
+
+ private boolean findCertificate(String tokenname, String nickname)
+ throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ } catch (Exception e) {
+ }
+
+ String fullnickname = nickname;
+
+ boolean hardware = false;
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) {
+ hardware = true;
+ fullnickname = tokenname+":"+nickname;
+ }
+
+ try {
+ X509Certificate cert = cm.findCertByNickname(fullnickname);
+ if (cert == null)
+ return false;
+ try {
+ boolean done = cs.getBoolean("preop.CertRequestPanel.done");
+ return true;
+ } catch (Exception ee) {
+ if (hardware) {
+ CMS.debug("CertRequestPanel findCertificate: The certificate with the same nickname: "+ fullnickname +" has been found on HSM. Please remove it before proceeding.");
+ throw new IOException("The certificate with the same nickname: "+ fullnickname +" has been found on HSM. Please remove it before proceeding.");
+ }
+ return true;
+ }
+ } catch (IOException e) {
+ CMS.debug("CertRequestPanel findCertificate: throw exception:"+e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel findCertificate: Exception="+e.toString());
+ return false;
+ }
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ String select = "";
+ String list = "";
+ String tokenname = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ list = cs.getString("preop.cert.list", "");
+ tokenname = cs.getString("preop.module.token", "");
+ } catch (Exception e) {
+ }
+
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(
+ ICertificateAuthority.ID);
+
+ if (ca != null) {
+ CMS.debug("CertRequestPanel cleanup: get certificate repository");
+ BigInteger beginS = null;
+ BigInteger endS = null;
+ String beginNum = "";
+ String endNum = "";
+ try {
+ beginNum = cs.getString("dbs.beginSerialNumber", "");
+ endNum = cs.getString("dbs.endSerialNumber", "");
+ if (!beginNum.equals(""))
+ beginS = new BigInteger(beginNum, 16);
+ if (!endNum.equals(""))
+ endS = new BigInteger(endNum, 16);
+ } catch (Exception e) {
+ }
+
+ ICertificateRepository cr = ca.getCertificateRepository();
+ if (cr != null) {
+ try {
+ cr.removeCertRecords(beginS, endS);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel cleanUp exception in removing all objects: "+e.toString());
+ }
+
+ try {
+ cr.resetSerialNumber(new BigInteger(beginNum,16));
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel cleanUp exception in resetting serial number: "+e.toString());
+ }
+ }
+ }
+
+
+ StringTokenizer st = new StringTokenizer(list, ",");
+ String nickname = "";
+ boolean enable = false;
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+
+ try {
+ enable = cs.getBoolean(PCERT_PREFIX+t+".enable", true);
+ nickname = cs.getString(PCERT_PREFIX +t+".nickname", "");
+ } catch (Exception e) {
+ }
+
+ if (!enable)
+ continue;
+
+ if (t.equals("sslserver"))
+ continue;
+
+ if (findCertificate(tokenname, nickname)) {
+ try {
+ CMS.debug("CertRequestPanel cleanup: deleting certificate ("+nickname+").");
+ deleteCert(tokenname, nickname);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel cleanup: failed to delete certificate (" +nickname+"). Exception: " +e.toString());
+ }
+ }
+ }
+
+ try {
+ boolean done = cs.getBoolean("preop.CertRequestPanel.done");
+ cs.putBoolean("preop.CertRequestPanel.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.CertRequestPanel.done",
+ false);
+
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ public void getCert(IConfigStore config,
+ Context context, String certTag, Cert cert) {
+ try {
+
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+
+ String certs = config.getString(subsystem + "." + certTag + ".cert", "");
+
+ if (cert != null) {
+ String certf = certs;
+
+ CMS.debug(
+ "CertRequestPanel getCert: certTag=" + certTag
+ + " cert=" + certs);
+ //get and set formated cert
+ if (!certs.startsWith("...")) {
+ certf = CryptoUtil.certFormat(certs);
+ }
+ cert.setCert(certf);
+
+ //get and set cert pretty print
+ byte[] certb = CryptoUtil.base64Decode(certs);
+ CertPrettyPrint pp = new CertPrettyPrint(certb);
+ cert.setCertpp(pp.toString(Locale.getDefault()));
+ } else {
+ CMS.debug( "CertRequestPanel::getCert() - cert is null!" );
+ return;
+ }
+ String userfriendlyname = config.getString(
+ PCERT_PREFIX + certTag + ".userfriendlyname");
+
+ cert.setUserFriendlyName(userfriendlyname);
+ String type = config.getString(PCERT_PREFIX + certTag + ".type");
+
+ cert.setType(type);
+ String dn = config.getString(PCERT_PREFIX + certTag + ".dn");
+
+ cert.setDN(dn);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel:getCert" + e.toString());
+ } // try
+ }
+
+ public X509Key getECCX509Key(IConfigStore config, String certTag)
+ throws Exception
+ {
+ X509Key pubk = null;
+ String pubKeyEncoded = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.encoded");
+ pubk = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded));
+ return pubk;
+ }
+
+ public X509Key getRSAX509Key(IConfigStore config, String certTag)
+ throws Exception
+ {
+ X509Key pubk = null;
+
+ String pubKeyModulus = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.modulus");
+ String pubKeyPublicExponent = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.exponent");
+ pubk = CryptoUtil.getPublicX509Key(
+ CryptoUtil.string2byte(pubKeyModulus),
+ CryptoUtil.string2byte(pubKeyPublicExponent));
+ return pubk;
+ }
+
+ public void handleCertRequest(IConfigStore config,
+ Context context, String certTag, Cert cert) {
+ try {
+ // get public key
+ String pubKeyType = config.getString(
+ PCERT_PREFIX + certTag + ".keytype");
+ String algorithm = config.getString(
+ PCERT_PREFIX + certTag + ".keyalgorithm");
+ X509Key pubk = null;
+ if (pubKeyType.equals("rsa")) {
+ pubk = getRSAX509Key(config, certTag);
+ } else if (pubKeyType.equals("ecc")) {
+ pubk = getECCX509Key(config, certTag);
+ } else {
+ CMS.debug( "CertRequestPanel::handleCertRequest() - "
+ + "pubKeyType " + pubKeyType + " is unsupported!" );
+ return;
+ }
+
+ CMS.debug("CertRequestPanel: tag=" + certTag);
+ if (pubk != null) {
+ CMS.debug("CertRequestPanel: got public key");
+ } else {
+ CMS.debug("CertRequestPanel: error getting public key null");
+ return;
+ }
+
+ // get private key
+ String privKeyID = config.getString(
+ PCERT_PREFIX + certTag + ".privkey.id");
+ CMS.debug("CertRequestPanel: privKeyID=" + privKeyID);
+ byte[] keyIDb = CryptoUtil.string2byte(privKeyID);
+
+ PrivateKey privk = CryptoUtil.findPrivateKeyFromID(keyIDb);
+
+ if (privk != null) {
+ CMS.debug("CertRequestPanel: got private key");
+ } else {
+ CMS.debug("CertRequestPanel: error getting private key null");
+ }
+
+ // construct cert request
+ String caDN = config.getString(PCERT_PREFIX + certTag + ".dn");
+
+ cert.setDN(caDN);
+ PKCS10 certReq = CryptoUtil.createCertificationRequest(caDN, pubk,
+ privk, algorithm);
+
+ CMS.debug("CertRequestPanel: created cert request");
+ byte[] certReqb = certReq.toByteArray();
+ String certReqs = CryptoUtil.base64Encode(certReqb);
+ String certReqf = CryptoUtil.reqFormat(certReqs);
+
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+ config.putString(subsystem + "." + certTag + ".certreq", certReqs);
+ config.commit(false);
+ cert.setRequest(certReqf);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel::handleCertRequest" + e.toString());
+ CMS.debug(e);
+ } // try
+
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ CMS.debug("CertRequestPanel: display()");
+ context.put("title", "Requests and Certificates");
+
+ try {
+ mCerts = new Vector();
+
+ IConfigStore config = CMS.getConfigStore();
+
+ String certTags = config.getString("preop.cert.list");
+ StringTokenizer st = new StringTokenizer(certTags, ",");
+
+ while (st.hasMoreTokens()) {
+ String certTag = st.nextToken();
+
+ try {
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+ String nickname = config.getString(
+ subsystem + "." + certTag + ".nickname");
+ String tokenname = config.getString(
+ subsystem + "." + certTag + ".tokenname");
+ Cert c = new Cert(tokenname, nickname, certTag);
+
+ handleCertRequest(config, context, certTag, c);
+
+ String type = config.getString(
+ PCERT_PREFIX + certTag + ".type");
+
+ c.setType(type);
+ boolean enable = config.getBoolean(PCERT_PREFIX+certTag+".enable", true);
+ c.setEnable(enable);
+ getCert(config, context, certTag, c);
+
+ c.setSubsystem(subsystem);
+ mCerts.addElement(c);
+ } catch (Exception e) {
+ CMS.debug(
+ "CertRequestPanel:display() Exception caught: "
+ + e.toString() + " for certTag " + certTag);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(
+ "CertRequestPanel:display() Exception caught: "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+
+ } // try
+
+ context.put("reqscerts", mCerts);
+ context.put("status", "display");
+ // context.put("status_token", "None");
+ context.put("panel", "admin/console/config/certrequestpanel.vm");
+
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ private boolean findBootstrapServerCert() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String instanceID = cs.getString("instanceId", "");
+ String nickname = "Server-Cert cert-" + instanceID;
+
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate cert = cm.findCertByNickname(nickname);
+ Principal issuerDN = cert.getIssuerDN();
+ Principal subjectDN = cert.getSubjectDN();
+ if (issuerDN.equals(subjectDN))
+ return true;
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel findBootstrapServerCert Exception="+e.toString());
+ }
+
+ return false;
+ }
+
+ private void deleteBootstrapServerCert() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String instanceID = cs.getString("instanceId", "");
+ String nickname = "Server-Cert cert-" + instanceID;
+
+ deleteCert("Internal Key Storage Token", nickname);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel deleteBootstrapServerCert Exception="+e.toString());
+ }
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ CMS.debug("CertRequestPanel: in update()");
+ boolean hasErr = false;
+ IConfigStore config = CMS.getConfigStore();
+
+ String catype = "";
+ try {
+ catype = config.getString("preop.ca.type", "");
+ } catch (Exception e) {
+ }
+
+ if (isPanelDone()) {
+ context.put("updateStatus", "success");
+ return;
+ }
+
+ try {
+ Enumeration c = mCerts.elements();
+
+ String tokenname = "";
+ try {
+ tokenname = config.getString("preop.module.token", "");
+ } catch (Exception e) {
+ }
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String certTag = cert.getCertTag();
+ String subsystem = cert.getSubsystem();
+ boolean enable = config.getBoolean(PCERT_PREFIX+certTag+".enable", true);
+ if (!enable)
+ continue;
+
+ if (hasErr)
+ continue;
+
+ String nickname = cert.getNickname();
+
+ CMS.debug(
+ "CertRequestPanel: update() for cert tag "
+ + cert.getCertTag());
+ // String b64 = config.getString(CERT_PREFIX+ certTag +".cert", "");
+ String b64 = HttpInput.getCert(request, certTag);
+
+ if (cert.getType().equals("local")
+ && b64.equals(
+ "...certificate be generated internally...")) {
+
+ String pubKeyType = config.getString(
+ PCERT_PREFIX + certTag + ".keytype");
+ X509Key x509key = null;
+ if (pubKeyType.equals("rsa")) {
+ x509key = getRSAX509Key(config, certTag);
+ } else if (pubKeyType.equals("ecc")) {
+ x509key = getECCX509Key(config, certTag);
+ }
+
+ if (findCertificate(tokenname, nickname)) {
+ if (!certTag.equals("sslserver"))
+ continue;
+ }
+ X509CertImpl impl = CertUtil.createLocalCert(config, x509key,
+ PCERT_PREFIX, certTag, cert.getType(), context);
+
+ if (impl != null) {
+ byte[] certb = impl.getEncoded();
+ String certs = CryptoUtil.base64Encode(certb);
+
+ cert.setCert(certs);
+ config.putString(subsystem + "." + certTag + ".cert", certs);
+ /* import certificate */
+ CMS.debug(
+ "CertRequestPanel configCert: nickname="
+ + nickname);
+
+ try {
+ if (certTag.equals("sslserver") && findBootstrapServerCert())
+ deleteBootstrapServerCert();
+ if (findCertificate(tokenname, nickname))
+ deleteCert(tokenname, nickname);
+ if (certTag.equals("signing") && subsystem.equals("ca"))
+ CryptoUtil.importUserCertificate(impl, nickname);
+ else
+ CryptoUtil.importUserCertificate(impl, nickname, false);
+ CMS.debug(
+ "CertRequestPanel configCert: cert imported for certTag "
+ + certTag);
+ } catch (Exception ee) {
+ CMS.debug(
+ "CertRequestPanel configCert: import certificate for certTag="
+ + certTag + " Exception: "
+ + ee.toString());
+ CMS.debug("ok");
+// hasErr = true;
+ }
+ }
+ } else if (cert.getType().equals("remote")) {
+ if (b64 != null && b64.length() > 0
+ && !b64.startsWith("...")) {
+ String b64chain = HttpInput.getCertChain(request, certTag+"_cc");
+ CMS.debug(
+ "CertRequestPanel: in update() process remote...import cert");
+
+ String input = HttpInput.getCert(request, cert.getCertTag());
+
+ if (input != null) {
+ try {
+ if (certTag.equals("sslserver") && findBootstrapServerCert())
+ deleteBootstrapServerCert();
+ if (findCertificate(tokenname, nickname)) {
+ deleteCert(tokenname, nickname);
+ }
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel update (remote): deleteCert Exception="+e.toString());
+ }
+ input = CryptoUtil.stripCertBrackets(input.trim());
+ String certs = CryptoUtil.normalizeCertStr(input);
+ byte[] certb = CryptoUtil.base64Decode(certs);
+
+ config.putString(subsystem + "." + certTag + ".cert",
+ certs);
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate x509cert = cm.importCertPackage(
+ certb, nickname);
+
+ CryptoUtil.trustCertByNickname(nickname);
+ X509Certificate[] certchains = cm.buildCertificateChain(
+ x509cert);
+ X509Certificate leaf = null;
+
+ if (certchains != null) {
+ CMS.debug(
+ "CertRequestPanel certchains length="
+ + certchains.length);
+ leaf = certchains[certchains.length - 1];
+ }
+
+ if( leaf == null ) {
+ CMS.debug( "CertRequestPanel::update() - "
+ + "leaf is null!" );
+ throw new IOException( "leaf is null" );
+ }
+
+ if (/*(certchains.length <= 1) &&*/
+ (b64chain != null)) {
+ CMS.debug("CertRequestPanel: cert might not have contained chain...calling importCertificateChain");
+ try {
+ CryptoUtil.importCertificateChain(
+ CryptoUtil.normalizeCertAndReq(b64chain));
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel: importCertChain: Exception: "+e.toString());
+ }
+ }
+
+ InternalCertificate icert = (InternalCertificate) leaf;
+
+ icert.setSSLTrust(
+ InternalCertificate.TRUSTED_CA
+ | InternalCertificate.TRUSTED_CLIENT_CA
+ | InternalCertificate.VALID_CA);
+ CMS.debug(
+ "CertRequestPanel configCert: import certificate successfully, certTag="
+ + certTag);
+ } catch (Exception ee) {
+ CMS.debug(
+ "CertRequestPanel configCert: import certificate for certTag="
+ + certTag + " Exception: "
+ + ee.toString());
+ CMS.debug("ok");
+// hasErr=true;
+ }
+ } else {
+ CMS.debug("CertRequestPanel: in update() input null");
+ hasErr = true;
+ }
+ } else {
+ CMS.debug("CertRequestPanel: in update() b64 not set");
+ hasErr=true;
+ }
+
+ } else {
+ b64 = CryptoUtil.stripCertBrackets(b64.trim());
+ String certs = CryptoUtil.normalizeCertStr(b64);
+ byte[] certb = CryptoUtil.base64Decode(certs);
+ X509CertImpl impl = new X509CertImpl(certb);
+ try {
+ if (certTag.equals("sslserver") && findBootstrapServerCert())
+ deleteBootstrapServerCert();
+ if (findCertificate(tokenname, nickname)) {
+ deleteCert(tokenname, nickname);
+ }
+ } catch (Exception ee) {
+ CMS.debug("CertRequestPanel update: deleteCert Exception="+ee.toString());
+ }
+
+ try {
+ if (certTag.equals("signing") && subsystem.equals("ca"))
+ CryptoUtil.importUserCertificate(impl, nickname);
+ else
+ CryptoUtil.importUserCertificate(impl, nickname, false);
+ } catch (Exception ee) {
+ CMS.debug("CertRequestPanel: Failed to import user certificate."+ee.toString());
+ hasErr=true;
+ }
+ }
+
+ //update requests in request queue for local certs to allow renewal
+ if ((cert.getType().equals("local")) || (cert.getType().equals("selfsign"))) {
+ CertUtil.updateLocalRequest(config, certTag, cert.getRequest(), "pkcs10", null);
+ }
+
+ if (certTag.equals("signing") && subsystem.equals("ca")) {
+ String NickName = nickname;
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+ NickName = tokenname+ ":"+ nickname;
+
+ CMS.debug("CertRequestPanel update: set trust on CA signing cert "+NickName);
+ CryptoUtil.trustCertByNickname(NickName);
+ CMS.reinit(ICertificateAuthority.ID);
+ }
+ } //while loop
+
+ if (hasErr == false) {
+ config.putBoolean("preop.CertRequestPanel.done", true);
+ }
+ config.commit(false);
+ } catch (Exception e) {
+ CMS.debug("CertRequestPanel: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+
+ //reset the attribute of the user certificate to u,u,u
+ String certlist = "";
+ try {
+ certlist = config.getString("preop.cert.list", "");
+ StringTokenizer tokenizer = new StringTokenizer(certlist, ",");
+ CryptoManager cm = CryptoManager.getInstance();
+ while (tokenizer.hasMoreTokens()) {
+ String tag = tokenizer.nextToken();
+ if (tag.equals("signing"))
+ continue;
+ String nickname = config.getString("preop.cert."+tag+".nickname", "");
+ String tokenname = config.getString("preop.module.token", "");
+ if (!tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ X509Certificate c = cm.findCertByNickname(nickname);
+ if (c instanceof InternalCertificate) {
+ InternalCertificate ic = (InternalCertificate)c;
+ ic.setSSLTrust(InternalCertificate.USER);
+ ic.setEmailTrust(InternalCertificate.USER);
+ if (tag.equals("audit_signing")) {
+ ic.setObjectSigningTrust(InternalCertificate.USER | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER);
+ } else {
+ ic.setObjectSigningTrust(InternalCertificate.USER);
+ }
+ }
+ }
+ } catch (Exception e) {
+ }
+ if (!hasErr) {
+ context.put("updateStatus", "success");
+ } else {
+ context.put("updateStatus", "failure");
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Certificate Request");
+ context.put("panel", "admin/console/config/certrequestpanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
new file mode 100644
index 000000000..dc8adaf97
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
@@ -0,0 +1,652 @@
+// --- 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.servlet.csadmin;
+
+import java.security.*;
+import java.security.cert.*;
+import java.net.*;
+import java.util.*;
+import java.math.*;
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmsutil.http.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.usrgrp.*;
+import netscape.security.x509.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.crypto.PrivateKey;
+import com.netscape.cmsutil.xml.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import netscape.security.pkcs.*;
+import netscape.ldap.*;
+import org.apache.velocity.context.Context;
+import org.xml.sax.*;
+
+
+public class CertUtil {
+ static final int LINE_COUNT = 76;
+
+ public static X509CertImpl createRemoteCert(String hostname,
+ int port, String content, HttpServletResponse response, WizardPanelBase panel)
+ throws IOException {
+ HttpClient httpclient = new HttpClient();
+ String c = null;
+ CMS.debug("CertUtil createRemoteCert: content " + content);
+ try {
+ JssSSLSocketFactory factory = new JssSSLSocketFactory();
+
+ httpclient = new HttpClient(factory);
+ httpclient.connect(hostname, port);
+ HttpRequest httprequest = new HttpRequest();
+
+ httprequest.setMethod(HttpRequest.POST);
+ httprequest.setURI("/ca/ee/ca/profileSubmit");
+ httprequest.setHeader("user-agent", "HTTPTool/1.0");
+ httprequest.setHeader("content-length", "" + content.length());
+ httprequest.setHeader("content-type",
+ "application/x-www-form-urlencoded");
+ httprequest.setContent(content);
+ HttpResponse httpresponse = httpclient.send(httprequest);
+
+ c = httpresponse.getContent();
+ } catch (Exception e) {
+ CMS.debug("CertUtil createRemoteCert: " + e.toString());
+ throw new IOException(e.toString());
+ }
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "CertUtil::createRemoteCert() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+ String status = parser.getValue("Status");
+
+ CMS.debug("CertUtil createRemoteCert: status=" + status);
+ if (status.equals("2")) {
+ //relogin to the security domain
+ panel.reloginSecurityDomain(response);
+ return null;
+ } else if (!status.equals("0")) {
+ String error = parser.getValue("Error");
+ throw new IOException(error);
+ }
+
+ String b64 = parser.getValue("b64");
+
+ CMS.debug("CertUtil createRemoteCert: " + b64);
+ b64 = CryptoUtil.normalizeCertAndReq(b64);
+ byte[] b = CryptoUtil.base64Decode(b64);
+
+ return new X509CertImpl(b);
+ } catch (Exception e) {
+ CMS.debug("CertUtil createRemoteCert: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public static String getPKCS10(IConfigStore config, String prefix,
+ Cert certObj, Context context) throws IOException {
+ String certTag = certObj.getCertTag();
+
+ X509Key pubk = null;
+ try {
+ String pubKeyType = config.getString(
+ prefix + certTag + ".keytype");
+ String algorithm = config.getString(
+ prefix + certTag + ".keyalgorithm");
+ if (pubKeyType.equals("rsa")) {
+ String pubKeyModulus = config.getString(
+ prefix + certTag + ".pubkey.modulus");
+ String pubKeyPublicExponent = config.getString(
+ prefix + certTag + ".pubkey.exponent");
+ pubk = CryptoUtil.getPublicX509Key(
+ CryptoUtil.string2byte(pubKeyModulus),
+ CryptoUtil.string2byte(pubKeyPublicExponent));
+ } else if (pubKeyType.equals("ecc")) {
+ String pubKeyEncoded = config.getString(
+ prefix + certTag + ".pubkey.encoded");
+ pubk = CryptoUtil.getPublicX509ECCKey(
+ CryptoUtil.string2byte(pubKeyEncoded));
+ } else {
+ CMS.debug( "CertRequestPanel::getPKCS10() - "
+ + "public key type is unsupported!" );
+ throw new IOException( "public key type is unsupported" );
+ }
+
+ if (pubk != null) {
+ CMS.debug("CertRequestPanel: got public key");
+ } else {
+ CMS.debug("CertRequestPanel: error getting public key null");
+ throw new IOException( "public key is null" );
+ }
+ // get private key
+ String privKeyID = config.getString(prefix + certTag + ".privkey.id");
+ byte[] keyIDb = CryptoUtil.string2byte(privKeyID);
+
+ PrivateKey privk = CryptoUtil.findPrivateKeyFromID(keyIDb);
+
+ if (privk != null) {
+ CMS.debug("CertRequestPanel: got private key");
+ } else {
+ CMS.debug("CertRequestPanel: error getting private key null");
+ }
+
+ // construct cert request
+ String dn = config.getString(prefix + certTag + ".dn");
+
+ PKCS10 certReq = null;
+ certReq = CryptoUtil.createCertificationRequest(dn, pubk,
+ privk, algorithm);
+ byte[] certReqb = certReq.toByteArray();
+ String certReqs = CryptoUtil.base64Encode(certReqb);
+
+ return certReqs;
+ } catch (Throwable e) {
+ CMS.debug(e);
+ context.put("errorString", e.toString());
+ CMS.debug("CertUtil getPKCS10: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+
+/*
+ * create requests so renewal can work on these initial certs
+ */
+ public static IRequest createLocalRequest(IRequestQueue queue, String serialNum, X509CertInfo info) throws EBaseException {
+// RequestId rid = new RequestId(serialNum);
+ // just need a request, no need to get into a queue
+// IRequest r = new EnrollmentRequest(rid);
+ CMS.debug("CertUtil: createLocalRequest for serial: "+ serialNum);
+ IRequest req = queue.newRequest("enrollment");
+ CMS.debug("certUtil: newRequest called");
+ req.setExtData("profile", "true");
+ req.setExtData("requestversion", "1.0.0");
+ req.setExtData("req_seq_num", "0");
+ req.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ req.setExtData(IEnrollProfile.REQUEST_EXTENSIONS,
+ new CertificateExtensions());
+ req.setExtData("requesttype", "enrollment");
+ req.setExtData("requestor_name", "");
+ req.setExtData("requestor_email", "");
+ req.setExtData("requestor_phone", "");
+ req.setExtData("profileRemoteHost", "");
+ req.setExtData("profileRemoteAddr", "");
+ req.setExtData("requestnotes","");
+ req.setExtData("isencryptioncert", "false");
+ req.setExtData("profileapprovedby", "system");
+
+ // mark request as complete
+ CMS.debug("certUtil: calling setRequestStatus");
+ req.setRequestStatus(RequestStatus.COMPLETE);
+
+ return req;
+ }
+
+/**
+ * update local cert request with the actual request
+ * called from CertRequestPanel.java
+ */
+ public static void updateLocalRequest(IConfigStore config, String certTag, String certReq, String reqType, String subjectName)
+ {
+ try {
+ CMS.debug("Updating local request... certTag=" + certTag);
+ RequestId rid = new RequestId(config.getString("preop.cert." + certTag + ".reqId"));
+
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(
+ ICertificateAuthority.ID);
+
+ IRequestQueue queue = ca.getRequestQueue();
+ if (queue != null) {
+ IRequest req = queue.findRequest(rid);
+ if (req != null) {
+ if (!certReq.equals(""))
+ req.setExtData("cert_request", certReq);
+ req.setExtData("cert_request_type", reqType);
+ if (subjectName != null) {
+ req.setExtData("subject", subjectName);
+ X500Name x5Name = new X500Name(subjectName);
+ }
+ }
+ queue.updateRequest(req);
+ } else {
+ CMS.debug("CertUtil:updateLocalRequest - request queue = null");
+ }
+ } catch (Exception e) {
+ CMS.debug("CertUtil:updateLocalRequest - Exception:" + e.toString());
+ }
+ }
+
+/**
+ * reads from the admin cert profile caAdminCert.profile and takes the first
+ * entry in the list of allowed algorithms. Users that wish a different algorithm
+ * can specify it in the profile using default.params.signingAlg
+ */
+
+ public static String getAdminProfileAlgorithm(IConfigStore config) {
+ String algorithm = "SHA256withRSA";
+ try {
+ String caSigningKeyType = config.getString("preop.cert.signing.keytype","rsa");
+ String pfile = config.getString("profile.caAdminCert.config");
+ FileInputStream fis = new FileInputStream(pfile);
+ DataInputStream in = new DataInputStream(fis);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+
+ String strLine;
+ while ((strLine = br.readLine()) != null) {
+ String marker2 = "default.params.signingAlg=";
+ int indx = strLine.indexOf(marker2);
+ if (indx != -1) {
+ String alg = strLine.substring(indx + marker2.length());
+ if ((alg.length() > 0) && (!alg.equals("-"))) {
+ algorithm = alg;
+ break;
+ };
+ };
+
+ String marker = "signingAlgsAllowed=";
+ indx = strLine.indexOf(marker);
+ if (indx != -1) {
+ String[] algs = strLine.substring(indx + marker.length()).split(",");
+ for (int i=0; i<algs.length; i++) {
+ if ((caSigningKeyType.equals("rsa") && (algs[i].indexOf("RSA") != -1)) ||
+ (caSigningKeyType.equals("ecc") && (algs[i].indexOf("EC" ) != -1)) ) {
+ algorithm = algs[i];
+ break;
+ }
+ }
+ }
+ }
+ in.close();
+ } catch (Exception e) {
+ CMS.debug("getAdminProfleAlgorithm: exception: " + e);
+ }
+ return algorithm;
+ }
+
+ public static X509CertImpl createLocalCert(IConfigStore config, X509Key x509key,
+ String prefix, String certTag, String type, Context context) throws IOException {
+
+ CMS.debug("Creating local certificate... certTag=" + certTag);
+ String profile = null;
+
+ try {
+ profile = config.getString(prefix + certTag + ".profile");
+ } catch (Exception e) {}
+
+ X509CertImpl cert = null;
+ ICertificateAuthority ca = null;
+ ICertificateRepository cr = null;
+ RequestId reqId = null;
+ String profileId = null;
+ IRequestQueue queue = null;
+ IRequest req = null;
+
+ try {
+ String dn = config.getString(prefix + certTag + ".dn");
+ String keyAlgorithm = null;
+ Date date = new Date();
+
+ X509CertInfo info = null;
+
+ if (certTag.equals("admin")) {
+ keyAlgorithm = getAdminProfileAlgorithm(config);
+ } else {
+ keyAlgorithm = config.getString(prefix + certTag + ".keyalgorithm");
+ }
+ ca = (ICertificateAuthority) CMS.getSubsystem(
+ ICertificateAuthority.ID);
+ cr = (ICertificateRepository) ca.getCertificateRepository();
+ BigInteger serialNo = cr.getNextSerialNumber();
+ if (type.equals("selfsign")) {
+ CMS.debug("Creating local certificate... issuerdn=" + dn);
+ CMS.debug("Creating local certificate... dn=" + dn);
+ info = CryptoUtil.createX509CertInfo(x509key, serialNo.intValue(), dn, dn, date,
+ date, keyAlgorithm);
+ } else {
+ String issuerdn = config.getString("preop.cert.signing.dn", "");
+ CMS.debug("Creating local certificate... issuerdn=" + issuerdn);
+ CMS.debug("Creating local certificate... dn=" + dn);
+
+ info = CryptoUtil.createX509CertInfo(x509key,
+ serialNo.intValue(), issuerdn, dn, date, date, keyAlgorithm);
+ }
+ CMS.debug("Cert Template: " + info.toString());
+
+ String instanceRoot = config.getString("instanceRoot");
+
+ CertInfoProfile processor = new CertInfoProfile(
+ instanceRoot + "/conf/" + profile);
+
+ // cfu - create request to enable renewal
+ try {
+ queue = ca.getRequestQueue();
+ if (queue != null) {
+ req = createLocalRequest(queue, serialNo.toString(), info);
+ CMS.debug("CertUtil profile name= "+profile);
+ req.setExtData("req_key", x509key.toString());
+
+ // store original profile id in cert request
+ int idx = profile.lastIndexOf('.');
+ if (idx == -1) {
+ CMS.debug("CertUtil profileName contains no .");
+ req.setExtData("origprofileid", profile);
+ } else {
+ String name = profile.substring(0, idx);
+ req.setExtData("origprofileid", name);
+ }
+
+ // store mapped profile ID for use in renewal
+ profileId = processor.getProfileIDMapping();
+ req.setExtData("profileid", profileId);
+ req.setExtData("profilesetid", processor.getProfileSetIDMapping());
+
+ reqId = req.getRequestId();
+ config.putString("preop.cert." + certTag + ".reqId", reqId.toString());
+ } else {
+ CMS.debug("certUtil: requestQueue null");
+ }
+ } catch (Exception e) {
+ CMS.debug("Creating local request exception:"+e.toString());
+ }
+
+ processor.populate(info);
+
+ String caPriKeyID = config.getString(
+ prefix + "signing" + ".privkey.id");
+ byte[] keyIDb = CryptoUtil.string2byte(caPriKeyID);
+ PrivateKey caPrik = CryptoUtil.findPrivateKeyFromID(
+ keyIDb);
+
+ if( caPrik == null ) {
+ CMS.debug( "CertUtil::createSelfSignedCert() - "
+ + "CA private key is null!" );
+ throw new IOException( "CA private key is null" );
+ } else {
+ CMS.debug("CertUtil createSelfSignedCert: got CA private key");
+ }
+
+ String keyAlgo = x509key.getAlgorithm();
+ CMS.debug("key algorithm is " + keyAlgo);
+ String caSigningKeyType =
+ config.getString("preop.cert.signing.keytype","rsa");
+ String caSigningKeyAlgo = "";
+ if (type.equals("selfsign")) {
+ caSigningKeyAlgo = config.getString("preop.cert.signing.keyalgorithm","SHA256withRSA");
+ } else {
+ caSigningKeyAlgo = config.getString("preop.cert.signing.signingalgorithm","SHA256withRSA");
+ }
+
+ CMS.debug("CA Signing Key type " + caSigningKeyType);
+ CMS.debug("CA Signing Key algorithm " + caSigningKeyAlgo);
+
+ if (caSigningKeyType.equals("ecc")) {
+ CMS.debug("CA signing cert is ECC");
+ cert = CryptoUtil.signECCCert(caPrik, info,
+ caSigningKeyAlgo);
+ } else {
+ CMS.debug("CA signing cert is not ecc");
+ cert = CryptoUtil.signCert(caPrik, info,
+ caSigningKeyAlgo);
+ }
+
+ if (cert != null) {
+ CMS.debug("CertUtil createSelfSignedCert: got cert signed");
+ }
+ } catch (Exception e) {
+ CMS.debug(e);
+ CMS.debug("NamePanel configCert() exception caught:" + e.toString());
+ }
+
+ if (cr == null) {
+ context.put("errorString",
+ "Ceritifcate Authority is not ready to serve.");
+ throw new IOException("Ceritifcate Authority is not ready to serve.");
+ }
+
+ ICertRecord record = null;
+ try {
+ MetaInfo meta = new MetaInfo();
+ if (reqId != null) {
+ meta.set(ICertRecord.META_REQUEST_ID, reqId.toString());
+ }
+
+ meta.set(ICertRecord.META_PROFILE_ID, profileId);
+ record = (ICertRecord) cr.createCertRecord(
+ cert.getSerialNumber(), cert, meta);
+ } catch (Exception e) {
+ CMS.debug(
+ "NamePanel configCert: failed to add metainfo. Exception: " + e.toString());
+ }
+
+ try {
+ cr.addCertificateRecord(record);
+ CMS.debug(
+ "NamePanel configCert: finished adding certificate record.");
+ } catch (Exception e) {
+ CMS.debug(
+ "NamePanel configCert: failed to add certificate record. Exception: "
+ + e.toString());
+ try {
+ cr.deleteCertificateRecord(record.getSerialNumber());
+ cr.addCertificateRecord(record);
+ } catch (Exception ee) {
+ CMS.debug("NamePanel update: Exception: " + ee.toString());
+ }
+ }
+
+ if (req != null) {
+ // update request with cert
+ req.setExtData(IEnrollProfile.REQUEST_ISSUED_CERT, cert);
+
+ // store request in db
+ try {
+ CMS.debug("certUtil: before updateRequest");
+ if (queue != null) {
+ queue.updateRequest(req);
+ }
+ } catch (Exception e) {
+ CMS.debug("Exception in updateRequest" + e);
+ }
+ }
+
+ return cert;
+ }
+
+ public static void addUserCertificate(X509CertImpl cert) {
+ IConfigStore cs = CMS.getConfigStore();
+ int num=0;
+ try {
+ num = cs.getInteger("preop.subsystem.count", 0);
+ } catch (Exception e) {
+ }
+ IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+ String id = "user"+num;
+
+ try {
+ String sysType = cs.getString("cs.type", "");
+ String machineName = cs.getString("machineName", "");
+ String securePort = cs.getString("service.securePort", "");
+ id = sysType + "-" + machineName + "-" + securePort;
+ } catch (Exception e1) {
+ // ignore
+ }
+
+ num++;
+ cs.putInteger("preop.subsystem.count", num);
+ cs.putInteger("subsystem.count", num);
+
+ try {
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+
+ IUser user = null;
+ X509CertImpl[] certs = new X509CertImpl[1];
+ CMS.debug("CertUtil addUserCertificate starts");
+ try {
+ user = system.createUser(id);
+ user.setFullName(id);
+ user.setEmail("");
+ user.setPassword("");
+ user.setUserType("agentType");
+ user.setState("1");
+ user.setPhone("");
+ certs[0] = cert;
+ user.setX509Certificates(certs);
+ system.addUser(user);
+ CMS.debug("CertUtil addUserCertificate: successfully add the user");
+ } catch (LDAPException e) {
+ CMS.debug("CertUtil addUserCertificate" + e.toString());
+ if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+ try {
+ user = system.getUser(id);
+ user.setX509Certificates(certs);
+ } catch (Exception ee) {
+ CMS.debug("CertUtil addUserCertificate: successfully find the user");
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("CertUtil addUserCertificate addUser " + e.toString());
+ }
+
+ try {
+ system.addUserCert(user);
+ CMS.debug("CertUtil addUserCertificate: successfully add the user certificate");
+ } catch (Exception e) {
+ CMS.debug("CertUtil addUserCertificate exception="+e.toString());
+ }
+
+ IGroup group = null;
+ String groupName = "Subsystem Group";
+
+ try {
+ group = system.getGroupFromName(groupName);
+ if (!group.isMember(id)) {
+ group.addMemberName(id);
+ system.modifyGroup(group);
+ CMS.debug("CertUtil addUserCertificate: update: successfully added the user to the group.");
+ }
+ } catch (Exception e) {
+ CMS.debug("CertUtil addUserCertificate update: modifyGroup " + e.toString());
+ }
+ }
+
+ /*
+ * formats a cert fingerprints
+ */
+ public static String fingerPrintFormat(String content) {
+ if (content == null || content.length() == 0) {
+ return "";
+ }
+
+ StringBuffer result = new StringBuffer();
+ result.append("Fingerprints:\n");
+ int index = 0;
+
+ while (content.length() >= LINE_COUNT) {
+ result.append(content.substring(0, LINE_COUNT));
+ result.append("\n");
+ content = content.substring(LINE_COUNT);
+ }
+ if (content.length() > 0)
+ result.append(content);
+ result.append("\n");
+
+ return result.toString();
+ }
+
+ public static boolean privateKeyExistsOnToken(String certTag,
+ String tokenname, String nickname) {
+ IConfigStore cs = CMS.getConfigStore();
+ String givenid = "";
+ try {
+ givenid = cs.getString("preop.cert."+certTag+".privkey.id");
+ } catch (Exception e) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: we did not generate private key yet.");
+ return false;
+ }
+
+ String fullnickname = nickname;
+
+ boolean hardware = false;
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) {
+ hardware = true;
+ fullnickname = tokenname+":"+nickname;
+ }
+
+ X509Certificate cert = null;
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ cert = cm.findCertByNickname(fullnickname);
+ } catch (Exception e) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: nickname="+fullnickname+" Exception:"+e.toString());
+ return false;
+ }
+
+ PrivateKey privKey = null;
+ try {
+ privKey = cm.findPrivKeyByCert(cert);
+ } catch (Exception e) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: cant find private key ("+fullnickname+") exception: "+e.toString());
+ return false;
+ }
+
+ if (privKey == null) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: cant find private key ("+fullnickname+")");
+ return false;
+ } else {
+ String str = "";
+ try {
+ str = CryptoUtil.byte2string(privKey.getUniqueID());
+ } catch (Exception e) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: encode string Exception: "+e.toString());
+ }
+
+ if (str.equals(givenid)) {
+ CMS.debug("CertUtil privateKeyExistsOnToken: find the private key on the token.");
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java
new file mode 100644
index 000000000..829e46a44
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java
@@ -0,0 +1,115 @@
+// --- 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.servlet.csadmin;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+
+public class CheckIdentity extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public CheckIdentity() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ CMS.debug("CheckIdentity init");
+ }
+
+ /**
+ * Process the HTTP request.
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+
+ try {
+ authToken = authenticate(cmsReq);
+ } catch (Exception e) {
+ CMS.debug("CheckIdentity authentication failed");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, "Error: Not authenticated");
+ return;
+ }
+
+ try {
+ XMLObject xmlObj = null;
+
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {
+ // do nothing, ie, it will not return the default javascript.
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java
new file mode 100644
index 000000000..8017a893f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java
@@ -0,0 +1,117 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.apps.*;
+
+
+public abstract class ConfigBaseServlet extends BaseServlet {
+ public boolean isDisplayMode(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String display = request.getParameter("display");
+
+ if (display == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public abstract void display(HttpServletRequest request,
+ HttpServletResponse response, Context context);
+
+ public abstract void update(HttpServletRequest request,
+ HttpServletResponse response, Context context);
+
+ public abstract Template getTemplate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context);
+
+ public void outputHttpParameters(HttpServletRequest httpReq) {
+ CMS.debug("ConfigBaseServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String pn = (String) paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("ConfigBaseServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("ConfigBaseServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+ /**
+ * Processes request.
+ */
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ if (CMS.debugOn()) {
+ outputHttpParameters(request);
+ }
+
+ if (isDisplayMode(request, response, context)) {
+ display(request, response, context);
+ } else {
+ update(request, response, context);
+ }
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = getTemplate(request, response, context);
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java
new file mode 100644
index 000000000..6acb71273
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java
@@ -0,0 +1,37 @@
+// --- 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.servlet.csadmin;
+
+import java.util.*;
+import com.netscape.certsrv.apps.CMS;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.ssl.*;
+
+
+public class ConfigCertApprovalCallback
+ implements SSLCertificateApprovalCallback {
+
+ public ConfigCertApprovalCallback() {
+ }
+
+ public boolean approve(X509Certificate cert,
+ SSLCertificateApprovalCallback.ValidityStatus status) {
+ return true;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java
new file mode 100644
index 000000000..0a9d9a9cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java
@@ -0,0 +1,46 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class ConfigCertReqServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = Velocity.getTemplate(
+ "admin/console/config/config_certreq.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java
new file mode 100644
index 000000000..73150946b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java
@@ -0,0 +1,46 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class ConfigCloneServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = Velocity.getTemplate(
+ "admin/console/config/config_clone.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java
new file mode 100644
index 000000000..56da3a232
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java
@@ -0,0 +1,190 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import java.io.*;
+
+
+public class ConfigDatabaseServlet extends ConfigBaseServlet {
+
+ private static final String HOST = "localhost";
+ private static final String PORT = "389";
+ private static final String BASEDN = "o=netscapeCertificateServer";
+ private static final String BINDDN = "cn=Directory Manager";
+ private static final String DATABASE = "userRoot";
+
+ public boolean isPanelModified() {
+ IConfigStore cs = CMS.getConfigStore();
+ String modified = "";
+
+ try {
+ modified = cs.getString("preop.configDatabase.modified", "");
+ } catch (Exception e) {}
+
+ if (modified.equals("true")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String hostname = null;
+ String portStr = null;
+ String basedn = null;
+ String binddn = null;
+ String bindpwd = "";
+ String database = null;
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ if (isPanelModified()) {
+ try {
+ hostname = cs.getString("internaldb.ldapconn.host", "");
+ portStr = cs.getString("internaldb.ldapconn.port", "");
+ basedn = cs.getString("internaldb.basedn", "");
+ binddn = cs.getString("internaldb.ldapauth.bindDN", "");
+ database = cs.getString("internaldb.database", "");
+ } catch (Exception e) {}
+ } else {
+ hostname = HOST;
+ portStr = PORT;
+ basedn = BASEDN;
+ binddn = BINDDN;
+ database = DATABASE;
+ }
+
+ context.put("hostname", hostname);
+ context.put("portStr", portStr);
+ context.put("basedn", basedn);
+ context.put("binddn", binddn);
+ context.put("bindpwd", bindpwd);
+ context.put("database", database);
+ context.put("displayStr", "initial");
+ context.put("errorString", "");
+ }
+
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ IConfigStore cs = CMS.getConfigStore();
+ String errorString = "";
+ String hostname = request.getParameter("host");
+
+ if (hostname != null && hostname.length() > 0) {
+ cs.putString("internaldb.ldapconn.host", hostname);
+ } else {
+ errorString = "Host is empty string";
+ }
+
+ String portStr = request.getParameter("port");
+
+ if (portStr != null && portStr.length() > 0) {
+ int port = -1;
+
+ try {
+ port = Integer.parseInt(portStr);
+ cs.putInteger("internaldb.ldapconn.port", port);
+ } catch (Exception e) {
+ errorString = "Port is invalid";
+ }
+ } else {
+ errorString = "Port is empty string";
+ }
+
+ String basedn = request.getParameter("basedn");
+
+ if (basedn != null && basedn.length() > 0) {
+ cs.putString("internaldb.basedn", basedn);
+ } else {
+ errorString = "Base DN is empty string";
+ }
+
+ String binddn = request.getParameter("binddn");
+
+ if (binddn != null && binddn.length() > 0) {
+ cs.putString("internaldb.ldapauth.bindDN", binddn);
+ } else {
+ errorString = "Bind DN is empty string";
+ }
+
+ String database = request.getParameter("database");
+
+ if (database != null && database.length() > 0) {
+ cs.putString("internaldb.database", database);
+ } else {
+ errorString = "Database is empty string";
+ }
+
+ String bindpwd = request.getParameter("__bindpwd");
+ IConfigStore psStore = null;
+
+ if (bindpwd != null && bindpwd.length() > 0) {
+ String passwordFile = null;
+
+ try {
+ passwordFile = cs.getString("passwordFile");
+ psStore = CMS.createFileConfigStore(passwordFile);
+ } catch (Exception e) {
+ CMS.debug("ConfigDatabaseServlet update: " + e.toString());
+ return;
+ }
+ psStore.putString("internaldb", bindpwd);
+ } else {
+ errorString = "Bind password is empty string";
+ }
+
+ cs.putString("preop.configDatabase.modified", "true");
+ if (errorString.equals("")) {
+ try {
+ psStore.commit(false);
+ cs.commit(false);
+ } catch (Exception e) {
+ CMS.debug("ConfigDatabaseServlet update: " + e.toString());
+ }
+ }
+
+ context.put("hostname", hostname);
+ context.put("portStr", portStr);
+ context.put("basedn", basedn);
+ context.put("binddn", binddn);
+ context.put("bindpwd", bindpwd);
+ context.put("database", database);
+ context.put("displayStr", "loaded");
+ context.put("errorString", errorString);
+ }
+
+ public Template getTemplate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ try {
+ return Velocity.getTemplate("admin/console/config/config_db.vm");
+ } catch (Exception e) {}
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
new file mode 100644
index 000000000..caee8c1d4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
@@ -0,0 +1,318 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+import javax.servlet.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.property.*;
+import com.netscape.cmsutil.crypto.*;
+import java.util.*;
+import java.io.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs11.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import com.netscape.cmsutil.password.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class ConfigHSMLoginPanel extends WizardPanelBase {
+ private CryptoManager mCryptoManager = null;
+ private String mPwdFilePath = "";
+
+ public ConfigHSMLoginPanel() {}
+
+ public void init(ServletConfig config, int panelno) throws ServletException {
+ try {
+ mCryptoManager = CryptoManager.getInstance();
+ mPwdFilePath = CMS.getConfigStore().getString(
+ "passwordFile");
+ } catch (Exception e) {
+ CMS.debug("ConfigHSMLoginPanel: " + e.toString());
+ }
+ setPanelNo(panelno);
+ setName("ConfigHSMLogin");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id) throws ServletException {
+ try {
+ mCryptoManager = CryptoManager.getInstance();
+ mPwdFilePath = CMS.getConfigStore().getString(
+ "passwordFile");
+ } catch (Exception e) {
+ CMS.debug("ConfigHSMLoginPanel: " + e.toString());
+ }
+ setPanelNo(panelno);
+ setName("ConfigHSMLogin");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ public boolean isPanelDone() {
+ return true;
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ public boolean isLoopbackPanel() {
+ return true;
+ }
+
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ CMS.debug("ConfigHSMLoginPanel: in display()");
+ context.put("title", "Security Module Login");
+
+ // get token selected to be logged in
+ String tokName = null;
+ try {
+ tokName = HttpInput.getTokenName(request, "SecToken");
+ } catch (IOException e) {
+ }
+
+ if (tokName != null) {
+ CMS.debug("ConfigHSMLoginPanel: selected token name= " + tokName);
+ } else {
+ CMS.debug("ConfigHSMLoginPanel: missing SecToken name");
+ context.put("error", "noTokenName");
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ return;
+ }
+ CryptoToken token = null;
+
+ try {
+ token = mCryptoManager.getTokenByName(tokName);
+ } catch (Exception e) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: getTokenByName() failed: "
+ + e.toString());
+ context.put("error", "tokenNotFound:" + tokName);
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ return;
+ }
+ // first see if password in password file, try to login
+ PlainPasswordReader pr = new PlainPasswordReader();
+
+ try {
+ pr.init(mPwdFilePath);
+ } catch (Exception e) {
+ // is ok to not have it
+ CMS.debug("ConfigHSMLoginPanel: passwrd file path: " + e.toString());
+ }
+ CMS.debug("ConfigHSMLoginPanel: checking if passwd in cache");
+ String tokPwd = pr.getPassword("hardware-"+tokName);
+
+ boolean loggedIn = false;
+
+ if (tokPwd == null) {
+ CMS.debug("ConfigHSMLoginPanel: passwd not in cache");
+ } else {
+ loggedIn = loginToken(token, tokPwd, context);
+ }
+
+ if (!loggedIn) {
+ context.put("status", "display");
+ }
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ context.put("SecToken", tokName);
+ }
+
+ // if logged in successfully, returns true
+ private boolean loginToken(CryptoToken token, String tokPwd, Context context) {
+ boolean rv = true;
+ Password password = null;
+
+ password = new Password(tokPwd.toCharArray());
+
+ if (password != null) {
+ try {
+ if (token.passwordIsInitialized()) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: loginToken():token password is initialized");
+ if (!token.isLoggedIn()) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: loginToken():Token is not logged in, try it");
+ token.login(password);
+ context.put("status", "justLoggedIn");
+ } else {
+ CMS.debug(
+ "ConfigHSMLoginPanel:Token has already logged on");
+ context.put("status", "alreadyLoggedIn");
+ }
+ } else {
+ CMS.debug(
+ "ConfigHSMLoginPanel: loginToken():Token password not initialized");
+ context.put("status", "tokenPasswordNotInitialized");
+ rv = false;
+ }
+
+ } catch (IncorrectPasswordException e) {
+ context.put("status", "incorrectPassword");
+ context.put("errorString", e.toString());
+ CMS.debug("ConfigHSMLoginPanel: loginToken():" + e.toString());
+ rv = false;
+ } catch (Exception e) {
+ CMS.debug("ConfigHSMLoginPanel: loginToken():" + e.toString());
+ context.put("errorString", e.toString());
+ rv = false;
+ }
+ } else { // no password in password file, get from user
+ CMS.debug(
+ "ConfigHSMLoginPanel: loginToken():no password in cache, getting from user");
+ rv = false;
+ }
+ return rv;
+ }
+
+ // XXX how do you do this?
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ Descriptor choiceDesc = new Descriptor(IDescriptor.CHOICE, "", "", null); /* no default parameters */
+
+ set.add(
+ "choice", choiceDesc);
+
+ return set;
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ IConfigStore cs = CMS.getConfigStore();
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+// if (select.equals("clone"))
+ // return;
+
+ CMS.debug("ConfigHSMLoginPanel: in update()");
+
+ String uTokName = null;
+ String uPasswd = null;
+ try {
+ uTokName = HttpInput.getTokenName(request, "uTokName");
+ uPasswd = HttpInput.getPassword(request, "__uPasswd");
+ } catch (Exception e) {
+ }
+
+ if (uPasswd == null) {
+ CMS.debug("ConfigHSMLoginPanel: password not found");
+ context.put("error", "no password");
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ context.put("updateStatus", "no password");
+ return;
+ } else {
+ CMS.debug("ConfigHSMLoginPanel: got password");
+
+ CryptoToken token = null;
+
+ try {
+ token = mCryptoManager.getTokenByName(uTokName);
+ } catch (Exception e) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: getTokenByName() failed: "
+ + e.toString());
+ context.put("error", "tokenNotFound:" + uTokName);
+ }
+
+ try {
+ if (loginToken(token, uPasswd, context) == false) {
+ CMS.debug(
+ "ConfigHSMLoginPanel:loginToken failed for "
+ + uTokName);
+ context.put("error", "tokenLoginFailed");
+ context.put("updateStatus", "login failed");
+ context.put("panel",
+ "admin/console/config/config_hsmloginpanel.vm");
+ return;
+ }
+ CMS.debug(
+ "ConfigHSMLoginPanel: update(): just logged in successfully");
+ PlainPasswordWriter pw = new PlainPasswordWriter();
+
+ pw.init(mPwdFilePath);
+ pw.putPassword("hardware-"+uTokName, uPasswd);
+ pw.commit();
+
+ } catch (FileNotFoundException e) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: update(): Exception caught: "
+ + e.toString() + " writing to "+ mPwdFilePath);
+ CMS.debug(
+ "ConfigHSMLoginPanel: update(): password not written to cache");
+ System.err.println("Exception caught: " + e.toString());
+ context.put("error", "Exception:" + e.toString());
+ } catch (Exception e) {
+ CMS.debug(
+ "ConfigHSMLoginPanel: update(): Exception caught: "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ context.put("error", "Exception:" + e.toString());
+ }
+
+ } // found password
+
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ context.put("status", "update");
+ context.put("error", "");
+ context.put("updateStatus", "success");
+
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Security Module Login");
+ context.put("panel", "admin/console/config/config_hsmloginpanel.vm");
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java
new file mode 100644
index 000000000..536dfe770
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java
@@ -0,0 +1,287 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+import javax.servlet.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmsutil.crypto.*;
+import java.util.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs11.*;
+
+
+public class ConfigHSMServlet extends ConfigBaseServlet {
+ private CryptoManager mCryptoManager = null;
+ private Vector mSupportedModules = null;
+ private Vector mOtherModules = null;
+ private String mDefaultTok = null;
+ private Hashtable mCurrModTable = new Hashtable();
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ }
+
+ public void loadCurrModTable() {
+ try {
+ // getting existing modules
+ mCryptoManager = CryptoManager.getInstance();
+ Enumeration modules = mCryptoManager.getModules();
+
+ while (modules.hasMoreElements()) {
+ PK11Module mod = (PK11Module) modules.nextElement();
+
+ CMS.debug("ConfigHSMServlet: got module " + mod.getName());
+ mCurrModTable.put(mod.getName(), mod);
+ } // while
+ } catch (Exception e) {
+ CMS.debug(
+ "ConfigHSMServlet: Exception caught in loadCurrModTable: "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ }
+
+ /*
+ * Modules not listed as supported modules
+ */
+ public void loadOtherModules() {
+ Enumeration m = mCurrModTable.elements();
+
+ mOtherModules = new Vector();
+ while (m.hasMoreElements()) {
+ PK11Module mod = (PK11Module) m.nextElement();
+ Enumeration s = mSupportedModules.elements();
+ boolean found = false;
+
+ while (s.hasMoreElements()) {
+ Module sm = (Module) s.nextElement();
+
+ if (mod.getName().equals(sm.getCommonName())) {
+ found = true;
+ break;
+ } else {
+ found = false;
+ }
+ }// while
+ if (!found) {
+ // unsupported, use common name as user friendly name
+ Module module = new Module(mod.getName(), mod.getName());
+
+ loadModTokens(module, mod);
+ module.setFound(true);
+ mOtherModules.addElement((Object) module);
+ break;
+ }
+ }// while
+ }
+
+ /*
+ * find all tokens belonging to a module and load the Module
+ */
+ public void loadModTokens(Module module, PK11Module mod) {
+ Enumeration tokens = mod.getTokens();
+
+ while (tokens.hasMoreElements()) {
+ try {
+ CryptoToken token = (CryptoToken) tokens.nextElement();
+
+ CMS.debug("ConfigHSMServlet: token nick name=" + token.getName());
+ CMS.debug(
+ "ConfigHSMServlet: token logged in?"
+ + token.isLoggedIn());
+ CMS.debug(
+ "ConfigHSMServlet: token is present?"
+ + token.isPresent());
+ if (!token.getName().equals("Internal Crypto Services Token")) {
+ module.addToken(token);
+ } else {
+ CMS.debug(
+ "ConfigHSMServlet: token " + token.getName()
+ + " not to be added");
+ }
+
+ } catch (TokenException ex) {
+ CMS.debug("ConfigHSMServlet:" + ex.toString());
+ }
+ }
+ }
+
+ /*
+ * Modules unsupported by the system will not be included
+ */
+ public void loadSupportedModules() {
+
+ // getting supported security modules
+ // a Vectgor of Modules
+ mSupportedModules = new Vector();
+ // read from conf store all supported modules
+ try {
+ int count = CMS.getConfigStore().getInteger(
+ "preop.configModules.count");
+
+ CMS.debug("ConfigHSMServlet: supported modules count= " + count);
+ for (int i = 0; i < count; i++) {
+ String cn = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".commonName");
+ String pn = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".userFriendlyName");
+ String img = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".imagePath");
+
+ if ((cn == null) || (cn.equals(""))) {
+ break;
+ }
+
+ CMS.debug("ConfigHSMServlet: got from config module: " + cn);
+ // create a Module object
+ Module module = new Module(cn, pn, img);
+
+ if (mCurrModTable.containsKey(cn)) {
+ CMS.debug("ConfigHSMServlet: module found: " + cn);
+ module.setFound(true);
+ // add token info to module vector
+ PK11Module m = (PK11Module) mCurrModTable.get(cn);
+
+ loadModTokens(module, m);
+ }
+
+ CMS.debug("ConfigHSMServlet: adding module " + cn);
+ // add module to set
+ if (!mSupportedModules.contains(module)) {
+ mSupportedModules.addElement((Object) module);
+ }
+ }// for
+
+ } catch (Exception e) {
+ CMS.debug(
+ "ConfigHSMServlet: Exception caught in loadSupportedModules(): "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ }
+
+ public boolean isDisplayMode(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String choice = request.getParameter("choice");
+
+ if (choice == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isPanelModified(IConfigStore cs) {
+ String modified = "";
+
+ try {
+ modified = cs.getString("preop.configModules.modified", "");
+ } catch (Exception e) {
+ return false;
+ }
+
+ if (modified.equals("true")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("ConfigHSMServlet: in display()");
+
+ loadCurrModTable();
+ loadSupportedModules();
+ loadOtherModules();
+ // getting default token selection
+ try {
+ mDefaultTok = CMS.getConfigStore().getString(
+ "preop.configModules.defaultTok",
+ "Internal Key Storage Token");
+ } catch (Exception e) {
+ CMS.debug("ConfigHSMServlet: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ if (mSupportedModules == null) {
+ CMS.debug("ConfigHSMServlet: mSupportedModules not loaded");
+ } else {
+ CMS.debug("ConfigHSMServlet: mSupportedModules loaded");
+ }
+
+ context.put("status", "display");
+ context.put("oms", mOtherModules);
+ context.put("sms", mSupportedModules);
+ context.put("defTok", mDefaultTok);
+ }
+
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ CMS.debug("ConfigHSMServlet: in update()");
+
+ if (mSupportedModules == null) {
+ CMS.debug("ConfigHSMServlet: mSupportedModules not loaded");
+ } else {
+ CMS.debug("ConfigHSMServlet: mSupportedModules loaded");
+ }
+
+ String select = request.getParameter("choice");
+
+ if (select == null) {
+ CMS.debug("ConfigHSMServlet: choice not found");
+ // throw new IOException("choice not found");
+ }
+
+ try {
+ CMS.debug("ConfigHSMServlet: choice =" + select);
+ cs.putString("preop.configModules.defaultTok", select);
+ cs.commit(false);
+ } catch (Exception e) {
+ CMS.debug("ConfigHSMServlet: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ context.put("status", "update");
+ context.put("error", "");
+
+ }
+
+ public Template getTemplate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ try {
+ return Velocity.getTemplate("admin/console/config/config_hsm.vm");
+ } catch (Exception e) {}
+ return null;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java
new file mode 100644
index 000000000..892d24584
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java
@@ -0,0 +1,46 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class ConfigImportCertServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = Velocity.getTemplate(
+ "admin/console/config/config_importcert.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java
new file mode 100644
index 000000000..b22178b48
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java
@@ -0,0 +1,185 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.cmsutil.crypto.*;
+
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+
+import java.util.*;
+import java.io.*;
+
+import java.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+
+
+public class ConfigJoinServlet extends ConfigBaseServlet {
+
+ public boolean isDisplayMode(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String cert = request.getParameter("cert");
+
+ if (cert == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isPanelModified() {
+ IConfigStore config = CMS.getConfigStore();
+
+ String cert = null;
+
+ try {
+ cert = config.getString("preop.join.cert", null);
+ } catch (EBaseException e) {}
+ if (cert == null || cert.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Displays panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ IConfigStore config = CMS.getConfigStore();
+
+ try {
+ String pubKeyModulus = config.getString(
+ "preop.keysize.pubKeyModulus");
+ String pubKeyPublicExponent = config.getString(
+ "preop.keysize.pubKeyPublicExponent");
+ String dn = config.getString("preop.name.dn");
+ String priKeyID = config.getString("preop.keysize.priKeyID");
+ String pkcs10 = CryptoUtil.getPKCS10FromKey(dn,
+ CryptoUtil.string2byte(pubKeyModulus),
+ CryptoUtil.string2byte(pubKeyPublicExponent),
+ CryptoUtil.string2byte(priKeyID));
+ context.put("certreq", pkcs10);
+ } catch (Exception e) {}
+
+ String select = "auto";
+ boolean select_manual = true;
+
+ if (isPanelModified()) {
+ try {
+ select = config.getString("preop.join.select", null);
+ } catch (EBaseException e) {
+ CMS.debug( "ConfigJoinServlet::display() - "
+ + "Exception="+e.toString() );
+ return;
+ }
+ if (select.equals("auto")) {
+
+ /* automated enrollment */
+ select_manual = false;
+ } else {
+ try {
+
+ /* manual enrollment */
+ String cert = config.getString("preop.join.cert", "");
+
+ context.put("cert", cert);
+ } catch (EBaseException e) {}
+ }
+ } else {
+ context.put("cert", "");
+ }
+ if (select_manual) {
+ context.put("check_manual", "checked");
+ context.put("check_auto", "");
+ } else {
+ context.put("check_manual", "");
+ context.put("check_auto", "checked");
+ }
+ context.put("status", "display");
+ }
+
+ /**
+ * Updates panel.
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("JoinServlet: update");
+ IConfigStore config = CMS.getConfigStore();
+ String select = request.getParameter("choice");
+
+ try {
+ if (select.equals("manual")) {
+
+ /* manual enrollment */
+ CMS.debug("JoinServlet: manual");
+ String certchain = request.getParameter("cert");
+
+ config.putString("preop.join.cert", certchain);
+ } else if (select.equals("auto")) {
+ CMS.debug("JoinServlet: auto");
+
+ /* automated enrollment */
+ String url = request.getParameter("url");
+ String uid = request.getParameter("uid");
+ String pwd = request.getParameter("__pwd");
+
+ config.putString("preop.join.url", url);
+ config.putString("preop.join.uid", uid);
+ config.putString("preop.join.pwd", pwd);
+
+ /* XXX - submit request to the CA, and import it automatically */
+ config.putString(
+ "preop.join.cert", ""); /* store the chain */
+ }
+ config.putString("preop.join.select", select);
+ config.commit(false);
+ } catch (Exception e) {}
+ }
+
+ public Template getTemplate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ Template template = null;
+
+ try {
+ template = Velocity.getTemplate(
+ "admin/console/config/config_join.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java
new file mode 100644
index 000000000..e07ea3c3b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java
@@ -0,0 +1,135 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.profile.*;
+
+import java.util.*;
+
+
+public class ConfigRootCAServlet extends ConfigBaseServlet {
+
+ public boolean isDisplayMode(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String profile = request.getParameter("profile");
+
+ if (profile == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isPanelModified() {
+ IConfigStore config = CMS.getConfigStore();
+
+ String profile = null;
+
+ try {
+ profile = config.getString("preop.hierarchy.profile", null);
+ } catch (EBaseException e) {}
+ if (profile == null || profile.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public Vector getProfiles() {
+ IConfigStore config = CMS.getConfigStore();
+ String instancePath = "";
+
+ try {
+ instancePath = config.getString("instanceRoot");
+ } catch (EBaseException e) {}
+ String p[] = { "caCert.profile" };
+ Vector profiles = new Vector();
+
+ for (int i = 0; i < p.length; i++) {
+ try {
+ profiles.addElement(
+ new CertInfoProfile(instancePath + "/conf/" + p[i]));
+ } catch (Exception e) {}
+ }
+ return profiles;
+ }
+
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ IConfigStore config = CMS.getConfigStore();
+ String profile = null;
+
+ if (isPanelModified()) {
+ try {
+ profile = config.getString("preop.hierarchy.profile", null);
+ } catch (EBaseException e) {}
+ }
+ if (profile == null) {
+ profile = "caCert.profile";
+ }
+ Vector profiles = getProfiles();
+
+ context.put("status", "display");
+ context.put("profiles", profiles);
+ context.put("selected_profile_id", profile);
+ }
+
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ String profile = request.getParameter("profile");
+ IConfigStore config = CMS.getConfigStore();
+
+ config.putString("preop.hierarchy.profile", profile);
+ try {
+ config.commit(false);
+ } catch (Exception e) {}
+ context.put("status", "update");
+ context.put("error", "");
+ Vector profiles = getProfiles();
+
+ context.put("profiles", profiles);
+ context.put("selected_profile_id", profile);
+ }
+
+ public Template getTemplate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ Template template = null;
+
+ try {
+ template = Velocity.getTemplate(
+ "admin/console/config/config_rootca.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java
new file mode 100644
index 000000000..a99969880
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java
@@ -0,0 +1,302 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.mozilla.jss.crypto.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmsutil.crypto.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class CreateSubsystemPanel extends WizardPanelBase {
+
+ public CreateSubsystemPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Subsystem Selection");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Subsystem Type");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.subsystem.select", "");
+ cs.putString("subsystem.select", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.subsystem.select", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Subsystem Type");
+ IConfigStore config = CMS.getConfigStore();
+ String session_id = request.getParameter("session_id");
+ if (session_id != null) {
+ CMS.debug("CreateSubsystemPanel setting session id.");
+ CMS.setConfigSDSessionId(session_id);
+ }
+
+ String errorString = "";
+ String url = "";
+
+ if (isPanelDone()) {
+ try {
+ String s = config.getString("preop.subsystem.select");
+
+ if (s.equals("new")) {
+ context.put("check_newsubsystem", "checked");
+ context.put("check_clonesubsystem", "");
+ } else if (s.equals("clone")) {
+ context.put("check_newsubsystem", "");
+ context.put("check_clonesubsystem", "checked");
+ }
+ context.put("subsystemName",
+ config.getString("preop.subsystem.name"));
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("check_newsubsystem", "checked");
+ context.put("check_clonesubsystem", "");
+ try {
+ context.put("subsystemName",
+ config.getString("preop.system.fullname"));
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ String cstype = "";
+
+ try {
+ cstype = config.getString("cs.type", "");
+ context.put("cstype", cstype);
+ context.put("wizardname", config.getString("preop.wizard.name"));
+ context.put("systemname", config.getString("preop.system.name"));
+ context.put("fullsystemname", config.getString("preop.system.fullname"));
+ context.put("machineName", config.getString("machineName"));
+ context.put("http_port", CMS.getEENonSSLPort());
+ context.put("https_agent_port", CMS.getAgentPort());
+ context.put("https_ee_port", CMS.getEESSLPort());
+ context.put("https_admin_port", CMS.getAdminPort());
+ } catch (EBaseException e) {
+ }
+
+ Vector v = getUrlListFromSecurityDomain(config, cstype, "SecurePort" );
+
+ StringBuffer list = new StringBuffer();
+ int size = v.size();
+ for (int i = 0; i < size; i++) {
+ if (i == size - 1) {
+ list.append(v.elementAt(i));
+ } else {
+ list.append(v.elementAt(i));
+ list.append(",");
+ }
+ }
+
+ try {
+ config.putString("preop.master.list", list.toString());
+ config.commit(false);
+ } catch (Exception e) {
+ errorString = "Internal error, cs.type is missing from CS.cfg";
+ }
+
+ if (list.length()==0)
+ context.put("disableClone", "true");
+
+ context.put("panel", "admin/console/config/createsubsystempanel.vm");
+ context.put("errorString", errorString);
+ context.put("urls", v);
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ String errorString = "";
+ IConfigStore config = CMS.getConfigStore();
+ String select = HttpInput.getID(request, "choice");
+
+ if (select == null) {
+ CMS.debug("CreateSubsystemPanel: choice not found");
+ context.put("updateStatus", "failure");
+ throw new IOException("choice not found");
+ }
+
+ config.putString("preop.subsystem.name",
+ HttpInput.getName(request, "subsystemName"));
+ if (select.equals("newsubsystem")) {
+ config.putString("preop.subsystem.select", "new");
+ config.putString("subsystem.select", "New");
+ } else if (select.equals("clonesubsystem")) {
+ String cstype = "";
+ try {
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+
+ cstype = toLowerCaseSubsystemType(cstype);
+
+ config.putString("preop.subsystem.select", "clone");
+ config.putString("subsystem.select", "Clone");
+
+ String lists = "";
+ try {
+ lists = config.getString("preop.cert.list", "");
+ } catch (Exception ee) {
+ }
+
+ StringTokenizer t = new StringTokenizer(lists, ",");
+ while (t.hasMoreTokens()) {
+ String tag = t.nextToken();
+ if (tag.equals("sslserver"))
+ config.putBoolean(PCERT_PREFIX+tag+".enable", true);
+ else
+ config.putBoolean(PCERT_PREFIX+tag+".enable", false);
+ }
+
+ // get the master CA
+ String index = request.getParameter("urls");
+ String url = "";
+
+ try {
+ int x = Integer.parseInt(index);
+ String list = config.getString("preop.master.list", "");
+ StringTokenizer tokenizer = new StringTokenizer(list, ",");
+ int counter = 0;
+
+ while (tokenizer.hasMoreTokens()) {
+ url = tokenizer.nextToken();
+ if (counter == x) {
+ break;
+ }
+ counter++;
+ }
+ } catch (Exception e) {
+ }
+
+ url = url.substring(url.indexOf("http"));
+
+ URL u = new URL(url);
+ String host = u.getHost();
+ int https_ee_port = u.getPort();
+
+ String https_admin_port = getSecurityDomainAdminPort( config,
+ host,
+ String.valueOf(https_ee_port),
+ cstype );
+
+ config.putString("preop.master.hostname", host);
+ config.putInteger("preop.master.httpsport", https_ee_port);
+ config.putString("preop.master.httpsadminport", https_admin_port);
+
+ ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback();
+ if (cstype.equals("ca")) {
+ updateCertChainUsingSecureEEPort( config, "clone", host, https_ee_port,
+ true, context, certApprovalCallback );
+ }
+
+ getTokenInfo(config, cstype, host, https_ee_port, true, context,
+ certApprovalCallback);
+ } else {
+ CMS.debug("CreateSubsystemPanel: invalid choice " + select);
+ errorString = "Invalid choice";
+ context.put("updateStatus", "failure");
+ throw new IOException("invalid choice " + select);
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+
+ context.put("errorString", errorString);
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Subsystem Type");
+ context.put("panel", "admin/console/config/createsubsystempanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
new file mode 100644
index 000000000..bdd0b0d08
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
@@ -0,0 +1,1507 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cmsutil.ldap.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class DatabasePanel extends WizardPanelBase {
+
+ private static final String HOST = "localhost";
+ private static final String CLONE_HOST="Enter FQDN here";
+ private static final String PORT = "389";
+ private static final String BASEDN = "o=netscapeCertificateServer";
+ private static final String BINDDN = "cn=Directory Manager";
+ private static final String DATABASE = "csRoot";
+ private static final String MASTER_AGREEMENT = "masteragreement-";
+ private static final String CLONE_AGREEMENT = "cloneagreement-";
+
+ private WizardServlet mServlet = null;
+
+ public DatabasePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Internal Database");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Internal Database");
+ setId(id);
+ mServlet = servlet;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putBoolean("preop.Database.done", false);
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.Database.done",
+ false);
+
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+ Descriptor hostDesc = new Descriptor(IDescriptor.STRING, null, null,
+ "Host name");
+
+ set.add("hostname", hostDesc);
+
+ Descriptor portDesc = new Descriptor(IDescriptor.INTEGER, null, null,
+ "Port");
+
+ set.add("portStr", portDesc);
+
+ Descriptor basednDesc = new Descriptor(IDescriptor.STRING, null, null,
+ "Base DN");
+
+ set.add("basedn", basednDesc);
+
+ Descriptor binddnDesc = new Descriptor(IDescriptor.STRING, null, null,
+ "Bind DN");
+
+ set.add("binddn", binddnDesc);
+
+ Descriptor bindpwdDesc = new Descriptor(IDescriptor.PASSWORD, null, null,
+ "Bind Password");
+
+ set.add("bindpwd", bindpwdDesc);
+
+ Descriptor databaseDesc = new Descriptor(IDescriptor.STRING, null, null,
+ "Database");
+
+ set.add("database", databaseDesc);
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("DatabasePanel: display()");
+ context.put("title", "Internal Database");
+ context.put("firsttime", "false");
+ IConfigStore cs = CMS.getConfigStore();
+ String hostname = null;
+ String portStr = null;
+ String basedn = null;
+ String binddn = null;
+ String bindpwd = "";
+ String database = null;
+ String errorString = "";
+ String secure = "false";
+ String cloneStartTLS = "false";
+ try {
+ String s = cs.getString("preop.database.removeData");
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ if (isPanelDone()) {
+ try {
+ hostname = cs.getString("internaldb.ldapconn.host", "");
+ portStr = cs.getString("internaldb.ldapconn.port", "");
+ basedn = cs.getString("internaldb.basedn", "");
+ binddn = cs.getString("internaldb.ldapauth.bindDN", "");
+ database = cs.getString("internaldb.database", "");
+ secure = cs.getString("internaldb.ldapconn.secureConn", "");
+ cloneStartTLS = cs.getString("internaldb.ldapconn.cloneStartTLS", "");
+ errorString = cs.getString("preop.database.errorString", "");
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel display: " + e.toString());
+ }
+ } else if (select.equals("clone")) {
+ hostname = CLONE_HOST;
+ portStr = PORT;
+ try {
+ basedn = cs.getString("internaldb.basedn", "");
+ } catch (Exception e) {
+ CMS.debug( "DatabasePanel::display() - "
+ + "Exception="+e.toString() );
+ return;
+ }
+ binddn = BINDDN;
+ database = basedn.substring(basedn.lastIndexOf('=')+1);
+ CMS.debug("Clone: database=" + database);
+ } else {
+ hostname = HOST;
+ portStr = PORT;
+ String instanceId = "";
+ String machineName = "";
+
+ try {
+ instanceId = cs.getString("instanceId", "");
+ machineName = cs.getString("machineName", "");
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel display: " + e.toString());
+ }
+ String suffix = "dc=" + machineName + "-" + instanceId;
+
+ boolean multipleEnable = false;
+ try {
+ multipleEnable = cs.getBoolean(
+ "internaldb.multipleSuffix.enable", false);
+ } catch (Exception e) {
+ }
+
+
+ if (multipleEnable)
+ basedn = "ou=" + instanceId + "," + suffix;
+ else
+ basedn = suffix;
+ binddn = BINDDN;
+ database = machineName + "-" + instanceId;
+ }
+
+ context.put("clone", select);
+ context.put("hostname", hostname);
+ context.put("portStr", portStr);
+ context.put("basedn", basedn);
+ context.put("binddn", binddn);
+ context.put("bindpwd", bindpwd);
+ context.put("database", database);
+ context.put("secureConn", (secure.equals("true")? "on":"off"));
+ context.put("cloneStartTLS", (cloneStartTLS.equals("true")? "on":"off"));
+ context.put("panel", "admin/console/config/databasepanel.vm");
+ context.put("errorString", errorString);
+ }
+
+ public void initParams(HttpServletRequest request, Context context)
+ throws IOException
+ {
+ IConfigStore config = CMS.getConfigStore();
+ String select = "";
+ try {
+ select = config.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+ context.put("clone", select);
+ context.put("hostname", request.getParameter("host"));
+ context.put("portStr", request.getParameter("port"));
+ context.put("basedn", request.getParameter("basedn"));
+ context.put("binddn", request.getParameter("binddn"));
+ context.put("bindpwd", request.getParameter("__bindpwd"));
+ context.put("database", request.getParameter("database"));
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+
+ IConfigStore cs = CMS.getConfigStore();
+ context.put("firsttime", "false");
+ try {
+ String s = cs.getString("preop.database.removeData");
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ String hostname = HttpInput.getHostname(request, "host");
+ context.put("hostname", hostname);
+
+ String portStr = HttpInput.getPortNumber(request, "port");
+ context.put("portStr", portStr);
+
+ String basedn = HttpInput.getDN(request, "basedn");
+ context.put("basedn", basedn);
+
+ String binddn = HttpInput.getDN(request, "binddn");
+ context.put("binddn", binddn);
+
+ String database = HttpInput.getLdapDatabase(request, "database");
+ context.put("database", database);
+
+ String bindpwd = HttpInput.getPassword(request, "__bindpwd");
+ context.put("bindpwd", bindpwd);
+
+ String secure = HttpInput.getCheckbox(request, "secureConn");
+ context.put("secureConn", secure);
+
+ String cloneStartTLS = HttpInput.getCheckbox(request, "cloneStartTLS");
+ context.put("cloneStartTLS", cloneStartTLS);
+
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ if (select.equals("clone")) {
+ String masterhost = "";
+ String masterport = "";
+ String masterbasedn = "";
+ try {
+ masterhost = cs.getString("preop.internaldb.master.hostname", "");
+ masterport = cs.getString("preop.internaldb.master.port", "");
+ masterbasedn = cs.getString("preop.internaldb.master.basedn", "");
+ } catch (Exception e) {
+ }
+
+ //get the real host name
+ String realhostname = "";
+ if (hostname.equals("localhost")) {
+ try {
+ realhostname = cs.getString("machineName", "");
+ } catch (Exception ee) {
+ }
+ }
+ if (masterhost.equals(realhostname) && masterport.equals(portStr)) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Master and clone must not share the same internal database");
+ }
+
+ if (!masterbasedn.equals(basedn)) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Master and clone should have the same base DN");
+ }
+ }
+
+ if (hostname == null || hostname.length() == 0) {
+ cs.putString("preop.database.errorString", "Host is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Host is empty string");
+ }
+
+ if (portStr != null && portStr.length() > 0) {
+ int port = -1;
+
+ try {
+ port = Integer.parseInt(portStr);
+ } catch (Exception e) {
+ cs.putString("preop.database.errorString", "Port is invalid");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Port is invalid");
+ }
+ } else {
+ cs.putString("preop.database.errorString", "Port is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Port is empty string");
+ }
+
+ if (basedn == null || basedn.length() == 0) {
+ cs.putString("preop.database.errorString", "Base DN is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Base DN is empty string");
+ }
+
+ if (binddn == null || binddn.length() == 0) {
+ cs.putString("preop.database.errorString", "Bind DN is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Bind DN is empty string");
+ }
+
+ if (database == null || database.length() == 0) {
+ cs.putString("preop.database.errorString",
+ "Database is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Database is empty string");
+ }
+
+ if (bindpwd == null || bindpwd.length() == 0) {
+ cs.putString("preop.database.errorString",
+ "Bind password is empty string");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Bind password is empty string");
+ }
+
+ context.put("errorString", "");
+ cs.putString("preop.database.errorString", "");
+ }
+
+ private LDAPConnection getLocalLDAPConn(Context context, String secure)
+ throws IOException
+ {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String host = "";
+ String port = "";
+ String pwd = "";
+ String binddn = "";
+ String security = "";
+
+ try {
+ host = cs.getString("internaldb.ldapconn.host");
+ port = cs.getString("internaldb.ldapconn.port");
+ binddn = cs.getString("internaldb.ldapauth.bindDN");
+ pwd = (String) context.get("bindpwd");
+ security = cs.getString("internaldb.ldapconn.secureConn");
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel populateDB: " + e.toString());
+ throw new IOException(
+ "Failed to retrieve LDAP information from CS.cfg.");
+ }
+
+ int p = -1;
+
+ try {
+ p = Integer.parseInt(port);
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel populateDB: " + e.toString());
+ throw new IOException("Port is not valid");
+ }
+
+ LDAPConnection conn = null;
+ if (security.equals("true")) {
+ CMS.debug("DatabasePanel populateDB: creating secure (SSL) connection for internal ldap");
+ conn = new LDAPConnection(CMS.getLdapJssSSLSocketFactory());
+ } else {
+ CMS.debug("DatabasePanel populateDB: creating non-secure (non-SSL) connection for internal ldap");
+ conn = new LDAPConnection();
+ }
+
+ CMS.debug("DatabasePanel connecting to " + host + ":" + p);
+ try {
+ conn.connect(host, p, binddn, pwd);
+ } catch (LDAPException e) {
+ CMS.debug("DatabasePanel populateDB: " + e.toString());
+ throw new IOException("Failed to connect to the internal database.");
+ }
+
+ return conn;
+ }
+
+ private boolean deleteDir(File dir)
+ {
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (int i=0; i<children.length; i++) {
+ boolean success = deleteDir(new File(dir, children[i]));
+ if (!success) {
+ return false;
+ }
+ }
+ }
+
+ // The directory is now empty so delete it
+ return dir.delete();
+ }
+
+ private void cleanupDB(LDAPConnection conn, String baseDN, String database)
+ {
+ String[] entries = {};
+ String filter = "objectclass=*";
+ LDAPSearchConstraints cons = null;
+ String[] attrs = null;
+ String dn="";
+ try {
+ CMS.debug("Deleting baseDN: " + baseDN);
+ LDAPSearchResults res = conn.search(baseDN, LDAPConnection.SCOPE_BASE, filter,
+ attrs, true, cons);
+ if (res != null)
+ deleteEntries(res, conn, baseDN, entries);
+ }
+ catch (LDAPException e) {}
+
+ try {
+ dn="cn=mapping tree, cn=config";
+ filter = "nsslapd-backend=" + database;
+ LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_ONE, filter,
+ attrs, true, cons);
+ if (res != null) {
+ while (res.hasMoreElements()) {
+ dn = res.next().getDN();
+ filter = "objectclass=*";
+ LDAPSearchResults res2 = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+ attrs, true, cons);
+ if (res2 != null)
+ deleteEntries(res2, conn, dn, entries);
+ }
+ }
+ }
+ catch (LDAPException e) {}
+
+ try {
+ dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+ LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+ attrs, true, cons);
+ if (res != null) {
+ deleteEntries(res, conn, dn, entries);
+ String dbdir = getInstanceDir(conn) + "/db/" + database;
+ if (dbdir != null) {
+ CMS.debug(" Deleting dbdir " + dbdir);
+ boolean success = deleteDir(new File(dbdir));
+ if (!success) {
+ CMS.debug("Unable to delete database directory " + dbdir);
+ }
+ }
+ }
+ }
+ catch (LDAPException e) {}
+ }
+
+
+ private void populateDB(HttpServletRequest request, Context context, String secure)
+ throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String baseDN = "";
+ String database = "";
+ String dn = "";
+
+ try {
+ baseDN = cs.getString("internaldb.basedn");
+ database = cs.getString("internaldb.database", "");
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel populateDB: " + e.toString());
+ throw new IOException(
+ "Failed to retrieve LDAP information from CS.cfg.");
+ }
+
+ String remove = HttpInput.getID(request, "removeData");
+ LDAPConnection conn = getLocalLDAPConn(context, secure);
+
+ // check that the database and baseDN do not exist
+
+ boolean foundBaseDN = false;
+ boolean foundDatabase = false;
+ try {
+ LDAPEntry entry = conn.read(baseDN);
+ if (entry != null) foundBaseDN = true;
+ } catch (LDAPException e) {
+ switch( e.getLDAPResultCode() ) {
+ case LDAPException.NO_SUCH_OBJECT:
+ break;
+ default:
+ CMS.debug("DatabasePanel update: LDAPException " + e.toString());
+ throw new IOException("Failed to create the database");
+ }
+ }
+
+ try {
+ dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+ LDAPEntry entry = conn.read(dn);
+ if (entry != null) foundDatabase = true;
+ } catch (LDAPException e) {
+ switch( e.getLDAPResultCode() ) {
+ case LDAPException.NO_SUCH_OBJECT:
+ break;
+ default:
+ CMS.debug("DatabasePanel update: LDAPException " + e.toString());
+ throw new IOException("Failed to create the database");
+ }
+ }
+ try {
+ dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config";
+ LDAPEntry entry = conn.read(dn);
+ if (entry != null) foundDatabase = true;
+ } catch (LDAPException e) {
+ switch( e.getLDAPResultCode() ) {
+ case LDAPException.NO_SUCH_OBJECT:
+ break;
+ default:
+ CMS.debug("DatabasePanel update: LDAPException " + e.toString());
+ throw new IOException("Failed to create the database");
+ }
+ }
+
+ if (foundDatabase) {
+ CMS.debug("DatabasePanel update: This database has already been used.");
+ if (remove == null) {
+ throw new IOException("This database has already been used. Select the checkbox below to remove all data and reuse this database");
+ }
+ else {
+ CMS.debug("DatabasePanel update: Deleting existing DB and reusing base DN");
+ cleanupDB(conn, baseDN, database);
+ foundBaseDN = false;
+ foundDatabase = false;
+ }
+ }
+
+ if (foundBaseDN) {
+ CMS.debug("DatabasePanel update: This base DN has already been used.");
+ if (remove == null) {
+ throw new IOException("This base DN ("+baseDN+") has already been used. Select the checkbox below to remove all data and reuse this base DN");
+ }
+ else {
+ CMS.debug("DatabasePanel update: Deleting existing DB and reusing base DN");
+ cleanupDB(conn, baseDN, database);
+ foundBaseDN = false;
+ foundDatabase = false;
+ }
+ }
+
+ // create database
+ try {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc[] = { "top", "extensibleObject", "nsBackendInstance"};
+ attrs.add(new LDAPAttribute("objectClass", oc));
+ attrs.add(new LDAPAttribute("cn", database));
+ attrs.add(new LDAPAttribute("nsslapd-suffix", baseDN));
+ dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config";
+ LDAPEntry entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ CMS.debug("Warning: database creation error - " + e.toString());
+ throw new IOException("Failed to create the database.");
+ }
+
+ try {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc2[] = { "top", "extensibleObject", "nsMappingTree"};
+ attrs.add(new LDAPAttribute("objectClass", oc2));
+ attrs.add(new LDAPAttribute("cn", baseDN));
+ attrs.add(new LDAPAttribute("nsslapd-backend", database));
+ attrs.add(new LDAPAttribute("nsslapd-state", "Backend"));
+ dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config";
+ LDAPEntry entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ CMS.debug("Warning: database mapping tree creation error - " + e.toString());
+ throw new IOException("Failed to create the database.");
+ }
+
+ try {
+ // create base dn
+ CMS.debug("Creating base DN: " + baseDN);
+ String dns3[] = LDAPDN.explodeDN(baseDN, false);
+ StringTokenizer st = new StringTokenizer(dns3[0], "=");
+ String n = st.nextToken();
+ String v = st.nextToken();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc3[] = { "top", "domain"};
+ if (n.equals("o")) {
+ oc3[1] = "organization";
+ } else if (n.equals("ou")) {
+ oc3[1] = "organizationalUnit";
+ }
+ attrs.add(new LDAPAttribute("objectClass", oc3));
+ attrs.add(new LDAPAttribute(n, v));
+ LDAPEntry entry = new LDAPEntry(baseDN, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ CMS.debug("Warning: suffix creation error - " + e.toString());
+ throw new IOException("Failed to create the base DN: "+baseDN);
+ }
+
+ // check to see if the base dn exists
+ CMS.debug("DatabasePanel checking existing " + baseDN);
+
+ try {
+ LDAPEntry entry = conn.read(baseDN);
+
+ if (entry != null) {
+ foundBaseDN = true;
+ }
+ } catch (LDAPException e) {}
+ boolean createBaseDN = true;
+
+ boolean testing = false;
+ try {
+ testing = cs.getBoolean("internaldb.multipleSuffix.enable", false);
+ } catch (Exception e) {}
+
+ if (!foundBaseDN) {
+ if (!testing) {
+ context.put("errorString", "Base DN was not found. Please make sure to create the suffix in the internal database.");
+ throw new IOException("Base DN not found");
+ }
+
+ if (createBaseDN) {
+ // only auto create if it is an ou entry
+ String dns1[] = LDAPDN.explodeDN(baseDN, false);
+
+ if (dns1 == null) {
+ throw new IOException("Invalid base DN");
+ }
+ if (!dns1[0].startsWith("ou")) {
+ throw new IOException(
+ "Failed to find base DN, and failed to create non ou entry.");
+ }
+ String dns2[] = LDAPDN.explodeDN(baseDN, true);
+ // support only one level creation - create new entry
+ // right under the suffix
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc[] = { "top", "organizationalUnit"};
+
+ attrs.add(new LDAPAttribute("objectClass", oc));
+ attrs.add(new LDAPAttribute("ou", dns2[0]));
+ LDAPEntry entry = new LDAPEntry(baseDN, attrs);
+
+ try {
+ conn.add(entry);
+ foundBaseDN = true;
+ CMS.debug("DatabasePanel added " + baseDN);
+ } catch (LDAPException e) {
+ throw new IOException("Failed to create " + baseDN);
+ }
+ }
+ }
+ if (!foundBaseDN) {
+ throw new IOException("Failed to find base DN");
+ }
+
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ if (select.equals("clone")) {
+ // if this is clone, add index before replication
+ // don't put in the schema or bad things will happen
+
+ importLDIFS("preop.internaldb.ldif", conn);
+ importLDIFS("preop.internaldb.index_ldif", conn);
+ } else {
+ // data will be replicated from the master to the clone
+ // so clone does not need the data
+ //
+
+ importLDIFS("preop.internaldb.schema.ldif", conn);
+ importLDIFS("preop.internaldb.ldif", conn);
+ importLDIFS("preop.internaldb.data_ldif", conn);
+ importLDIFS("preop.internaldb.index_ldif", conn);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (LDAPException e) {}
+ }
+
+ private void importLDIFS(String param, LDAPConnection conn) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ String v = null;
+
+ CMS.debug("DatabasePanel populateDB param=" + param);
+ try {
+ v = cs.getString(param);
+ } catch (EBaseException e) {
+ CMS.debug("DatabasePanel populateDB: " + e.toString());
+ throw new IOException("Cant find ldif files.");
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(v, ",");
+ String baseDN = null;
+ String database = null;
+
+ try {
+ baseDN = cs.getString("internaldb.basedn");
+ } catch (EBaseException e) {
+ throw new IOException("internaldb.basedn is missing.");
+ }
+
+ try {
+ database = cs.getString("internaldb.database");
+ CMS.debug("DatabasePanel update: database=" + database);
+ } catch (EBaseException e) {
+ CMS.debug(
+ "DatabasePanel update: Failed to get database name. Exception: "
+ + e.toString());
+ database = "userRoot";
+ }
+
+ String instancePath = null;
+
+ try {
+ instancePath = cs.getString("instanceRoot");
+ } catch (EBaseException e) {
+ throw new IOException("instanceRoot is missing");
+ }
+
+ String instanceId = null;
+
+ try {
+ instanceId = cs.getString("instanceId");
+ } catch (EBaseException e) {
+ throw new IOException("instanceId is missing");
+ }
+
+
+ String configDir = instancePath + File.separator + "conf";
+
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken().trim();
+ int index = token.lastIndexOf("/");
+ String name = token;
+
+ if (index != -1) {
+ name = token.substring(index + 1);
+ }
+
+ CMS.debug("DatabasePanel importLDIFS: ldif file = " + token);
+ String filename = configDir + File.separator + name;
+
+ CMS.debug("DatabasePanel importLDIFS: ldif file copy to " + filename);
+ PrintStream ps = null;
+ BufferedReader in = null;
+
+ try {
+ in = new BufferedReader(new FileReader(token));
+ ps = new PrintStream(new FileOutputStream(filename, false));
+ while (in.ready()) {
+ String s = in.readLine();
+ int n = s.indexOf("{");
+
+ if (n == -1) {
+ ps.println(s);
+ } else {
+ boolean endOfline = false;
+
+ while (n != -1) {
+ ps.print(s.substring(0, n));
+ int n1 = s.indexOf("}");
+ String tok = s.substring(n + 1, n1);
+
+ if (tok.equals("instanceId")) {
+ ps.print(instanceId);
+ } else if (tok.equals("rootSuffix")) {
+ ps.print(baseDN);
+ } else if (tok.equals("database")) {
+ ps.print(database);
+ }
+ if ((s.length() + 1) == n1) {
+ endOfline = true;
+ break;
+ }
+ s = s.substring(n1 + 1);
+ n = s.indexOf("{");
+ }
+
+ if (!endOfline) {
+ ps.println(s);
+ }
+ }
+ }
+ in.close();
+ ps.close();
+ } catch (Exception e) {
+ CMS.debug("DBSubsystem popuateDB: " + e.toString());
+ throw new IOException(
+ "Problem of copying ldif file: " + filename);
+ }
+
+ LDAPUtil.importLDIF(conn, filename);
+ }
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ boolean hasErr = false;
+
+ boolean firsttime = false;
+ context.put("firsttime", "false");
+ try {
+ String v = cs.getString("preop.database.removeData");
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ firsttime = true;
+ }
+
+ String hostname1 = "";
+ String portStr1 = "";
+ String database1 = "";
+ String basedn1 = "";
+
+ try {
+ hostname1 = cs.getString("internaldb.ldapconn.host", "");
+ portStr1 = cs.getString("internaldb.ldapconn.port", "");
+ database1 = cs.getString("internaldb.database", "");
+ basedn1 = cs.getString("internaldb.basedn", "");
+ } catch (Exception e) {
+ }
+
+ String hostname2 = HttpInput.getHostname(request, "host");
+ String portStr2 = HttpInput.getPortNumber(request, "port");
+ String database2 = HttpInput.getLdapDatabase(request, "database");
+ String basedn2 = HttpInput.getDN(request, "basedn");
+
+ cs.putString("internaldb.ldapconn.host", hostname2);
+ cs.putString("internaldb.ldapconn.port", portStr2);
+ cs.putString("internaldb.basedn", basedn2);
+ String binddn = HttpInput.getDN(request, "binddn");
+ cs.putString("internaldb.ldapauth.bindDN", binddn);
+ cs.putString("internaldb.database", database2);
+ String secure = HttpInput.getCheckbox(request, "secureConn");
+ cs.putString("internaldb.ldapconn.secureConn", (secure.equals("on")?"true":"false"));
+ String cloneStartTLS = HttpInput.getCheckbox(request, "cloneStartTLS");
+ cs.putString("internaldb.ldapconn.cloneStartTLS", (cloneStartTLS.equals("on")?"true":"false"));
+
+ String remove = HttpInput.getID(request, "removeData");
+ if (isPanelDone() && (remove == null || remove.equals(""))) {
+ /* if user submits the same data, they just want to skip
+ to the next panel, no database population is required. */
+ if (hostname1.equals(hostname2) &&
+ portStr1.equals(portStr2) &&
+ database1.equals(database2)) {
+ context.put("updateStatus", "success");
+ return;
+ }
+ }
+
+ mServlet.cleanUpFromPanel(mServlet.getPanelNo(request));
+
+
+ try {
+ populateDB(request, context, (secure.equals("on")?"true":"false"));
+ } catch (IOException e) {
+ CMS.debug("DatabasePanel update: populateDB Exception: "+e.toString());
+ context.put("updateStatus", "failure");
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel update: populateDB Exception: "+e.toString());
+ context.put("errorString", e.toString());
+ cs.putString("preop.database.errorString", e.toString());
+ context.put("updateStatus", "failure");
+ throw new IOException(e.toString());
+ }
+
+ String bindpwd = HttpInput.getPassword(request, "__bindpwd");
+
+ /* BZ 430745 create password for replication manager */
+ String replicationpwd = Integer.toString(new Random().nextInt());
+
+ IConfigStore psStore = null;
+ String passwordFile = null;
+
+ try {
+ passwordFile = cs.getString("passwordFile");
+ psStore = CMS.createFileConfigStore(passwordFile);
+ } catch (Exception e) {
+ CMS.debug("ConfigDatabaseServlet update: " + e.toString());
+ context.put("updateStatus", "failure");
+ throw new IOException( e.toString() );
+ }
+ psStore.putString("internaldb", bindpwd);
+ psStore.putString("replicationdb", replicationpwd);
+ cs.putString("preop.internaldb.replicationpwd" , replicationpwd);
+ cs.putString("preop.database.removeData", "false");
+
+ try {
+ cs.commit(false);
+ psStore.commit(false);
+ CMS.reinit(IDBSubsystem.SUB_ID);
+ String type = cs.getString("cs.type", "");
+ if (type.equals("CA"))
+ CMS.reinit(ICertificateAuthority.ID);
+ CMS.reinit(IAuthSubsystem.ID);
+ CMS.reinit(IAuthzSubsystem.ID);
+ CMS.reinit(IUGSubsystem.ID);
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel update: " + e.toString());
+ context.put("errorString", e.toString());
+ cs.putString("preop.database.errorString", e.toString());
+ context.put("updateStatus", "failure");
+ throw new IOException(e.toString());
+ }
+
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ // always populate the index the last
+ try {
+ CMS.debug("Populating local indexes");
+ LDAPConnection conn = getLocalLDAPConn(context,
+ (secure.equals("on")?"true":"false"));
+ importLDIFS("preop.internaldb.post_ldif", conn);
+
+ /* For vlvtask, we need to check if the task has
+ been completed or not. Presence of nsTaskExitCode means task is complete
+ */
+ String wait_dn = cs.getString("preop.internaldb.wait_dn", "");
+ if (!wait_dn.equals("")) {
+ int i = 0;
+ LDAPEntry task = null;
+ boolean taskComplete = false;
+ CMS.debug("Checking wait_dn " + wait_dn);
+ do {
+ Thread.sleep(1000);
+ try {
+ task = conn.read(wait_dn, (String[])null);
+ if (task != null) {
+ LDAPAttribute attr = task.getAttribute("nsTaskExitCode");
+ if (attr != null) {
+ taskComplete = true;
+ String val = (String) attr.getStringValues().nextElement();
+ if (val.compareTo("0") != 0) {
+ CMS.debug("Error in populating local indexes: nsTaskExitCode=" + val);
+ }
+ }
+ }
+ } catch (LDAPException le) {
+ CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")");
+ } catch (Exception e) {
+ CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + e.toString() + ").");
+ }
+ } while ((!taskComplete) && (i < 20));
+ if (i < 20) {
+ CMS.debug("Done checking wait_dn " + wait_dn);
+ } else {
+ CMS.debug("Done checking wait_dn " + wait_dn + " due to timeout.");
+ }
+ }
+
+ conn.disconnect();
+ CMS.debug("Done populating local indexes");
+ } catch (Exception e) {
+ CMS.debug("Populating index failure - " + e);
+ }
+
+ // setup replication after indexes have been created
+ if (select.equals("clone")) {
+ CMS.debug("Start setting up replication.");
+ setupReplication(request, context, (secure.equals("on")?"true":"false"), (cloneStartTLS.equals("on")?"true":"false"));
+ CMS.debug("Finish setting up replication.");
+
+ try {
+ CMS.reinit(IDBSubsystem.SUB_ID);
+ String type = cs.getString("cs.type", "");
+ if (type.equals("CA"))
+ CMS.reinit(ICertificateAuthority.ID);
+ CMS.reinit(IAuthSubsystem.ID);
+ CMS.reinit(IAuthzSubsystem.ID);
+ CMS.reinit(IUGSubsystem.ID);
+ } catch (Exception e) {
+ }
+ }
+
+
+ if (hasErr == false) {
+ cs.putBoolean("preop.Database.done", true);
+ try {
+ cs.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug(
+ "DatabasePanel: update() Exception caught at config commit: "
+ + e.toString());
+ }
+ }
+ context.put("updateStatus", "success");
+ }
+
+ private void setupReplication(HttpServletRequest request,
+ Context context, String secure, String cloneStartTLS) throws IOException {
+ String bindpwd = HttpInput.getPassword(request, "__bindpwd");
+ IConfigStore cs = CMS.getConfigStore();
+
+ String cstype = "";
+ String machinename = "";
+ String instanceId = "";
+ try {
+ cstype = cs.getString("cs.type");
+ cstype = toLowerCaseSubsystemType(cstype);
+ machinename = cs.getString("machineName", "");
+ instanceId = cs.getString("instanceId", "");
+ } catch (Exception e) {
+ }
+
+
+ //setup replication agreement
+ String masterAgreementName = "masterAgreement1-"+machinename+"-"+instanceId;
+ cs.putString("internaldb.replication.master", masterAgreementName);
+ String cloneAgreementName = "cloneAgreement1-"+machinename+"-"+instanceId;
+ cs.putString("internaldb.replication.consumer", cloneAgreementName);
+
+ try {
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+
+ String master1_hostname = "";
+ int master1_port = -1;
+ String master1_binddn = "";
+ String master1_bindpwd = "";
+ String master1_replicationpwd = "";
+
+ try {
+ master1_hostname = cs.getString("preop.internaldb.master.hostname", "");
+ master1_port = cs.getInteger("preop.internaldb.master.port", -1);
+ master1_binddn = cs.getString("preop.internaldb.master.binddn", "");
+ master1_bindpwd = cs.getString("preop.internaldb.master.bindpwd", "");
+ master1_replicationpwd = cs.getString("preop.internaldb.master.replicationpwd", "");
+ } catch (Exception e) {
+ }
+
+ String master2_hostname = "";
+ int master2_port = -1;
+ String master2_binddn = "";
+ String master2_bindpwd = "";
+ String master2_replicationpwd = "";
+
+ try {
+ master2_hostname = cs.getString("internaldb.ldapconn.host", "");
+ master2_port = cs.getInteger("internaldb.ldapconn.port", -1);
+ master2_binddn = cs.getString("internaldb.ldapauth.bindDN", "");
+ master2_bindpwd = bindpwd;
+ master2_replicationpwd = cs.getString("preop.internaldb.replicationpwd", "");
+ } catch (Exception e) {
+ }
+
+ LDAPConnection conn1 = null;
+ LDAPConnection conn2 = null;
+ if (secure.equals("true")) {
+ CMS.debug("DatabasePanel setupReplication: creating secure (SSL) connections for internal ldap");
+ conn1 = new LDAPConnection(CMS.getLdapJssSSLSocketFactory());
+ conn2 = new LDAPConnection(CMS.getLdapJssSSLSocketFactory());
+ } else {
+ CMS.debug("DatabasePanel setupreplication: creating non-secure (non-SSL) connections for internal ldap");
+ conn1 = new LDAPConnection();
+ conn2 = new LDAPConnection();
+ }
+
+ String basedn = "";
+ try {
+ basedn = cs.getString("internaldb.basedn");
+ } catch (Exception e) {
+ }
+
+ try {
+ conn1.connect(master1_hostname, master1_port, master1_binddn,
+ master1_bindpwd);
+ conn2.connect(master2_hostname, master2_port, master2_binddn,
+ master2_bindpwd);
+ String suffix = cs.getString("internaldb.basedn", "");
+
+ String replicadn = "cn=replica,cn=\""+suffix+"\",cn=mapping tree,cn=config";
+ CMS.debug("DatabasePanel setupReplication: replicadn="+replicadn);
+
+ String masterBindUser = "Replication Manager " + masterAgreementName;
+ String cloneBindUser = "Replication Manager " + cloneAgreementName;
+
+ createReplicationManager(conn1, masterBindUser, master1_replicationpwd);
+ createReplicationManager(conn2, cloneBindUser, master2_replicationpwd);
+
+ String dir1 = getInstanceDir(conn1);
+ createChangeLog(conn1, dir1 + "/changelogs");
+
+ String dir2 = getInstanceDir(conn2);
+ createChangeLog(conn2, dir2 + "/changelogs");
+
+ int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1);
+
+ replicaId = enableReplication(replicadn, conn1, masterBindUser, basedn, replicaId);
+ replicaId = enableReplication(replicadn, conn2, cloneBindUser, basedn, replicaId);
+ cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId));
+
+ CMS.debug("DatabasePanel setupReplication: Finished enabling replication");
+
+ createReplicationAgreement(replicadn, conn1, masterAgreementName,
+ master2_hostname, master2_port, master2_replicationpwd, basedn, cloneBindUser, secure, cloneStartTLS);
+
+ createReplicationAgreement(replicadn, conn2, cloneAgreementName,
+ master1_hostname, master1_port, master1_replicationpwd, basedn, masterBindUser, secure, cloneStartTLS);
+
+ // initialize consumer
+ initializeConsumer(replicadn, conn1, masterAgreementName);
+
+ while (! replicationDone(replicadn, conn1, masterAgreementName)) {
+ CMS.debug("DatabasePanel setupReplication: Waiting for replication to complete");
+ Thread.sleep(1000);
+ }
+
+ String status = replicationStatus(replicadn, conn1, masterAgreementName);
+ if (!status.startsWith("0 ")) {
+ CMS.debug("DatabasePanel setupReplication: consumer initialization failed. " +
+ status);
+ throw new IOException("consumer initialization failed. " + status);
+ }
+
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel setupReplication: "+e.toString());
+ throw new IOException("Failed to setup the replication for cloning.");
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ try {
+ initParams(request, context);
+ } catch (IOException e) {
+ }
+ context.put("title", "Database");
+ context.put("panel", "admin/console/config/databasepanel.vm");
+ }
+
+ private boolean isAgreementExist(String replicadn, LDAPConnection conn,
+ String name) {
+ String dn = "cn="+name+","+replicadn;
+ String filter = "(cn="+name+")";
+ String[] attrs = {"cn"};
+ try {
+ LDAPSearchResults results = conn.search(dn, LDAPv3.SCOPE_SUB,
+ filter, attrs, false);
+ while (results.hasMoreElements())
+ return true;
+ } catch (LDAPException e) {
+ return false;
+ }
+
+ return false;
+ }
+
+ private void createReplicationManager(LDAPConnection conn, String bindUser, String pwd)
+ throws LDAPException {
+ LDAPAttributeSet attrs = null;
+ LDAPEntry entry = null;
+ String dn = "cn=" + bindUser + ",cn=config";
+ try {
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "person"));
+ attrs.add(new LDAPAttribute("userpassword", pwd));
+ attrs.add(new LDAPAttribute("cn", bindUser));
+ attrs.add(new LDAPAttribute("sn", "manager"));
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ CMS.debug("DatabasePanel createReplicationManager: Replication Manager has already used");
+ try {
+ conn.delete(dn);
+ conn.add(entry);
+ } catch (LDAPException ee) {
+ CMS.debug("DatabasePanel createReplicationManager: "+ee.toString());
+ }
+ return;
+ } else {
+ CMS.debug("DatabasePanel createReplicationManager: Failed to create replication manager. Exception: "+e.toString());
+ throw e;
+ }
+ }
+
+ CMS.debug("DatabasePanel createReplicationManager: Successfully created Replication Manager");
+ }
+
+ private void createChangeLog(LDAPConnection conn, String dir)
+ throws LDAPException {
+ LDAPAttributeSet attrs = null;
+ LDAPEntry entry = null;
+ String dn = "cn=changelog5,cn=config";
+ try {
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "extensibleObject"));
+ attrs.add(new LDAPAttribute("cn", "changelog5"));
+ attrs.add(new LDAPAttribute("nsslapd-changelogdir", dir));
+ entry = new LDAPEntry("cn=changelog5,cn=config", attrs);
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ CMS.debug("DatabasePanel createChangeLog: Changelog entry has already used");
+/* leave it, dont delete it because it will have operation error
+ try {
+ conn.delete(dn);
+ conn.add(entry);
+ } catch (LDAPException ee) {
+ CMS.debug("DatabasePanel createChangeLog: "+ee.toString());
+ }
+*/
+ return;
+ } else {
+ CMS.debug("DatabasePanel createChangeLog: Failed to create changelog entry. Exception: "+e.toString());
+ throw e;
+ }
+ }
+
+ CMS.debug("DatabasePanel createChangeLog: Successfully create change log entry");
+ }
+
+ private int enableReplication(String replicadn, LDAPConnection conn, String bindUser, String basedn, int id)
+ throws LDAPException {
+ CMS.debug("DatabasePanel enableReplication: replicadn: "+replicadn);
+ LDAPAttributeSet attrs = null;
+ LDAPEntry entry = null;
+ try {
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "nsDS5Replica"));
+ attrs.add(new LDAPAttribute("objectclass", "extensibleobject"));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaType", "3"));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN",
+ "cn=" + bindUser + ",cn=config"));
+ attrs.add(new LDAPAttribute("cn", "replica"));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaId", Integer.toString(id)));
+ attrs.add(new LDAPAttribute("nsds5flags", "1"));
+ entry = new LDAPEntry(replicadn, attrs);
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ /* BZ 470918 -we cant just add the new dn. We need to do a replace instead
+ * until the DS code is fixed */
+ CMS.debug("DatabasePanel enableReplication: "+replicadn+" has already been used");
+
+ try {
+ entry = conn.read(replicadn);
+ LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN");
+ attr.addValue( "cn=" + bindUser + ",cn=config");
+ LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
+ conn.modify(replicadn, mod);
+ } catch (LDAPException ee) {
+ CMS.debug("DatabasePanel enableReplication: Failed to modify "
+ +replicadn+" entry. Exception: "+e.toString());
+ }
+ return id;
+ } else {
+ CMS.debug("DatabasePanel enableReplication: Failed to create "+replicadn+" entry. Exception: "+e.toString());
+ return id;
+ }
+ }
+
+ CMS.debug("DatabasePanel enableReplication: Successfully create "+replicadn+" entry.");
+ return id + 1;
+ }
+
+ private void createReplicationAgreement(String replicadn,
+ LDAPConnection conn, String name, String replicahost, int replicaport,
+ String replicapwd, String basedn, String bindUser, String secure, String cloneStartTLS) throws LDAPException {
+ String dn = "cn="+name+","+replicadn;
+ CMS.debug("DatabasePanel createReplicationAgreement: dn: "+dn);
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ try {
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass",
+ "nsds5replicationagreement"));
+ attrs.add(new LDAPAttribute("cn", name));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaPort", ""+replicaport));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN",
+ "cn=" + bindUser + ",cn=config"));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple"));
+ attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd));
+
+ if (secure.equals("true")) {
+ attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL"));
+ } else if (cloneStartTLS.equals("true")) {
+ attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "TLS"));
+ }
+
+ CMS.debug("About to set description attr to " + name);
+ attrs.add(new LDAPAttribute("description",name));
+
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ CMS.debug("DatabasePanel createReplicationAgreement: "+dn+" has already used");
+ try {
+ conn.delete(dn);
+ } catch (LDAPException ee) {
+ CMS.debug("DatabasePanel createReplicationAgreement: "+ee.toString());
+ throw ee;
+ }
+
+ try {
+ conn.add(entry);
+ } catch (LDAPException ee) {
+ CMS.debug("DatabasePanel createReplicationAgreement: "+ee.toString());
+ throw ee;
+ }
+ } else {
+ CMS.debug("DatabasePanel createReplicationAgreement: Failed to create "+dn+" entry. Exception: "+e.toString());
+ throw e;
+ }
+ }
+
+ CMS.debug("DatabasePanel createReplicationAgreement: Successfully create replication agreement "+name);
+ }
+
+ private void initializeConsumer(String replicadn, LDAPConnection conn,
+ String name) {
+ String dn = "cn="+name+","+replicadn;
+ CMS.debug("DatabasePanel initializeConsumer: initializeConsumer dn: "+dn);
+ CMS.debug("DatabasePanel initializeConsumer: initializeConsumer host: "+conn.getHost() + " port: " + conn.getPort());
+ try {
+ LDAPAttribute attr = new LDAPAttribute("nsds5beginreplicarefresh",
+ "start");
+ LDAPModification mod = new LDAPModification(
+ LDAPModification.REPLACE, attr);
+ CMS.debug("DatabasePanel initializeConsumer: start modifying");
+ conn.modify(dn, mod);
+ CMS.debug("DatabasePanel initializeConsumer: Finish modification.");
+ } catch (LDAPException e) {
+ CMS.debug("DatabasePanel initializeConsumer: Failed to modify "+dn+" entry. Exception: "+e.toString());
+ return;
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel initializeConsumer: exception " + e);
+ }
+
+ try {
+ CMS.debug("DatabasePanel initializeConsumer: thread sleeping for 5 seconds.");
+ Thread.sleep(5000);
+ CMS.debug("DatabasePanel initializeConsumer: finish sleeping.");
+ } catch (InterruptedException ee) {
+ CMS.debug("DatabasePanel initializeConsumer: exception: "+ee.toString());
+ }
+
+ CMS.debug("DatabasePanel initializeConsumer: Successfully initialize consumer");
+ }
+
+ private boolean replicationDone(String replicadn, LDAPConnection conn, String name)
+ throws IOException {
+ String dn = "cn="+name+","+replicadn;
+ String filter = "(objectclass=*)";
+ String[] attrs = {"nsds5beginreplicarefresh"};
+
+ CMS.debug("DatabasePanel replicationDone: dn: "+dn);
+ try {
+ LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+ attrs, true);
+
+ int count = results.getCount();
+ if (count < 1) {
+ throw new IOException("Replication entry not found");
+ }
+
+ LDAPEntry entry = results.next();
+ LDAPAttribute refresh = entry.getAttribute("nsds5beginreplicarefresh");
+ if (refresh == null) {
+ return true;
+ }
+ return false;
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel replicationDone: exception " + e);
+ throw new IOException("Exception in replicationDone: " + e);
+ }
+ }
+
+ private String replicationStatus(String replicadn, LDAPConnection conn, String name)
+ throws IOException {
+ String dn = "cn="+name+","+replicadn;
+ String filter = "(objectclass=*)";
+ String[] attrs = {"nsds5replicalastinitstatus"};
+ String status = null;
+
+ CMS.debug("DatabasePanel replicationStatus: dn: "+dn);
+ try {
+ LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter,
+ attrs, false);
+
+ int count = results.getCount();
+ if (count < 1) {
+ throw new IOException("Replication entry not found");
+ }
+
+ LDAPEntry entry = results.next();
+ LDAPAttribute attr = entry.getAttribute("nsds5replicalastinitstatus");
+ if (attr != null) {
+ Enumeration valsInAttr = attr.getStringValues();
+ if (valsInAttr.hasMoreElements()) {
+ return (String)valsInAttr.nextElement();
+ } else {
+ throw new IOException("No value returned for nsds5replicalastinitstatus");
+ }
+ } else {
+ throw new IOException("nsDS5ReplicaLastInitStatus is null.");
+ }
+ } catch (Exception e) {
+ CMS.debug("DatabasePanel replicationStatus: exception " + e);
+ throw new IOException("Exception in replicationStatus: " + e);
+ }
+ }
+
+ private String getInstanceDir(LDAPConnection conn) {
+ String instancedir="";
+ try {
+ String filter = "(objectclass=*)";
+ String[] attrs = {"nsslapd-directory"};
+ LDAPSearchResults results = conn.search("cn=config,cn=ldbm database,cn=plugins,cn=config", LDAPv3.SCOPE_SUB,
+ filter, attrs, false);
+
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = results.next();
+ String dn = entry.getDN();
+ CMS.debug("DatabasePanel getInstanceDir: DN for storing nsslapd-directory: "+dn);
+ LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+ Enumeration attrsInSet = entryAttrs.getAttributes();
+ while (attrsInSet.hasMoreElements()) {
+ LDAPAttribute nextAttr = (LDAPAttribute)attrsInSet.nextElement();
+ String attrName = nextAttr.getName();
+ CMS.debug("DatabasePanel getInstanceDir: attribute name: "+attrName);
+ Enumeration valsInAttr = nextAttr.getStringValues();
+ while ( valsInAttr.hasMoreElements() ) {
+ String nextValue = (String)valsInAttr.nextElement();
+ if (attrName.equalsIgnoreCase("nsslapd-directory")) {
+ CMS.debug("DatabasePanel getInstanceDir: instanceDir="+nextValue);
+ return nextValue.substring(0,nextValue.lastIndexOf("/db"));
+ }
+ }
+ }
+ }
+ } catch (LDAPException e) {
+ CMS.debug("DatabasePanel getInstanceDir: Error in retrieving the instance directory. Exception: "+e.toString());
+ }
+
+ return instancedir;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java
new file mode 100644
index 000000000..03f8f2f86
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java
@@ -0,0 +1,45 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class DatabaseServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = Velocity.getTemplate("admin/console/config/database.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java
new file mode 100644
index 000000000..cf25ab0e9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java
@@ -0,0 +1,235 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import org.xml.sax.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.xml.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import com.netscape.cmsutil.http.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.asn1.*;
+import netscape.security.util.*;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.cms.servlet.wizard.*;
+
+public class DisplayCertChainPanel extends WizardPanelBase {
+
+ public DisplayCertChainPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Display Certificate Chain");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Display Certificate Chain");
+ setId(id);
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ public boolean isPanelDone() {
+ return true;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ /**
+ * Should we skip this panel for the configuration.
+ */
+ public boolean shouldSkip() {
+ CMS.debug("DisplayCertChainPanel: should skip");
+
+ IConfigStore cs = CMS.getConfigStore();
+ // if we are root, no need to get the certificate chain.
+
+ try {
+ String select = cs.getString("securitydomain.select","");
+ String type = cs.getString("preop.subsystem.select", "");
+ String hierarchy = cs.getString("preop.hierarchy.select", "");
+
+ if (getId().equals("hierarchy") && hierarchy.equals("root"))
+ return true;
+
+ if (select.equals("new")) {
+ return true;
+ }
+
+ if (type.equals("new") && getId().equals("clone"))
+ return true;
+
+ if (type.equals("clone") && getId().equals("ca"))
+ return true;
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("DisplayCertChainPanel: display");
+
+ // update session id
+ String session_id = request.getParameter("session_id");
+ if (session_id != null) {
+ CMS.debug("DisplayCertChainPanel setting session id.");
+ CMS.setConfigSDSessionId(session_id);
+ }
+
+ String type = getId();
+
+ IConfigStore cs = CMS.getConfigStore();
+ String certChainConfigName = "preop." + type + ".certchain.size";
+ String certchain_size = "";
+
+ try {
+ certchain_size = cs.getString(certChainConfigName, "");
+ } catch (Exception e) {}
+
+ int size = 0;
+ Vector v = new Vector();
+
+ if (!certchain_size.equals("")) {
+ try {
+ size = Integer.parseInt(certchain_size);
+ } catch (Exception e) {}
+ for (int i = 0; i < size; i++) {
+ certChainConfigName = "preop." + type + ".certchain." + i;
+ try {
+ String c = cs.getString(certChainConfigName, "");
+ byte[] b_c = CryptoUtil.base64Decode(c);
+ CertPrettyPrint pp = new CertPrettyPrint(
+ new X509CertImpl(b_c));
+
+ v.addElement(pp.toString(Locale.getDefault()));
+ } catch (Exception e) {}
+ }
+ }
+
+ if (getId().equals("securitydomain")) {
+ context.put("panelid", "securitydomain");
+ context.put("panelname", "Security Domain Trust Verification");
+ } else {
+ context.put("panelid", "other");
+ context.put("panelname", "Subsystem Trust Verification");
+ }
+ context.put("title", "Display Certificate Chain");
+ context.put("panel", "admin/console/config/displaycertchainpanel.vm");
+ context.put("errorString", "");
+ context.put("certchain", v);
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ importCertChain(getId());
+
+ if (getId().equals("securitydomain")) {
+ int panel = getPanelNo()+1;
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String sd_hostname = cs.getString("securitydomain.host", "");
+ int sd_port = cs.getInteger("securitydomain.httpsadminport", -1);
+ String cs_hostname = cs.getString("machineName", "");
+ int cs_port = cs.getInteger("pkicreate.admin_secure_port", -1);
+ String subsystem = cs.getString("cs.type", "");
+ String urlVal = "https://"+cs_hostname+":"+cs_port+"/"+toLowerCaseSubsystemType(subsystem)+"/admin/console/config/wizard?p="+panel+"&subsystem="+subsystem;
+ String encodedValue = URLEncoder.encode(urlVal, "UTF-8");
+ String sdurl = "https://"+sd_hostname+":"+sd_port+"/ca/admin/ca/securityDomainLogin?url="+encodedValue;
+ response.sendRedirect(sdurl);
+
+ // The user previously specified the CA Security Domain's
+ // SSL Admin port in the "Security Domain Panel";
+ // now retrieve this specified CA Security Domain's
+ // non-SSL EE, SSL Agent, and SSL EE ports:
+ cs.putString( "securitydomain.httpport",
+ getSecurityDomainPort( cs, "UnSecurePort" ) );
+ cs.putString("securitydomain.httpsagentport",
+ getSecurityDomainPort( cs, "SecureAgentPort" ) );
+ cs.putString("securitydomain.httpseeport",
+ getSecurityDomainPort( cs, "SecurePort" ) );
+ } catch (Exception ee) {
+ CMS.debug("DisplayCertChainPanel Exception="+ee.toString());
+ }
+ }
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ /* This should never be called */
+ context.put("title", "Display Certificate Chain");
+ context.put("panel", "admin/console/config/displaycertchainpanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java
new file mode 100644
index 000000000..2c0184f26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java
@@ -0,0 +1,45 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class DisplayServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ Template template = null;
+
+ try {
+ String tmpl = request.getParameter("t");
+
+ template = Velocity.getTemplate(tmpl);
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java
new file mode 100644
index 000000000..f21a56de9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java
@@ -0,0 +1,800 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.*;
+import com.netscape.cmsutil.password.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import java.net.*;
+import java.io.*;
+import java.math.*;
+import java.security.cert.*;
+import org.w3c.dom.*;
+import java.util.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class DonePanel extends WizardPanelBase {
+
+ public static final BigInteger BIG_ZERO = new BigInteger("0");
+ public static final Long MINUS_ONE = Long.valueOf(-1);
+ public static final String RESTART_SERVER_AFTER_CONFIGURATION =
+ "restart_server_after_configuration";
+ public static final String PKI_SECURITY_DOMAIN = "pki_security_domain";
+
+ public DonePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Done");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Done");
+ setId(id);
+ }
+
+ public boolean hasSubPanel() {
+ return false;
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ private LDAPConnection getLDAPConn(Context context)
+ throws IOException
+ {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String host = "";
+ String port = "";
+ String pwd = null;
+ String binddn = "";
+ String security = "";
+
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+
+ if (pwdStore != null) {
+ CMS.debug("DonePanel: getLDAPConn: password store available");
+ pwd = pwdStore.getPassword("internaldb");
+ }
+
+ if ( pwd == null) {
+ throw new IOException("DonePanel: Failed to obtain password from password store");
+ }
+
+ try {
+ host = cs.getString("internaldb.ldapconn.host");
+ port = cs.getString("internaldb.ldapconn.port");
+ binddn = cs.getString("internaldb.ldapauth.bindDN");
+ security = cs.getString("internaldb.ldapconn.secureConn");
+ } catch (Exception e) {
+ CMS.debug("DonePanel: getLDAPConn" + e.toString());
+ throw new IOException(
+ "Failed to retrieve LDAP information from CS.cfg.");
+ }
+
+ int p = -1;
+
+ try {
+ p = Integer.parseInt(port);
+ } catch (Exception e) {
+ CMS.debug("DonePanel getLDAPConn: " + e.toString());
+ throw new IOException("Port is not valid");
+ }
+
+ LDAPConnection conn = null;
+ if (security.equals("true")) {
+ CMS.debug("DonePanel getLDAPConn: creating secure (SSL) connection for internal ldap");
+ conn = new LDAPConnection(CMS.getLdapJssSSLSocketFactory());
+ } else {
+ CMS.debug("DonePanel getLDAPConn: creating non-secure (non-SSL) connection for internal ldap");
+ conn = new LDAPConnection();
+ }
+
+ CMS.debug("DonePanel connecting to " + host + ":" + p);
+ try {
+ conn.connect(host, p, binddn, pwd);
+ } catch (LDAPException e) {
+ CMS.debug("DonePanel getLDAPConn: " + e.toString());
+ throw new IOException("Failed to connect to the internal database.");
+ }
+
+ return conn;
+ }
+
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("DonePanel: display()");
+
+ // update session id
+ String session_id = request.getParameter("session_id");
+ if (session_id != null) {
+ CMS.debug("NamePanel setting session id.");
+ CMS.setConfigSDSessionId(session_id);
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+ String ownport = CMS.getEENonSSLPort();
+ String ownsport = CMS.getEESSLPort();
+ String owneeclientauthsport = CMS.getEEClientAuthSSLPort();
+ String ownhost = CMS.getEESSLHost();
+ String ownagentsport = CMS.getAgentPort();
+ String ownagenthost = CMS.getAgentHost();
+ String ownadminsport = CMS.getAdminPort();
+ String ownadminhost = CMS.getAdminHost();
+ String select = "";
+
+ String type = "";
+ String instanceId = "";
+ String instanceRoot = "";
+ try {
+ type = cs.getString("cs.type", "");
+ instanceId = cs.getString("instanceId");
+ instanceRoot = cs.getString("instanceRoot");
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {}
+
+ String initDaemon = "";
+ if (type.equals("CA")) {
+ initDaemon = "pki-cad";
+ } else if (type.equals("KRA")) {
+ initDaemon = "pki-krad";
+ } else if (type.equals("OCSP")) {
+ initDaemon = "pki-ocspd";
+ } else if (type.equals("TKS")) {
+ initDaemon = "pki-tksd";
+ }
+ String os = System.getProperty( "os.name" );
+ if( os.equalsIgnoreCase( "Linux" ) ) {
+ context.put( "initCommand", "/sbin/service " + initDaemon );
+ context.put( "instanceId", instanceId );
+ } else {
+ /* default case: e. g. - ( os.equalsIgnoreCase( "SunOS" ) */
+ context.put( "initCommand", "/etc/init.d/" + initDaemon );
+ context.put( "instanceId", instanceId );
+ }
+ context.put("title", "Done");
+ context.put("panel", "admin/console/config/donepanel.vm");
+ context.put("host", ownadminhost);
+ context.put("port", ownadminsport);
+ String subsystemType = toLowerCaseSubsystemType(type);
+ context.put("systemType", subsystemType);
+
+ try {
+ int state = cs.getInteger("cs.state");
+ if (state == 1) {
+ context.put("csstate", "1");
+ return;
+ } else
+ context.put("csstate", "0");
+
+ } catch (Exception e) {
+ }
+
+ String sd_agent_port = "";
+ String sd_admin_port = "";
+ String sd_host = "";
+ String ca_host = "";
+ try {
+ sd_host = cs.getString("securitydomain.host", "");
+ sd_agent_port = cs.getString("securitydomain.httpsagentport", "");
+ sd_admin_port = cs.getString("securitydomain.httpsadminport", "");
+ ca_host = cs.getString("preop.ca.hostname", "");
+ } catch (Exception e) {
+ }
+
+ if (ca_host.equals(""))
+ context.put("externalCA", "true");
+ else
+ context.put("externalCA", "false");
+
+ // update security domain
+ String sdtype = "";
+ String instanceName = "";
+ String subsystemName = "";
+ try {
+ sdtype = cs.getString("securitydomain.select", "");
+ instanceName = cs.getString("instanceId", "");
+ subsystemName = cs.getString("preop.subsystem.name", "");
+ } catch (Exception e) {
+ }
+
+ boolean cloneMaster = false;
+
+ if (select.equals("clone") && type.equalsIgnoreCase("CA") && isSDHostDomainMaster(cs)) {
+ cloneMaster = true;
+ CMS.debug("Cloning a domain master");
+ }
+
+ String s = getSubsystemNodeName(type);
+ if (sdtype.equals("new")) {
+ try {
+ LDAPConnection conn = getLDAPConn(context);
+
+ String basedn = cs.getString("internaldb.basedn");
+ String secdomain = cs.getString("securitydomain.name");
+
+ try {
+ // Create security domain ldap entry
+ String dn = "ou=Security Domain," + basedn;
+ CMS.debug("DonePanel: creating ldap entry : " + dn);
+
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "pkiSecurityDomain"));
+ if (secdomain.equals("")) {
+ // this should not happen - just in case
+ CMS.debug("DonePanel display(): Security domain is an empty string!");
+ throw new IOException("Security domain is an empty string!");
+ } else {
+ attrs.add(new LDAPAttribute("name", secdomain));
+ }
+ attrs.add(new LDAPAttribute("ou", "Security Domain"));
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ CMS.debug("Unable to create security domain");
+ throw e;
+ }
+
+ try {
+ // create list containers
+ String clist[] = {"CAList", "OCSPList", "KRAList", "RAList", "TKSList", "TPSList"};
+ for (int i=0; i< clist.length; i++) {
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ String dn = "cn=" + clist[i] + ",ou=Security Domain," + basedn;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "pkiSecurityGroup"));
+ attrs.add(new LDAPAttribute("cn", clist[i]));
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ }
+ } catch (Exception e) {
+ CMS.debug("Unable to create security domain list groups" );
+ throw e;
+ }
+
+ try {
+ // Add this host (only CA can create new domain)
+ String cn = ownhost + ":" + ownadminsport;
+ String dn = "cn=" + cn + ",cn=CAList,ou=Security Domain," + basedn;
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "pkiSubsystem"));
+ attrs.add(new LDAPAttribute("Host", ownhost));
+ attrs.add(new LDAPAttribute("SecurePort", ownsport));
+ attrs.add(new LDAPAttribute("SecureAgentPort",
+ ownagentsport));
+ attrs.add(new LDAPAttribute("SecureAdminPort",
+ ownadminsport));
+ if (owneeclientauthsport != null) {
+ attrs.add(new LDAPAttribute("SecureEEClientAuthPort",
+ owneeclientauthsport));
+ }
+ attrs.add(new LDAPAttribute("UnSecurePort", ownport));
+ attrs.add(new LDAPAttribute("Clone", "FALSE"));
+ attrs.add(new LDAPAttribute("SubsystemName", subsystemName));
+ attrs.add(new LDAPAttribute("cn", cn));
+ attrs.add(new LDAPAttribute("DomainManager", "TRUE"));
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ CMS.debug("Unable to create host entry in security domain");
+ throw e;
+ }
+ CMS.debug("DonePanel display: finish updating domain info");
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("DonePanel display: "+e.toString());
+ }
+
+ int sd_admin_port_int = -1;
+ try {
+ sd_admin_port_int = Integer.parseInt( sd_admin_port );
+ } catch (Exception e) {
+ }
+
+ try {
+ // Fetch the "new" security domain and display it
+ CMS.debug( "Dump contents of new Security Domain . . ." );
+ String c = getDomainXML( sd_host, sd_admin_port_int, true );
+ } catch( Exception e ) {}
+
+ // Since this instance is a new Security Domain,
+ // create an empty file to designate this fact.
+ String security_domain = instanceRoot + "/conf/"
+ + PKI_SECURITY_DOMAIN;
+ if( !Utils.isNT() ) {
+ Utils.exec( "touch " + security_domain );
+ Utils.exec( "chmod 00660 " + security_domain );
+ }
+
+ } else { //existing domain
+ int sd_agent_port_int = -1;
+ int sd_admin_port_int = -1;
+ try {
+ sd_agent_port_int = Integer.parseInt(sd_agent_port);
+ sd_admin_port_int = Integer.parseInt(sd_admin_port);
+ } catch (Exception e) {
+ }
+
+ try {
+ String cloneStr = "";
+ if (select.equals("clone"))
+ cloneStr = "&clone=true";
+ else
+ cloneStr = "&clone=false";
+
+ String domainMasterStr = "";
+ if (cloneMaster)
+ domainMasterStr = "&dm=true";
+ else
+ domainMasterStr = "&dm=false";
+ String eecaStr = "";
+ if (owneeclientauthsport != null)
+ eecaStr="&eeclientauthsport=" + owneeclientauthsport;
+
+ updateDomainXML( sd_host, sd_agent_port_int, true,
+ "/ca/agent/ca/updateDomainXML",
+ "list=" + s
+ + "&type=" + type
+ + "&host=" + ownhost
+ + "&name=" + subsystemName
+ + "&sport=" + ownsport
+ + domainMasterStr
+ + cloneStr
+ + "&agentsport=" + ownagentsport
+ + "&adminsport=" + ownadminsport
+ + eecaStr
+ + "&httpport=" + ownport );
+
+ // Fetch the "updated" security domain and display it
+ CMS.debug( "Dump contents of updated Security Domain . . ." );
+ String c = getDomainXML( sd_host, sd_admin_port_int, true );
+ } catch (Exception e) {
+ context.put("errorString", "Failed to update the security domain on the domain master.");
+ //return;
+ }
+ }
+
+ // add service.securityDomainPort to CS.cfg in case pkiremove
+ // needs to remove system reference from the security domain
+ try {
+ cs.putString("service.securityDomainPort", ownagentsport);
+ cs.putString("securitydomain.store", "ldap");
+ cs.commit(false);
+ } catch (Exception e) {
+ CMS.debug("DonePanel: exception in adding service.securityDomainPort to CS.cfg" + e);
+ }
+
+
+ // need to push connector information to the CA
+ if (type.equals("KRA") && !ca_host.equals("")) {
+ try {
+ updateConnectorInfo(ownagenthost, ownagentsport);
+ } catch (IOException e) {
+ context.put("errorString", "Failed to update connector information.");
+ return;
+ }
+ setupClientAuthUser();
+ } // if KRA
+
+ // import the CA certificate into the OCSP
+ // configure the CRL Publishing to OCSP in CA
+ if (type.equals("OCSP") && !ca_host.equals("")) {
+ try {
+ CMS.reinit(IOCSPAuthority.ID);
+ importCACertToOCSP();
+ } catch (Exception e) {
+ CMS.debug("DonePanel display: Failed to import the CA certificate into OCSP.");
+ }
+
+ try {
+ updateOCSPConfig(response);
+ } catch (Exception e) {
+ CMS.debug("DonePanel display: Failed to update OCSP information in CA.");
+ }
+
+ setupClientAuthUser();
+ }
+
+ if (!select.equals("clone")) {
+ if (type.equals("CA") || type.equals("KRA")) {
+ String beginRequestNumStr = "";
+ String endRequestNumStr = "";
+ String beginSerialNumStr = "";
+ String endSerialNumStr = "";
+ String requestIncStr = "";
+ String serialIncStr = "";
+
+ try {
+ endRequestNumStr = cs.getString("dbs.endRequestNumber", "");
+ endSerialNumStr = cs.getString("dbs.endSerialNumber", "");
+ BigInteger endRequestNum = new BigInteger(endRequestNumStr);
+ BigInteger endSerialNum = new BigInteger(endSerialNumStr);
+ BigInteger oneNum = new BigInteger("1");
+
+ // update global next range entries
+ LDAPConnection conn = getLDAPConn(context);
+ String basedn = cs.getString("internaldb.basedn");
+
+ String serialdn = "";
+ if (type.equals("CA")) {
+ serialdn = "ou=certificateRepository,ou=" + type.toLowerCase() + "," + basedn;
+ } else {
+ serialdn = "ou=keyRepository,ou=" + type.toLowerCase() + "," + basedn;
+ }
+ LDAPAttribute attrSerialNextRange = new LDAPAttribute( "nextRange", endSerialNum.add(oneNum).toString());
+ LDAPModification serialmod = new LDAPModification( LDAPModification.REPLACE, attrSerialNextRange );
+ conn.modify( serialdn, serialmod );
+
+ String requestdn = "ou=" + type.toLowerCase() + ",ou=requests," + basedn;
+ LDAPAttribute attrRequestNextRange = new LDAPAttribute( "nextRange", endRequestNum.add(oneNum).toString());
+ LDAPModification requestmod = new LDAPModification( LDAPModification.REPLACE, attrRequestNextRange );
+ conn.modify( requestdn, requestmod );
+
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("Unable to update global next range numbers: " + e);
+ }
+ }
+ }
+
+ if (cloneMaster) {
+ // cloning a domain master CA, the clone is also master of its domain
+ try {
+ cs.putString("securitydomain.host", ownhost);
+ cs.putString("securitydomain.httpport", ownport);
+ cs.putString("securitydomain.httpsadminport", ownadminsport);
+ cs.putString("securitydomain.httpsagentport", ownagentsport);
+ cs.putString("securitydomain.httpseeport", ownsport);
+ cs.putString("securitydomain.select", "new");
+ } catch (Exception e) {
+ CMS.debug("Caught exception trying to save security domain parameters for clone of a domain master");
+ }
+ }
+
+ cs.putInteger("cs.state", 1);
+ try {
+ // save variables needed for cloning and remove preop
+ String list = cs.getString("preop.cert.list", "");
+ StringTokenizer st = new StringTokenizer(list, ",");
+
+ while (st.hasMoreTokens()) {
+ String ss = st.nextToken();
+ if (ss.equals("sslserver"))
+ continue;
+ cs.putString("cloning." + ss + ".nickname", cs.getString("preop.cert." + ss + ".nickname", ""));
+ cs.putString("cloning." + ss + ".dn", cs.getString("preop.cert." + ss + ".dn", ""));
+ cs.putString("cloning." + ss + ".keytype", cs.getString("preop.cert." + ss + ".keytype", ""));
+ cs.putString("cloning." + ss + ".keyalgorithm", cs.getString("preop.cert." + ss + ".keyalgorithm", ""));
+ cs.putString("cloning." + ss + ".privkey.id", cs.getString("preop.cert." + ss + ".privkey.id", ""));
+ cs.putString("cloning." + ss + ".pubkey.exponent", cs.getString("preop.cert." + ss + ".pubkey.exponent", ""));
+ cs.putString("cloning." + ss + ".pubkey.modulus", cs.getString("preop.cert." + ss + ".pubkey.modulus", ""));
+ cs.putString("cloning." + ss + ".pubkey.encoded", cs.getString("preop.cert." + ss + ".pubkey.encoded", ""));
+ }
+ cs.putString("cloning.module.token", cs.getString("preop.module.token", ""));
+ cs.putString("cloning.list", list);
+
+ // more cloning variables needed for non-ca clones
+
+ if (! type.equals("CA")) {
+ String val = cs.getString("preop.ca.hostname", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.hostname", val);
+
+ val = cs.getString("preop.ca.httpport", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.httpport", val);
+
+ val = cs.getString("preop.ca.httpsport", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.httpsport", val);
+
+ val = cs.getString("preop.ca.list", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.list", val);
+
+ val = cs.getString("preop.ca.pkcs7", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.pkcs7", val);
+
+ val = cs.getString("preop.ca.type", "");
+ if (val.compareTo("") != 0) cs.putString("cloning.ca.type", val);
+ }
+
+ // save EC type for sslserver cert (if present)
+ cs.putString("jss.ssl.sslserver.ectype", cs.getString("preop.cert.sslserver.ec.type", "ECDHE"));
+
+ cs.removeSubStore("preop");
+ cs.commit(false);
+
+ // Create an empty file that designates the fact that although
+ // this server instance has been configured, it has NOT yet
+ // been restarted!
+ String restart_server = instanceRoot + "/conf/"
+ + RESTART_SERVER_AFTER_CONFIGURATION;
+ if( !Utils.isNT() ) {
+ Utils.exec( "touch " + restart_server );
+ Utils.exec( "chmod 00660 " + restart_server );
+ }
+
+ } catch (Exception e) {
+ CMS.debug("Caught exception saving preop variables: " + e);
+ }
+
+ context.put("csstate", "1");
+ }
+
+ private void setupClientAuthUser()
+ {
+ IConfigStore cs = CMS.getConfigStore();
+
+ // retrieve CA subsystem certificate from the CA
+ IUGSubsystem system =
+ (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+ String id = "";
+ try {
+ String b64 = getCASubsystemCert();
+ if (b64 != null) {
+ int num = cs.getInteger("preop.subsystem.count", 0);
+ id = getCAUserId();
+ num++;
+ cs.putInteger("preop.subsystem.count", num);
+ cs.putInteger("subsystem.count", num);
+ IUser user = system.createUser(id);
+ user.setFullName(id);
+ user.setEmail("");
+ user.setPassword("");
+ user.setUserType("agentType");
+ user.setState("1");
+ user.setPhone("");
+ X509CertImpl[] certs = new X509CertImpl[1];
+ certs[0] = new X509CertImpl(CMS.AtoB(b64));
+ user.setX509Certificates(certs);
+ system.addUser(user);
+ CMS.debug("DonePanel display: successfully add the user");
+ system.addUserCert(user);
+ CMS.debug("DonePanel display: successfully add the user certificate");
+ cs.commit(false);
+ }
+ } catch (Exception e) {
+ }
+
+ try {
+ String groupName = "Trusted Managers";
+ IGroup group = system.getGroupFromName(groupName);
+ if (!group.isMember(id)) {
+ group.addMemberName(id);
+ system.modifyGroup(group);
+ CMS.debug("DonePanel display: successfully added the user to the group.");
+ }
+ } catch (Exception e) {
+ }
+ }
+
+
+ private void updateOCSPConfig(HttpServletResponse response)
+ throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String cahost = "";
+ int caport = -1;
+ String sdhost = "";
+ int sdport = -1;
+
+ try {
+ cahost = config.getString("preop.ca.hostname", "");
+ caport = config.getInteger("preop.ca.httpsport", -1);
+ sdhost = config.getString("securitydomain.host", "");
+ sdport = config.getInteger("securitydomain.httpseeport", -1);
+ } catch (Exception e) {
+ }
+
+ String ocsphost = CMS.getAgentHost();
+ int ocspport = Integer.parseInt(CMS.getAgentPort());
+ int ocspagentport = Integer.parseInt(CMS.getAgentPort());
+ String session_id = CMS.getConfigSDSessionId();
+ String content = "xmlOutput=true&sessionID="+session_id+"&ocsp_host="+ocsphost+"&ocsp_port="+ocspport;
+
+ updateOCSPConfig(cahost, caport, true, content, response);
+ }
+
+ private void importCACertToOCSP() throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+
+ // get certificate chain from CA
+ try {
+ String b64 = config.getString("preop.ca.pkcs7", "");
+
+ if (b64.equals(""))
+ throw new IOException("Failed to get certificate chain.");
+
+ try {
+ // this could be a chain
+ X509Certificate[] certs = Cert.mapCertFromPKCS7(b64);
+ X509Certificate leafCert = null;
+ if (certs != null && certs.length > 0) {
+ if (certs[0].getSubjectDN().getName().equals(certs[0].getIssuerDN().getName())) {
+ leafCert = certs[certs.length - 1];
+ } else {
+ leafCert = certs[0];
+ }
+
+ IOCSPAuthority ocsp =
+ (IOCSPAuthority)CMS.getSubsystem(IOCSPAuthority.ID);
+ IDefStore defStore = ocsp.getDefaultStore();
+
+ // (1) need to normalize (sort) the chain
+
+ // (2) store certificate (and certificate chain) into
+ // database
+ ICRLIssuingPointRecord rec = defStore.createCRLIssuingPointRecord(
+ leafCert.getSubjectDN().getName(),
+ BIG_ZERO,
+ MINUS_ONE, null, null);
+
+ try {
+ rec.set(ICRLIssuingPointRecord.ATTR_CA_CERT, leafCert.getEncoded());
+ } catch (Exception e) {
+ // error
+ }
+ defStore.addCRLIssuingPoint(leafCert.getSubjectDN().getName(), rec);
+ //log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Added CA certificate " + leafCert.getSubjectDN().getName());
+
+ CMS.debug("DonePanel importCACertToOCSP: Added CA certificate.");
+ }
+ } catch (Exception e) {
+ throw new IOException("Failed to encode the certificate chain");
+ }
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("DonePanel importCACertToOCSP: Failed to import the certificate chain into the OCSP");
+ throw new IOException("Failed to import the certificate chain into the OCSP");
+ }
+ }
+
+ private String getCASubsystemCert() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ String host = "";
+ int port = -1;
+ try {
+ host = cs.getString("preop.ca.hostname", "");
+ port = cs.getInteger("preop.ca.httpsadminport", -1);
+ } catch (Exception e) {
+ }
+
+ return getSubsystemCert(host, port, true);
+ }
+
+ private String getCAUserId() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ String host = "";
+ int port = -1;
+ try {
+ host = cs.getString("preop.ca.hostname", "");
+ port = cs.getInteger("preop.ca.httpsport", -1);
+ } catch (Exception e) {
+ }
+
+ return "CA-" + host + "-" + port;
+ }
+
+ private void updateConnectorInfo(String ownagenthost, String ownagentsport)
+ throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ int port = -1;
+ String url = "";
+ String host = null;
+ String transportCert = "";
+ try {
+ url = cs.getString("preop.ca.url", "");
+ if (!url.equals("")) {
+ host = cs.getString("preop.ca.hostname", "");
+ port = cs.getInteger("preop.ca.httpsadminport", -1);
+ transportCert = cs.getString("kra.transport.cert", "");
+ }
+ } catch (Exception e) {
+ }
+
+ if (host == null) {
+ CMS.debug("DonePanel: preop.ca.url is not defined. External CA selected. No transport certificate setup is required");
+ } else {
+ CMS.debug("DonePanel: Transport certificate is being setup in " + url);
+ String session_id = CMS.getConfigSDSessionId();
+ String content = "ca.connector.KRA.enable=true&ca.connector.KRA.local=false&ca.connector.KRA.timeout=30&ca.connector.KRA.uri=/kra/agent/kra/connector&ca.connector.KRA.host="+ownagenthost+"&ca.connector.KRA.port="+ownagentsport+"&ca.connector.KRA.transportCert="+URLEncoder.encode(transportCert)+"&sessionID="+session_id;
+
+ updateConnectorInfo(host, port, true, content);
+ }
+ }
+
+ private String getSubsystemNodeName(String type) {
+ if (type.equals("CA")) {
+ return "CAList";
+ } else if (type.equals("KRA")) {
+ return "KRAList";
+ } else if (type.equals("TKS")) {
+ return "TKSList";
+ } else if (type.equals("OCSP")) {
+ return "OCSPList";
+ }
+
+ return "";
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {}
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {/* This should never be called */}
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java
new file mode 100644
index 000000000..ecc1e7e40
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java
@@ -0,0 +1,146 @@
+// --- 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.servlet.csadmin;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.crypto.*;
+
+public class DownloadPKCS12 extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public DownloadPKCS12() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("DownloadPKCS12: initializing...");
+ super.init(sc);
+ CMS.debug("DownloadPKCS12: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("DownloadPKCS12: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IConfigStore cs = CMS.getConfigStore();
+ mRenderResult = false;
+
+ // check the pin from the session
+ String pin = (String)httpReq.getSession().getAttribute("pin");
+ if (pin == null) {
+ CMS.debug("DownloadPKCS12 process: Failed to get the pin from the cookie.");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ String cspin = "";
+ try {
+ cspin = cs.getString("preop.pin");
+ } catch (Exception e) {
+ }
+
+ if (!pin.equals(cspin)) {
+ CMS.debug("DownloadPKCS12 process: Wrong pin");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ byte[] pkcs12 = null;
+ try {
+ String str = cs.getString("preop.pkcs12");
+ pkcs12 = CryptoUtil.string2byte(str);
+ } catch (Exception e) {
+ }
+
+ try {
+ httpResp.setContentType("application/x-pkcs12");
+ httpResp.getOutputStream().write(pkcs12);
+ return;
+ } catch (Exception e) {
+ CMS.debug("DownloadPKCS12 process: Exception="+e.toString());
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java
new file mode 100644
index 000000000..3a9a36e91
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java
@@ -0,0 +1,160 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+
+public class GetCertChain extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public GetCertChain() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ String outputString = null;
+
+ CertificateChain certChain = ((ICertAuthority) mAuthority).getCACertChain();
+
+ if (certChain == null) {
+ CMS.debug(
+ "GetCertChain displayChain: cannot get the certificate chain.");
+ outputError(httpResp, "Error: Failed to get certificate chain.");
+ return;
+ }
+
+ byte[] bytes = null;
+
+ try {
+ ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+
+ certChain.encode(encoded);
+ bytes = encoded.toByteArray();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_CA_CHAIN_1",
+ e.toString()));
+ outputError(httpResp,
+ "Error: Failed to encode the certificate chain");
+ }
+
+ String chainBase64 = CMS.BtoA(bytes);
+
+ chainBase64 = normalizeCertStr(chainBase64);
+
+ try {
+ XMLObject xmlObj = null;
+
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "ChainBase64", chainBase64);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ private String normalizeCertStr(String s) {
+ StringBuffer val = new StringBuffer();
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val.append(s.charAt(i));
+ }
+ return val.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
new file mode 100644
index 000000000..c47bfdc1c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
@@ -0,0 +1,211 @@
+// --- 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.servlet.csadmin;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.password.*;
+import org.w3c.dom.*;
+
+public class GetConfigEntries extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public GetConfigEntries() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ CMS.debug("GetConfigEntries init");
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+
+ try {
+ authToken = authenticate(cmsReq);
+ } catch (Exception e) {
+ CMS.debug("GetConfigEntries authentication failed");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ // Get the operation code
+ String op = null;
+
+ op = args.getValueAsString("op", null);
+ CMS.debug("GetConfigEntries process: op=" + op);
+
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+ } catch (Exception e) {
+ CMS.debug("GetConfigEntries process: Exception: "+e.toString());
+ throw new EBaseException( e.toString() );
+ }
+
+ Node root = xmlObj.createRoot("XMLResponse");
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ if (op != null) {
+ IConfigStore config = CMS.getConfigStore();
+ String substores = args.getValueAsString("substores", "");
+ StringTokenizer t = new StringTokenizer(substores, ",");
+ while (t.hasMoreTokens()) {
+ String name1 = t.nextToken();
+ IConfigStore cs = config.getSubStore(name1);
+ Enumeration enum1 = cs.getPropertyNames();
+
+ while (enum1.hasMoreElements()) {
+ String name = name1+"."+enum1.nextElement();
+ try {
+ String value = config.getString(name);
+ Node container = xmlObj.createContainer(root, "Config");
+ xmlObj.addItemToContainer(container, "name", name);
+ xmlObj.addItemToContainer(container, "value", value);
+ } catch (Exception ee) {
+ continue;
+ }
+ }
+ }
+
+ String names = args.getValueAsString("names", "");
+ StringTokenizer t1 = new StringTokenizer(names, ",");
+ while (t1.hasMoreTokens()) {
+ String name = t1.nextToken();
+ String value = "";
+
+ try {
+ CMS.debug("Retrieving config name=" + name);
+ value = config.getString(name);
+ CMS.debug("Retrieving config value=" + value);
+ if (value.equals("localhost"))
+ value = config.getString("machineName", "");
+ } catch (Exception ee) {
+ if (name.equals("internaldb.ldapauth.password")) {
+ value = getLDAPPassword();
+ } else if (name.equals("internaldb.replication.password")) {
+ value = getReplicationPassword();
+ } else
+ continue;
+ }
+
+ Node container = xmlObj.createContainer(root, "Config");
+ xmlObj.addItemToContainer(container, "name", name);
+ xmlObj.addItemToContainer(container, "value", value);
+ }
+ }
+
+ try {
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ private String getLDAPPassword() {
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+ return pwdStore.getPassword("internaldb");
+ }
+
+ private String getReplicationPassword() {
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+ return pwdStore.getPassword("replicationdb");
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java
new file mode 100644
index 000000000..b78b98b82
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java
@@ -0,0 +1,276 @@
+// --- 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.servlet.csadmin;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.net.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+
+public class GetCookie extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private static Random mRandom = null;
+ private final static int SESSION_MAX_AGE = 3600;
+ private String mErrorFormPath = null;
+ private String mFormPath = null;
+
+ public GetCookie() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ CMS.debug("GetCookie init");
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mRandom = new Random();
+ mErrorFormPath = sc.getInitParameter("errorTemplatePath");
+ if (mOutputTemplatePath != null) {
+ mFormPath = mOutputTemplatePath;
+ }
+ }
+
+ /**
+ * Process the HTTP request.
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ CMS.debug("GetCookie start");
+ IAuthToken authToken = null;
+ int sessionMaxAge = SESSION_MAX_AGE;
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ sessionMaxAge = cs.getInteger("sessionMaxAge", SESSION_MAX_AGE);
+ } catch (Exception e) {
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ String url = httpReq.getParameter("url");
+ CMS.debug("GetCookie before auth, url ="+url);
+ String url_e = "";
+ URL u = null;
+ try {
+ url_e = URLDecoder.decode(url, "UTF-8");
+ u = new URL(url_e);
+ } catch (Exception eee) {
+ throw new ECMSGWException(
+ "GetCookie missing parameter: url");
+ }
+
+ int index2 = url_e.indexOf("subsystem=");
+ String subsystem = "";
+ if (index2 > 0) {
+ subsystem = url.substring(index2+10);
+ int index1 = subsystem.indexOf("&");
+ if (index1 > 0)
+ subsystem = subsystem.substring(0, index1);
+ }
+
+ try {
+ authToken = authenticate(cmsReq);
+ } catch (Exception e) {
+ CMS.debug("GetCookie authentication failed");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ header.addStringValue("sd_uid", "");
+ header.addStringValue("sd_pwd", "");
+ header.addStringValue("host", u.getHost());
+ header.addStringValue("sdhost", CMS.getEESSLHost());
+ header.addStringValue("subsystem", subsystem);
+ header.addStringValue("url", url_e);
+ header.addStringValue("errorString", "Failed Authentication");
+ String sdname = cs.getString("securitydomain.name", "");
+ header.addStringValue("sdname", sdname);
+
+ CMS.debug("mErrorFormPath=" + mErrorFormPath);
+ try {
+ form = getTemplate(mErrorFormPath, httpReq, locale);
+ } catch (IOException eee) {
+ CMS.debug("GetCookie process: cant locate the form");
+/*
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+*/
+ }
+
+ if( form == null ) {
+ CMS.debug("GetCookie::process() - form is null!");
+ throw new EBaseException( "form is null" );
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException ee) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", ee.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ return;
+ }
+
+ String cookie = "";
+ if (authToken != null) {
+ String uid = authToken.getInString("uid");
+ String groupname = getGroupName(uid, subsystem);
+
+ if (groupname != null) {
+ // assign cookie
+ long num = mRandom.nextLong();
+ cookie = num+"";
+ ISecurityDomainSessionTable ctable = CMS.getSecurityDomainSessionTable();
+ String addr = "";
+ try {
+ addr = u.getHost();
+ } catch (Exception e) {
+ }
+ String ip = "";
+ try {
+ ip = InetAddress.getByName(addr).toString();
+ int index = ip.indexOf("/");
+ if (index > 0)
+ ip = ip.substring(index+1);
+ } catch (Exception e) {
+ }
+
+ ctable.addEntry(cookie, ip, uid, groupname);
+ try {
+ String sd_url = "https://"+CMS.getEESSLHost()+":"+CMS.getEESSLPort();
+ if (!url.startsWith("$")) {
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ CMS.debug("GetCookie process: cant locate the form");
+/*
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+*/
+ }
+
+ header.addStringValue("url", url);
+ header.addStringValue("session_id", cookie);
+
+ EBaseException error = null;
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ if (error == null) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ private String getGroupName(String uid, String subsystemname) {
+ String groupname = "";
+ IUGSubsystem subsystem =
+ (IUGSubsystem)(CMS.getSubsystem(IUGSubsystem.ID));
+ if (subsystem.isMemberOf(uid, "Enterprise CA Administrators") &&
+ subsystemname.equals("CA")) {
+ return "Enterprise CA Administrators";
+ } else if (subsystem.isMemberOf(uid, "Enterprise KRA Administrators") &&
+ subsystemname.equals("KRA")) {
+ return "Enterprise KRA Administrators";
+ } else if (subsystem.isMemberOf(uid, "Enterprise OCSP Administrators") &&
+ subsystemname.equals("OCSP")) {
+ return "Enterprise OCSP Administrators";
+ } else if (subsystem.isMemberOf(uid, "Enterprise TKS Administrators") &&
+ subsystemname.equals("TKS")) {
+ return "Enterprise TKS Administrators";
+ } else if (subsystem.isMemberOf(uid, "Enterprise RA Administrators") &&
+ subsystemname.equals("RA")) {
+ return "Enterprise RA Administrators";
+ } else if (subsystem.isMemberOf(uid, "Enterprise TPS Administrators") &&
+ subsystemname.equals("TPS")) {
+ return "Enterprise TPS Administrators";
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java
new file mode 100644
index 000000000..f2b4589e3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java
@@ -0,0 +1,241 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+public class GetDomainXML extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public GetDomainXML() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("GetDomainXML: initializing...");
+ super.init(sc);
+ CMS.debug("GetDomainXML: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("GetDomainXML: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ ServletContext context = cmsReq.getServletContext();
+
+ String status = SUCCESS;
+ String basedn = null;
+ String secstore = null;
+
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ secstore = cs.getString("securitydomain.store");
+ basedn = cs.getString("internaldb.basedn");
+ }
+ catch (Exception e) {
+ CMS.debug("Unable to determine the security domain name or internal basedn. Please run the domaininfo migration script");
+ }
+
+ try {
+ XMLObject response = new XMLObject();
+ Node root = response.createRoot("XMLResponse");
+
+ if ((secstore != null) && (basedn != null) && (secstore.equals("ldap"))) {
+ ILdapConnFactory connFactory = null;
+ LDAPConnection conn = null;
+ try {
+ // get data from ldap
+ String[] entries = {};
+ String filter = "objectclass=pkiSecurityGroup";
+ LDAPSearchConstraints cons = null;
+ String[] attrs = null;
+ String dn = "ou=Security Domain," + basedn;
+
+ IConfigStore ldapConfig = cs.getSubStore("internaldb");
+ connFactory = CMS.getLdapBoundConnFactory();
+ connFactory.init(ldapConfig);
+ conn = connFactory.getConn();
+
+ // get the security domain name
+ String secdomain = (String) conn.read(dn).getAttribute("name").getStringValues().nextElement();
+
+ XMLObject xmlObj = new XMLObject();
+ Node domainInfo = xmlObj.createRoot("DomainInfo");
+ xmlObj.addItemToContainer(domainInfo, "Name", secdomain);
+
+ // this should return CAList, KRAList etc.
+ LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_ONE, filter,
+ attrs, true, cons);
+
+ while (res.hasMoreElements()) {
+ int count = 0;
+ dn = res.next().getDN();
+ String listName = dn.substring(3, dn.indexOf(","));
+ String subType = listName.substring(0, listName.indexOf("List"));
+ Node listNode = xmlObj.createContainer(domainInfo, listName);
+
+ filter = "objectclass=pkiSubsystem";
+ LDAPSearchResults res2 = conn.search(dn, LDAPConnection.SCOPE_ONE, filter,
+ attrs, false, cons);
+ while (res2.hasMoreElements()) {
+ Node node = xmlObj.createContainer(listNode, subType);
+ LDAPEntry entry = res2.next();
+ LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+ Enumeration attrsInSet = entryAttrs.getAttributes();
+ while (attrsInSet.hasMoreElements()) {
+ LDAPAttribute nextAttr = (LDAPAttribute) attrsInSet.nextElement();
+ String attrName = nextAttr.getName();
+ if ((! attrName.equals("cn")) && (! attrName.equals("objectClass"))) {
+ String attrValue = (String) nextAttr.getStringValues().nextElement();
+ xmlObj.addItemToContainer(node, securityDomainLDAPtoXML(attrName), attrValue);
+ }
+ }
+ count ++;
+ }
+ xmlObj.addItemToContainer(listNode, "SubsystemCount", Integer.toString(count));
+ }
+
+ // Add new xml object as string to response.
+ response.addItemToContainer(root, "DomainInfo", xmlObj.toXMLString());
+ }
+ catch (Exception e) {
+ CMS.debug("GetDomainXML: Failed to read domain.xml from ldap " + e.toString());
+ status = FAILED;
+ }
+ finally {
+ if ((conn != null) && (connFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ connFactory.returnConn(conn);
+ }
+ }
+ }
+ else {
+ // get data from file store
+
+ String path = CMS.getConfigStore().getString("instanceRoot", "")
+ + "/conf/domain.xml";
+
+ CMS.debug("GetDomainXML: got path=" + path);
+
+ try {
+ CMS.debug("GetDomainXML: Reading domain.xml from file ...");
+ FileInputStream fis = new FileInputStream(path);
+ int s = fis.available();
+
+ CMS.debug("GetDomainXML: size " + s);
+ byte buf[] = new byte[s];
+
+ fis.read(buf, 0, s);
+ fis.close();
+ CMS.debug("GetDomainXML: Done Reading domain.xml...");
+
+ response.addItemToContainer(root, "DomainInfo", new String(buf));
+ }
+ catch (Exception e) {
+ CMS.debug("Failed to read domain.xml from file" + e.toString());
+ status = FAILED;
+ }
+ }
+
+ response.addItemToContainer(root, "Status", status);
+ byte[] cb = response.toByteArray();
+ outputResult(httpResp, "application/xml", cb);
+
+ } catch (Exception e) {
+ CMS.debug("GetDomainXML: Failed to send the XML output" + e.toString());
+ }
+ }
+
+ protected String securityDomainLDAPtoXML(String attribute) {
+ if (attribute.equals("host")) return "Host";
+ else return attribute;
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java
new file mode 100644
index 000000000..5f533fbe4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java
@@ -0,0 +1,115 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+
+public class GetStatus extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public GetStatus() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ }
+
+ /**
+ * Process the HTTP request.
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IConfigStore config = CMS.getConfigStore();
+
+ String outputString = null;
+
+ String state = config.getString("cs.state", "");
+ String type = config.getString("cs.type", "");
+
+ try {
+ XMLObject xmlObj = null;
+
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "State", state);
+ xmlObj.addItemToContainer(root, "Type", type);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java
new file mode 100644
index 000000000..ab6a1aa01
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java
@@ -0,0 +1,155 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.crypto.*;
+import org.w3c.dom.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.X509Certificate;
+
+
+public class GetSubsystemCert extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public GetSubsystemCert() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ String outputString = null;
+
+ IConfigStore cs = CMS.getConfigStore();
+ String nickname = "";
+ try {
+ nickname = cs.getString("ca.subsystem.nickname", "");
+ String tokenname = cs.getString("ca.subsystem.tokenname", "");
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ } catch (Exception e) {
+ }
+
+ CMS.debug("GetSubsystemCert process: nickname="+nickname);
+ String s = "";
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate cert = cm.findCertByNickname(nickname);
+
+ if (cert == null) {
+ CMS.debug("GetSubsystemCert process: subsystem cert is null");
+ outputError(httpResp, "Error: Failed to get subsystem certificate.");
+ return;
+ }
+
+ byte[] bytes = cert.getEncoded();
+ s = CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bytes));
+ } catch (Exception e) {
+ CMS.debug("GetSubsystemCert process: exception: "+e.toString());
+ }
+
+ try {
+ XMLObject xmlObj = null;
+ xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "Cert", s);
+ byte[] cb = xmlObj.toByteArray();
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ private String normalizeCertStr(String s) {
+ StringBuffer val = new StringBuffer();
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val.append(s.charAt(i));
+ }
+ return val.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java
new file mode 100644
index 000000000..442826c42
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java
@@ -0,0 +1,147 @@
+// --- 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.servlet.csadmin;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.password.*;
+import org.w3c.dom.*;
+
+public class GetTokenInfo extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public GetTokenInfo() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ CMS.debug("GetTokenInfo init");
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+ } catch (Exception e) {
+ CMS.debug("GetTokenInfo process: Exception: "+e.toString());
+ throw new EBaseException( e.toString() );
+ }
+
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ IConfigStore config = CMS.getConfigStore();
+
+ String certlist = "";
+ try {
+ certlist = config.getString("cloning.list");
+ } catch (Exception e) {
+ }
+
+ StringTokenizer t1 = new StringTokenizer(certlist, ",");
+ while (t1.hasMoreTokens()) {
+ String name = t1.nextToken();
+ if (name.equals("sslserver"))
+ continue;
+ name = "cloning."+name+".nickname";
+ String value = "";
+
+ try {
+ value = config.getString(name);
+ } catch (Exception ee) {
+ continue;
+ }
+
+ Node container = xmlObj.createContainer(root, "Config");
+ xmlObj.addItemToContainer(container, "name", name);
+ xmlObj.addItemToContainer(container, "value", value);
+ }
+
+ String value = "";
+ String name = "cloning.module.token";
+ try {
+ value = config.getString(name);
+ } catch (Exception e) {
+ }
+
+ Node container = xmlObj.createContainer(root, "Config");
+ xmlObj.addItemToContainer(container, "name", name);
+ xmlObj.addItemToContainer(container, "value", value);
+
+ try {
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java
new file mode 100644
index 000000000..21e64086e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java
@@ -0,0 +1,189 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.util.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.*;
+
+/**
+ * This servlet retrieves the transport certificate from DRM.
+ */
+public class GetTransportCert extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public GetTransportCert() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("GetTransportCert: initializing...");
+ super.init(sc);
+ CMS.debug("GetTransportCert: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateUpdater: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(cmsReq);
+ CMS.debug("GetTransportCert authentication successful.");
+ } catch (Exception e) {
+ CMS.debug("GetTransportCert: authentication failed.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ if (authToken == null) {
+ CMS.debug("GetTransportCert: authentication failed.");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "read");
+ CMS.debug("GetTransportCert authorization successful.");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ IKeyRecoveryAuthority kra =
+ (IKeyRecoveryAuthority) mAuthority;
+ ITransportKeyUnit tu = kra.getTransportKeyUnit();
+ org.mozilla.jss.crypto.X509Certificate transportCert =
+ tu.getCertificate();
+
+ String mime64 = "";
+ try {
+ mime64 = CMS.BtoA(transportCert.getEncoded());
+ mime64 = com.netscape.cmsutil.util.Cert.normalizeCertStrAndReq(mime64);
+ } catch (CertificateEncodingException eee) {
+ CMS.debug("GetTransportCert: Failed to encode certificate");
+ }
+
+ // send success status back to the requestor
+ try {
+ CMS.debug("GetTransportCert: Sending response " + mime64);
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "TransportCert", mime64);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("GetTransportCert: Failed to send the XML output " + e);
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java
new file mode 100644
index 000000000..653387bf4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java
@@ -0,0 +1,203 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+
+import java.util.*;
+import java.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+
+import netscape.security.x509.*;
+import com.netscape.cms.servlet.wizard.*;
+
+public class HierarchyPanel extends WizardPanelBase {
+
+ public HierarchyPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("PKI Hierarchy");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("PKI Hierarchy");
+ setId(id);
+ }
+
+ public boolean shouldSkip() {
+
+ // we dont need to ask the hierachy if we are
+ // setting up a clone
+ try {
+ IConfigStore c = CMS.getConfigStore();
+ String s = c.getString("preop.subsystem.select",
+ null);
+ if (s != null && s.equals("clone")) {
+ // mark this panel as done
+ c.putString("preop.hierarchy.select","root");
+ c.putString("hierarchy.select","Clone");
+ return true;
+ }
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.hierarchy.select", "");
+ cs.putString("hierarchy.select", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.hierarchy.select", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "PKI Hierarchy");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+ try {
+ String s = config.getString("preop.hierarchy.select");
+
+ if (s.equals("root")) {
+ context.put("check_root", "checked");
+ } else if (s.equals("join")) {
+ context.put("check_join", "checked");
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("check_root", "checked");
+ context.put("check_join", "");
+ }
+
+ context.put("panel", "admin/console/config/hierarchypanel.vm");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ try {
+ String cstype = config.getString("preop.subsystem.select", "");
+ if (cstype.equals("clone")) {
+ context.put("updateStatus", "success");
+ return;
+ }
+ } catch (Exception e) {
+ }
+
+ String select = HttpInput.getID(request, "choice");
+
+ if (select == null) {
+ CMS.debug("HierarchyPanel: choice not found");
+ context.put("updateStatus", "failure");
+ throw new IOException("choice not found");
+ }
+
+ if (select.equals("root")) {
+ config.putString("preop.hierarchy.select", "root");
+ config.putString("hierarchy.select", "Root");
+ config.putString("preop.ca.type", "sdca");
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {}
+ } else if (select.equals("join")) {
+ config.putString(PCERT_PREFIX + "signing.type", "remote");
+ config.putString("preop.hierarchy.select", "join");
+ config.putString("hierarchy.select", "Subordinate");
+ } else {
+ config.putString(PCERT_PREFIX + "signing.type", "remote");
+ CMS.debug("HierarchyPanel: invalid choice " + select);
+ context.put("updateStatus", "failure");
+ throw new IOException("invalid choice " + select);
+ }
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {}
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java
new file mode 100644
index 000000000..9b4a3ae3f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java
@@ -0,0 +1,342 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+
+import org.mozilla.jss.asn1.*;
+import com.netscape.cms.servlet.wizard.*;
+
+public class ImportAdminCertPanel extends WizardPanelBase {
+
+ public ImportAdminCertPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import Administrator's Certificate");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import Administrator's Certificate");
+ setId(id);
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ public boolean isPanelDone() {
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("ImportAdminCertPanel: display");
+ context.put("errorString", "");
+ context.put("title", "Import Administrator's Certificate");
+ context.put("panel", "admin/console/config/importadmincertpanel.vm");
+ context.put("import", "true");
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ String type = "";
+ String subsystemtype = "";
+
+ try {
+ type = cs.getString("preop.ca.type", "");
+ subsystemtype = cs.getString("cs.type", "");
+ } catch (Exception e) {}
+
+ try {
+ String serialno = cs.getString("preop.admincert.serialno.0");
+
+ context.put("serialNumber", serialno);
+ } catch (Exception e) {
+ context.put("errorString", "Failed to get serial number.");
+ }
+
+ context.put("caType", type);
+
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+
+ if (ca == null) {
+ context.put("ca", "false");
+ } else {
+ context.put("ca", "true");
+ }
+
+ String caHost = "";
+ String caPort = "";
+ String info = "";
+
+ if (ca == null) {
+ if (type.equals("otherca")) {
+ try {
+ // this is a non-CA system that has elected to have its certificates
+ // signed by a CA outside of the security domain.
+ // in this case, we submitted the cert request for the admin cert to
+ // to security domain host.
+ caHost = cs.getString("securitydomain.host", "");
+ caPort = cs.getString("securitydomain.httpsadminport", "");
+ } catch (Exception e) {}
+ } else if (type.equals("sdca")) {
+ try {
+ // this is a non-CA system that submitted its certs to a CA
+ // within the security domain. In this case, we submitted the cert
+ // request for the admin cert to this CA
+ caHost = cs.getString("preop.ca.hostname", "");
+ caPort = cs.getString("preop.ca.httpsadminport", "");
+ } catch (Exception e) {}
+ }
+ } else {
+ // for CAs, we always generate our own admin certs
+ // send our own connection details
+ try {
+ caHost = cs.getString("service.machineName", "");
+ caPort = cs.getString("pkicreate.admin_secure_port", "");
+ } catch (Exception e) {}
+ }
+
+ String pkcs7 = "";
+ try {
+ pkcs7 = cs.getString("preop.admincert.pkcs7", "");
+ } catch (Exception e) {
+ }
+
+ context.put("pkcs7", pkcs7);
+ context.put("caHost", caHost);
+ context.put("caPort", caPort);
+ context.put("info", info);
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String type = "";
+ String subsystemtype = "";
+ String security_domain_type = "";
+ String selected_hierarchy = "";
+
+ try {
+ type = cs.getString("preop.ca.type", "");
+ subsystemtype = cs.getString("cs.type", "");
+ security_domain_type = cs.getString("securitydomain.select", "");
+ selected_hierarchy = cs.getString("preop.hierarchy.select", "");
+ } catch (Exception e) {}
+
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(
+ ICertificateAuthority.ID);
+
+ if (ca == null) {
+ context.put("ca", "false");
+ } else {
+ context.put("ca", "true");
+ }
+ context.put("caType", type);
+
+ X509CertImpl certs[] = new X509CertImpl[1];
+
+ // REMINDER: This panel is NOT used by "clones"
+ if( ca != null ) {
+ String serialno = null;
+
+ if( selected_hierarchy.equals( "root" ) ) {
+ CMS.debug( "ImportAdminCertPanel update: "
+ + "Root CA subsystem - "
+ + "(new Security Domain)" );
+ } else {
+ CMS.debug( "ImportAdminCertPanel update: "
+ + "Subordinate CA subsystem - "
+ + "(new Security Domain)" );
+ }
+
+ try {
+ serialno = cs.getString("preop.admincert.serialno.0");
+ } catch (Exception e) {
+ CMS.debug(
+ "ImportAdminCertPanel update: Failed to get request id.");
+ context.put("updateStatus", "failure");
+ throw new IOException("Failed to get request id.");
+ }
+
+ ICertificateRepository repost = ca.getCertificateRepository();
+
+ try {
+ certs[0] = repost.getX509Certificate(
+ new BigInteger(serialno, 16));
+ } catch (Exception ee) {}
+ } else {
+ String dir = null;
+
+ // REMINDER: This panel is NOT used by "clones"
+ if( subsystemtype.equals( "CA" ) ) {
+ if( selected_hierarchy.equals( "root" ) ) {
+ CMS.debug( "ImportAdminCertPanel update: "
+ + "Root CA subsystem - "
+ + "(existing Security Domain)" );
+ } else {
+ CMS.debug( "ImportAdminCertPanel update: "
+ + "Subordinate CA subsystem - "
+ + "(existing Security Domain)" );
+ }
+ } else {
+ CMS.debug( "ImportAdminCertPanel update: "
+ + subsystemtype
+ + " subsystem" );
+ }
+
+ try {
+ dir = cs.getString("preop.admincert.b64", "");
+ CMS.debug("ImportAdminCertPanel update: dir=" + dir);
+ } catch (Exception ee) {}
+
+ try {
+ BufferedReader reader = new BufferedReader(
+ new FileReader(dir));
+ String b64 = "";
+
+ StringBuffer sb = new StringBuffer();
+ while (reader.ready()) {
+ sb.append(reader.readLine());
+ }
+ b64 = sb.toString();
+ reader.close();
+
+ b64 = b64.trim();
+ b64 = CryptoUtil.stripCertBrackets(b64);
+ CMS.debug("ImportAdminCertPanel update: b64=" + b64);
+ byte[] b = CryptoUtil.base64Decode(b64);
+ certs[0] = new X509CertImpl(b);
+ } catch (Exception e) {
+ CMS.debug("ImportAdminCertPanel update: " + e.toString());
+ }
+ }
+
+ try {
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(IUGSubsystem.ID);
+ String uid = cs.getString("preop.admin.uid");
+ IUser user = ug.getUser(uid);
+ user.setX509Certificates(certs);
+ ug.addUserCert(user);
+ } catch (LDAPException e) {
+ CMS.debug("ImportAdminCertPanel update: failed to add certificate to the internal database. Exception: "+e.toString());
+ if (e.getLDAPResultCode() != LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
+ context.put("updateStatus", "failure");
+ throw new IOException(e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug(
+ "ImportAdminCertPanel update: failed to add certificate. Exception: "
+ + e.toString());
+ context.put("updateStatus", "failure");
+ throw new IOException(e.toString());
+ }
+
+ context.put("errorString", "");
+ context.put("info", "");
+ context.put("title", "Import Administrator Certificate");
+ context.put("panel", "admin/console/config/importadmincertpanel.vm");
+ context.put("updateStatus", "success");
+ }
+
+ public boolean shouldSkip() {
+ try {
+ IConfigStore c = CMS.getConfigStore();
+ String s = c.getString("preop.subsystem.select",null);
+ if (s != null && s.equals("clone")) {
+ return true;
+ }
+ } catch (EBaseException e) {
+ }
+
+ return false;
+ }
+
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ /* This should never be called */
+ context.put("title", "Import Administrator Certificate");
+ context.put("panel", "admin/console/config/importadmincertpanel.vm");
+ context.put("info", "");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java
new file mode 100755
index 000000000..8a730d519
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java
@@ -0,0 +1,161 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+
+import org.mozilla.jss.asn1.*;
+import com.netscape.cms.servlet.wizard.*;
+
+public class ImportCAChainPanel extends WizardPanelBase {
+
+ public ImportCAChainPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import CA's Certificate Chain");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import CA's Certificate Chain");
+ setId(id);
+ }
+
+ public boolean isSubPanel() {
+ return false;
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ public boolean isPanelDone() {
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("ImportCACertChain: display");
+ context.put("errorString", "");
+ context.put("title", "Import CA's Certificate Chain");
+ context.put("panel", "admin/console/config/importcachainpanel.vm");
+ context.put("import", "true");
+
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ context.put("machineName", cs.getString("machineName"));
+ context.put("https_port", cs.getString("pkicreate.ee_secure_port"));
+ context.put("http_port", cs.getString("pkicreate.unsecure_port"));
+ } catch (EBaseException e) {
+ CMS.debug("ImportCACertChain:display: Exception: " + e.toString());
+ context.put("errorString", "Error loading values for Import CA Certificate Panel");
+ }
+
+ ISubsystem ca = (ISubsystem) CMS.getSubsystem("ca");
+
+ if (ca == null) {
+ context.put("ca", "false");
+ } else {
+ context.put("ca", "true");
+ }
+
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+
+
+ context.put("errorString", "");
+ context.put("title", "Import CA's Certificate Chain");
+ context.put("panel", "admin/console/config/importcachainpanel.vm");
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ /* This should never be called */
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ context.put("machineName", cs.getString("machineName"));
+ context.put("https_port", cs.getString("pkicreate.ee_secure_port"));
+ context.put("http_port", cs.getString("pkicreate.unsecure_port"));
+ context.put("title", "Import CA's Certificate Chain");
+ context.put("panel", "admin/console/config/importcachainpanel.vm");
+ } catch (EBaseException e) {}
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java
new file mode 100644
index 000000000..1d884856f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java
@@ -0,0 +1,195 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.PrivateKey.Type;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.pkcs12.*;
+import org.mozilla.jss.pkcs11.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import java.security.interfaces.*;
+
+/**
+ * This servlet imports DRM's transport certificate into TKS.
+ */
+public class ImportTransportCert extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public ImportTransportCert() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("ImportTransportCert: initializing...");
+ super.init(sc);
+ CMS.debug("ImportTransportCert: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateUpdater: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(cmsReq);
+ CMS.debug("ImportTransportCert authentication successful.");
+ } catch (Exception e) {
+ CMS.debug("ImportTransportCert: authentication failed.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ if (authToken == null) {
+ CMS.debug("ImportTransportCert: authentication failed.");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ CMS.debug("ImportTransportCert authorization successful.");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ String name = httpReq.getParameter("name");
+ String certsString = httpReq.getParameter("certificate");
+
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ CMS.debug("ImportTransportCert: Importing certificate");
+ org.mozilla.jss.crypto.X509Certificate cert =
+ cm.importCACertPackage(CMS.AtoB(certsString));
+ String nickName = cert.getNickname();
+ CMS.debug("ImportTransportCert: nickname " + nickName);
+ cs.putString("tks.drm_transport_cert_nickname", nickName);
+ CMS.debug("ImportTransportCert: Commiting configuration");
+ cs.commit(false);
+
+ // send success status back to the requestor
+ CMS.debug("ImportTransportCert: Sending response");
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("ImportTransportCert: Failed to send the XML output " + e);
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java
new file mode 100644
index 000000000..65b98a4ae
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java
@@ -0,0 +1,333 @@
+// --- 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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import netscape.ldap.*;
+import com.netscape.cmsutil.password.*;
+
+/**
+ * This object stores the values for IP, uid and group based on the cookie id in LDAP.
+ * Entries are stored under ou=Security Domain, ou=sessions, $basedn
+ */
+public class LDAPSecurityDomainSessionTable
+ implements ISecurityDomainSessionTable {
+
+ private long m_timeToLive;
+
+ public LDAPSecurityDomainSessionTable(long timeToLive) {
+ m_timeToLive = timeToLive;
+ }
+
+ public void addEntry(String sessionId, String ip,
+ String uid, String group) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ boolean sessions_exists = true;
+
+ String basedn = null;
+ String sessionsdn = null;
+ try {
+ basedn = cs.getString("internaldb.basedn");
+ sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: addEntry: failed to read basedn" + e);
+ return;
+ }
+
+ try {
+ // create session entry (if it does not exist)
+ conn = getLDAPConn();
+
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "organizationalUnit"));
+ attrs.add(new LDAPAttribute("ou", "sessions"));
+ entry = new LDAPEntry(sessionsdn, attrs);
+ conn.add(entry);
+ } catch (Exception e) {
+ if ((e instanceof LDAPException) && (((LDAPException) e).getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS)) {
+ // continue
+ } else {
+ CMS.debug("SecurityDomainSessionTable: unable to create ou=sessions:" + e);
+ sessions_exists = false;
+ }
+ }
+
+ // add new entry
+ try {
+ LDAPEntry entry = null;
+ LDAPAttributeSet attrs = null;
+ String entrydn = "cn=" + sessionId + "," + sessionsdn;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "securityDomainSessionEntry"));
+ attrs.add(new LDAPAttribute("cn", sessionId));
+ attrs.add(new LDAPAttribute("host", ip));
+ attrs.add(new LDAPAttribute("uid", uid));
+ attrs.add(new LDAPAttribute("cmsUserGroup", group));
+ attrs.add(new LDAPAttribute("dateOfCreate", Long.toString((new Date()).getTime())));
+
+ entry = new LDAPEntry(entrydn, attrs);
+ if (sessions_exists) {
+ conn.add(entry);
+ }
+ CMS.debug("SecurityDomainSessionTable: added session entry" + sessionId);
+ } catch(Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to create session entry" + sessionId + ": " + e);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable:addEntry: Error in disconnecting from database: " + e);
+ }
+ }
+
+ public void removeEntry(String sessionId) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String dn = "cn=" + sessionId + ",ou=sessions,ou=Security Domain," + basedn;
+ conn = getLDAPConn();
+ conn.delete(dn);
+ } catch (Exception e) {
+ if ((e instanceof LDAPException) && (((LDAPException) e).getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT)) {
+ // continue
+ } else {
+ CMS.debug("SecurityDomainSessionTable: unable to delete session " + sessionId + ": " + e);
+ }
+ }
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: removeEntry: Error in disconnecting from database: " + e);
+ }
+ }
+
+ public boolean isSessionIdExist(String sessionId) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ boolean ret = false;
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ String filter = "(cn=" + sessionId + ")";
+ String[] attrs = { "cn" };
+
+ conn = getLDAPConn();
+ LDAPSearchResults res = conn.search(sessionsdn, LDAPv2.SCOPE_SUB, filter, attrs, false);
+ if (res.getCount() > 0) ret = true;
+ } catch(Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to query session " + sessionId + ": " + e);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: isSessionIdExist: Error in disconnecting from database: " + e);
+ }
+ return ret;
+ }
+
+
+ public Enumeration getSessionIds() {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ Vector ret = new Vector();
+
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ String filter = "(objectclass=securityDomainSessionEntry)";
+ String[] attrs = { "cn" };
+
+ conn = getLDAPConn();
+ LDAPSearchResults res = conn.search(sessionsdn, LDAPv2.SCOPE_SUB, filter, attrs, false);
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = res.next();
+ ret.add(entry.getAttribute("cn").getStringValueArray()[0]);
+ }
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ CMS.debug("SecurityDomainSessionTable: getSessionIds(): no sessions have been created");
+ break;
+ default:
+ CMS.debug("SecurityDomainSessionTable: unable to query sessionIds due to ldap exception: " + e);
+ }
+ } catch(Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to query sessionIds: " + e);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: getSessionIds: Error in disconnecting from database: " + e);
+ }
+
+ return ret.elements();
+ }
+
+ private String getStringValue(String sessionId, String attr) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ String ret = null;
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ String filter = "(cn=" + sessionId + ")";
+ String[] attrs = { attr };
+ conn = getLDAPConn();
+ LDAPSearchResults res = conn.search(sessionsdn, LDAPv2.SCOPE_SUB, filter, attrs, false);
+ if (res.getCount() > 0) {
+ LDAPEntry entry = res.next();
+ ret = entry.getAttribute(attr).getStringValueArray()[0];
+ }
+ } catch(Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to query session " + sessionId + ": " + e);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: isSessionIdExist: Error in disconnecting from database: " + e);
+ }
+ return ret;
+ }
+
+ public String getIP(String sessionId) {
+ return getStringValue(sessionId, "host");
+ }
+
+ public String getUID(String sessionId) {
+ return getStringValue(sessionId, "uid");
+ }
+
+ public String getGroup(String sessionId) {
+ return getStringValue(sessionId, "cmsUserGroup");
+ }
+
+ public long getBeginTime(String sessionId) {
+ String beginStr = getStringValue(sessionId, "dateOfCreate");
+ if (beginStr != null) {
+ return Long.parseLong(beginStr);
+ }
+ return -1;
+ }
+
+ public long getTimeToLive() {
+ return m_timeToLive;
+ }
+
+ public int getSize() {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ int ret =0;
+
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ String filter = "(objectclass=securityDomainSessionEntry)";
+ String[] attrs = { "cn" };
+
+ conn = getLDAPConn();
+ LDAPSearchResults res = conn.search(sessionsdn, LDAPv2.SCOPE_SUB, filter, attrs, false);
+ ret = res.getCount();
+ } catch(Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to query sessionIds: " + e);
+ }
+
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: getSessionIds: Error in disconnecting from database: " + e);
+ }
+
+ return ret;
+ }
+
+ private LDAPConnection getLDAPConn()
+ throws IOException
+ {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String host = "";
+ String port = "";
+ String pwd = null;
+ String binddn = "";
+ String security = "";
+
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+
+ if (pwdStore != null) {
+ //CMS.debug("SecurityDomainSessionTable: getLDAPConn: password store available");
+ pwd = pwdStore.getPassword("internaldb");
+ }
+
+ if ( pwd == null) {
+ throw new IOException("SecurityDomainSessionTable: Failed to obtain password from password store");
+ }
+
+ try {
+ host = cs.getString("internaldb.ldapconn.host");
+ port = cs.getString("internaldb.ldapconn.port");
+ binddn = cs.getString("internaldb.ldapauth.bindDN");
+ security = cs.getString("internaldb.ldapconn.secureConn");
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: getLDAPConn" + e.toString());
+ throw new IOException(
+ "Failed to retrieve LDAP information from CS.cfg.");
+ }
+
+ int p = -1;
+
+ try {
+ p = Integer.parseInt(port);
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable getLDAPConn: " + e.toString());
+ throw new IOException("Port is not valid");
+ }
+
+ LDAPConnection conn = null;
+ if (security.equals("true")) {
+ //CMS.debug("SecurityDomainSessionTable getLDAPConn: creating secure (SSL) connection for internal ldap");
+ conn = new LDAPConnection(CMS.getLdapJssSSLSocketFactory());
+ } else {
+ //CMS.debug("SecurityDomainSessionTable getLDAPConn: creating non-secure (non-SSL) connection for internal ldap");
+ conn = new LDAPConnection();
+ }
+
+ //CMS.debug("SecurityDomainSessionTable connecting to " + host + ":" + p);
+ try {
+ conn.connect(host, p, binddn, pwd);
+ } catch (LDAPException e) {
+ CMS.debug("SecurityDomainSessionTable getLDAPConn: " + e.toString());
+ throw new IOException("Failed to connect to the internal database.");
+ }
+
+ return conn;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java
new file mode 100644
index 000000000..ca3879adb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java
@@ -0,0 +1,70 @@
+// --- 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.servlet.csadmin;
+
+
+import java.util.*;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.CMS;
+
+
+public class LoginServlet extends BaseServlet {
+
+ public boolean authenticate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ return true;
+ }
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ Template template = null;
+
+ try {
+ String pin = request.getParameter("pin");
+
+ if (pin == null) {
+ context.put("error", "");
+ } else {
+ String cspin = CMS.getConfigStore().getString("preop.pin");
+
+ if (cspin != null && cspin.equals(pin)) {
+ // create session
+ request.getSession(true).setAttribute("pin", cspin);
+ // pin match, redirect to the welcome page
+ response.sendRedirect("wizard");
+ return null;
+ } else {
+ context.put("error", "Login Failed");
+ }
+ }
+ template = Velocity.getTemplate("admin/console/config/login.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java
new file mode 100644
index 000000000..ff8d08b85
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java
@@ -0,0 +1,155 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.ILogger;
+
+public class MainPageServlet extends CMSServlet {
+ private static final String PROP_AUTHORITY_ID="authorityId";
+ private String mAuthorityId = null;
+ private String mFormPath = null;
+
+ public MainPageServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mTemplates.remove(CMSRequest.ERROR);
+ }
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ CMS.debug("MainPageServlet process");
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ form = getTemplate(mFormPath, request, locale);
+ } catch (IOException e) {
+ CMS.debug("MainPageServlet process: cant locate the form");
+/*
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+*/
+ }
+
+ process(argSet, header, ctx, request, response);
+
+ EBaseException error = null;
+ try {
+ ServletOutputStream out = response.getOutputStream();
+
+ if (error == null) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ response.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ IArgBlock ctx, HttpServletRequest req, HttpServletResponse resp)
+ throws EBaseException {
+
+ int num = 0;
+ IArgBlock rarg = null;
+ IConfigStore cs = CMS.getConfigStore();
+ int state = 0;
+ String host = "";
+ String adminInterface = "";
+ String eeInterface = "";
+ String agentInterface = "";
+ try {
+ state = cs.getInteger("cs.state", 0);
+ host = cs.getString("machineName", "");
+ adminInterface = cs.getString("admin.interface.uri", "");
+ eeInterface = cs.getString("ee.interface.uri", "");
+ agentInterface = cs.getString("agent.interface.uri", "");
+ } catch (Exception e) {
+ }
+
+ if (state == 0) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue("type", "admin");
+ rarg.addStringValue("prefix", "http");
+ rarg.addIntegerValue("port",
+ Integer.valueOf(CMS.getEENonSSLPort()).intValue());
+ rarg.addStringValue("host", host);
+ rarg.addStringValue("uri", adminInterface);
+ argSet.addRepeatRecord(rarg);
+ num++;
+ } else if (state == 1) {
+ if (!eeInterface.equals("")) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue("type", "ee");
+ rarg.addStringValue("prefix", "https");
+ rarg.addIntegerValue("port",
+ Integer.valueOf(CMS.getEESSLPort()).intValue());
+ rarg.addStringValue("host", host);
+ rarg.addStringValue("uri", eeInterface);
+ argSet.addRepeatRecord(rarg);
+ num++;
+ }
+ if (!agentInterface.equals("")) {
+ rarg = CMS.createArgBlock();
+ rarg.addStringValue("type", "agent");
+ rarg.addStringValue("prefix", "https");
+ rarg.addIntegerValue("port",
+ Integer.valueOf(CMS.getAgentPort()).intValue());
+ rarg.addStringValue("host", host);
+ rarg.addStringValue("uri", agentInterface);
+ argSet.addRepeatRecord(rarg);
+ num++;
+ }
+ }
+ header.addIntegerValue("totalRecordCount", num);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java
new file mode 100644
index 000000000..e5852cf59
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java
@@ -0,0 +1,330 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import com.netscape.certsrv.apps.CMS;
+
+import com.netscape.cmsutil.crypto.*;
+import java.util.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class ModulePanel extends WizardPanelBase {
+ private CryptoManager mCryptoManager = null;
+ private Vector mSupportedModules = null;
+ private Vector mOtherModules = null;
+ private Hashtable mCurrModTable = new Hashtable();
+ private WizardServlet mServlet = null;
+ public ModulePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Key Store");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Key Store");
+ setId(id);
+ mServlet = servlet;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putBoolean("preop.ModulePanel.done",false);
+ }
+
+ public void loadCurrModTable() {
+ try {
+ // getting existing modules
+ mCryptoManager = CryptoManager.getInstance();
+ Enumeration modules = mCryptoManager.getModules();
+
+ while (modules.hasMoreElements()) {
+ PK11Module mod = (PK11Module) modules.nextElement();
+
+ CMS.debug("ModulePanel: got module " + mod.getName());
+ mCurrModTable.put(mod.getName(), mod);
+ } // while
+ } catch (Exception e) {
+ CMS.debug(
+ "ModulePanel: Exception caught in loadCurrModTable: "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ }
+
+ /*
+ * Modules not listed as supported modules
+ */
+ public void loadOtherModules() {
+ Enumeration m = mCurrModTable.elements();
+
+ mOtherModules = new Vector();
+ while (m.hasMoreElements()) {
+ PK11Module mod = (PK11Module) m.nextElement();
+ Enumeration s = mSupportedModules.elements();
+ boolean found = false;
+
+ while (s.hasMoreElements()) {
+ Module sm = (Module) s.nextElement();
+
+ if (mod.getName().equals(sm.getCommonName())) {
+ found = true;
+ break;
+ } else {
+ found = false;
+ }
+ }// while
+ if (!found) {
+ // unsupported, use common name as user friendly name
+ Module module = new Module(mod.getName(), mod.getName());
+
+ loadModTokens(module, mod);
+ module.setFound(true);
+ mOtherModules.addElement((Object) module);
+ break;
+ }
+ }// while
+ }
+
+ /*
+ * find all tokens belonging to a module and load the Module
+ */
+ public void loadModTokens(Module module, PK11Module mod) {
+ Enumeration tokens = mod.getTokens();
+
+ while (tokens.hasMoreElements()) {
+ try {
+ CryptoToken token = (CryptoToken) tokens.nextElement();
+
+ CMS.debug("ModulePanel: token nick name=" + token.getName());
+ CMS.debug("ModulePanel: token logged in?" + token.isLoggedIn());
+ CMS.debug("ModulePanel: token is present?" + token.isPresent());
+ if (!token.getName().equals("Internal Crypto Services Token") &&
+ !token.getName().equals("NSS Generic Crypto Services")) {
+ module.addToken(token);
+ } else {
+ CMS.debug(
+ "ModulePanel: token " + token.getName()
+ + " not to be added");
+ }
+
+ } catch (TokenException ex) {
+ CMS.debug("ModulePanel:" + ex.toString());
+ }
+ }
+ }
+
+ /*
+ * Modules unsupported by the system will not be included
+ */
+ public void loadSupportedModules() {
+
+ // getting supported security modules
+ // a Vectgor of Modules
+ mSupportedModules = new Vector();
+ // read from conf store all supported modules
+ try {
+ int count = CMS.getConfigStore().getInteger(
+ "preop.configModules.count");
+
+ CMS.debug("ModulePanel: supported modules count= " + count);
+ for (int i = 0; i < count; i++) {
+ String cn = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".commonName");
+ String pn = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".userFriendlyName");
+ String img = CMS.getConfigStore().getString(
+ "preop.configModules.module" + i + ".imagePath");
+
+ if ((cn == null) || (cn.equals(""))) {
+ break;
+ }
+
+ CMS.debug("ModulePanel: got from config module: " + cn);
+ // create a Module object
+ Module module = new Module(cn, pn, img);
+
+ if (mCurrModTable.containsKey(cn)) {
+ CMS.debug("ModulePanel: module found: " + cn);
+ module.setFound(true);
+ // add token info to module vector
+ PK11Module m = (PK11Module) mCurrModTable.get(cn);
+
+ loadModTokens(module, m);
+ }
+
+ CMS.debug("ModulePanel: adding module " + cn);
+ // add module to set
+ if (!mSupportedModules.contains(module)) {
+ mSupportedModules.addElement((Object) module);
+ }
+ }// for
+
+ } catch (Exception e) {
+ CMS.debug(
+ "ModulePanel: Exception caught in loadSupportedModules(): "
+ + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+ }
+
+ public PropertySet getUsage() {
+ // it a token choice. Available tokens are discovered dynamically so
+ // can't be a real CHOICE
+ PropertySet set = new PropertySet();
+
+ Descriptor tokenDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* default parameter */
+ "module token selection");
+
+ set.add("choice", tokenDesc);
+
+ return set;
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.ModulePanel.done",
+ false);
+
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ public boolean hasSubPanel() {
+ return true;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("ModulePanel: display()");
+ context.put("title", "Key Store");
+
+ loadCurrModTable();
+ loadSupportedModules();
+ loadOtherModules();
+
+ IConfigStore config = CMS.getConfigStore();
+
+ try {
+ String s = config.getString("preop.module.token",
+ "Internal Key Storage Token");
+
+ context.put("defTok", s);
+ } catch (Exception e) {
+ CMS.debug("ModulePanel:" + e.toString());
+ }
+
+ context.put("status", "display");
+ context.put("oms", mOtherModules);
+ context.put("sms", mSupportedModules);
+ // context.put("status_token", "None");
+ String subpanelno = String.valueOf(getPanelNo()+1);
+ CMS.debug("ModulePanel subpanelno =" +subpanelno);
+ context.put("subpanelno", subpanelno);
+ context.put("panel", "admin/console/config/modulepanel.vm");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ boolean hasErr = false;
+
+ try {
+ // get the value of the choice
+ String select = HttpInput.getID(request, "choice");
+
+ if (select == null) {
+ CMS.debug("ModulePanel: no choice selected");
+ hasErr = true;
+ throw new IOException("choice not found");
+ }
+
+ IConfigStore config = CMS.getConfigStore();
+ String oldtokenname = config.getString("preop.module.token", "");
+ if (!oldtokenname.equals(select))
+ mServlet.cleanUpFromPanel(mServlet.getPanelNo(request));
+
+ if (hasErr == false) {
+ config.putString("preop.module.token", select);
+ config.putBoolean("preop.ModulePanel.done", true);
+ }
+ config.commit(false);
+ context.put("updateStatus", "success");
+ } catch (Exception e) {
+ CMS.debug("ModulePanel: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ context.put("updateStatus", "failure");
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Security Module");
+ context.put("panel", "admin/console/config/modulepanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java
new file mode 100644
index 000000000..9230ef5b7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java
@@ -0,0 +1,86 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.CMS;
+
+
+public class ModuleServlet extends BaseServlet {
+
+ /**
+ * Collect information on where keys are to be generated.
+ * Once collected, write to CS.cfg:
+ * "preop.module=soft"
+ * or
+ * "preop.module=hard"
+ *
+ * <ul>
+ * <li>http.param selection "soft" or "hard" for software token or hardware token
+ * </ul>
+ */
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ CMS.debug("ModuleServlet: in ModuleServlet");
+ try {
+
+ // get the value of the selection
+ String selection = request.getParameter("selection");
+
+ if (selection != null) {
+
+ if (selection.equals("soft")) {
+ CMS.debug("ModuleServlet: user selected software");
+ // XXX
+ CMS.getConfigStore().putString("preop.module", "soft");
+ CMS.getConfigStore().commit(false);
+ response.sendRedirect("size");
+ } else if (selection.equals("hard")) {
+ CMS.debug("ModuleServlet: user selected hardware");
+ // YYY
+ CMS.getConfigStore().putString("preop.module", "hard");
+ CMS.getConfigStore().commit(false);
+ response.sendRedirect("size");
+ } else {
+ CMS.debug("ModuleServlet: illegal selection: " + selection);
+ context.put("error", "failed selection");
+ }
+
+ } else {
+ CMS.debug("ModuleServlet: no selection");
+ }
+
+ template = Velocity.getTemplate("admin/console/config/module.vm");
+ } catch (Exception e) {
+ CMS.debug("ModuleServlet: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java
new file mode 100644
index 000000000..9e0b3c863
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java
@@ -0,0 +1,986 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import java.net.*;
+import java.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+
+import netscape.security.x509.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class NamePanel extends WizardPanelBase {
+ private Vector mCerts = null;
+ private WizardServlet mServlet = null;
+
+ public NamePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Subject Names");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Subject Names");
+ setId(id);
+ mServlet = servlet;
+ }
+
+ /**
+ * Returns the usage.XXX usage needs to be made dynamic
+ */
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ Descriptor caDN = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "CA Signing Certificate's DN");
+
+ set.add("caDN", caDN);
+
+ Descriptor sslDN = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "SSL Server Certificate's DN");
+
+ set.add("sslDN", sslDN);
+
+ Descriptor subsystemDN = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "CA Subsystem Certificate's DN");
+
+ set.add("subsystemDN", subsystemDN);
+
+ Descriptor ocspDN = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "OCSP Signing Certificate's DN");
+
+ set.add("ocspDN", ocspDN);
+
+ return set;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean done = cs.getBoolean("preop.NamePanel.done");
+ cs.putBoolean("preop.NamePanel.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+
+ String list = "";
+ try {
+ list = cs.getString("preop.cert.list", "");
+ } catch (Exception e) {
+ }
+
+ StringTokenizer st = new StringTokenizer(list, ",");
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ cs.remove("preop.cert."+t+".done");
+ }
+
+ try {
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.NamePanel.done", false);
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ public String capitalize(String s) {
+ if (s.length() == 0) {
+ return s;
+ } else {
+ return s.substring(0, 1).toUpperCase() + s.substring(1);
+ }
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("NamePanel: display()");
+ context.put("title", "Subject Names");
+
+ // update session id
+ String session_id = request.getParameter("session_id");
+ if (session_id != null) {
+ CMS.debug("NamePanel setting session id.");
+ CMS.setConfigSDSessionId(session_id);
+ }
+
+ mCerts = new Vector();
+
+ String domainname = "";
+ IConfigStore config = CMS.getConfigStore();
+ String select = "";
+ String hselect = "";
+ String cstype = "";
+ try {
+ //if CA, at the hierarchy panel, was it root or subord?
+ hselect = config.getString("preop.hierarchy.select", "");
+ select = config.getString("preop.subsystem.select", "");
+ cstype = config.getString("cs.type", "");
+ context.put("select", select);
+ if (cstype.equals("CA") && hselect.equals("root")) {
+ CMS.debug("NamePanel ca is root");
+ context.put("isRoot", "true");
+ } else {
+ CMS.debug("NamePanel not ca or not root");
+ context.put("isRoot", "false");
+ }
+ } catch (Exception e) {
+ }
+
+ try {
+ domainname = config.getString("securitydomain.name", "");
+
+ String certTags = config.getString("preop.cert.list");
+ // same token for now
+ String token = config.getString(PRE_CONF_CA_TOKEN);
+ StringTokenizer st = new StringTokenizer(certTags, ",");
+ String domaintype = config.getString("securitydomain.select");
+ int count = 0;
+ String host = "";
+ int sd_admin_port = -1;
+ if (domaintype.equals("existing")) {
+ host = config.getString("securitydomain.host", "");
+ sd_admin_port = config.getInteger("securitydomain.httpsadminport", -1);
+ count = getSubsystemCount(host, sd_admin_port, true, cstype);
+ }
+
+ while (st.hasMoreTokens()) {
+ String certTag = st.nextToken();
+
+ CMS.debug("NamePanel: display() about to process certTag :" + certTag);
+ String nn = config.getString(
+ PCERT_PREFIX + certTag + ".nickname");
+ Cert c = new Cert(token, nn, certTag);
+ String userfriendlyname = config.getString(
+ PCERT_PREFIX + certTag + ".userfriendlyname");
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+
+ c.setUserFriendlyName(userfriendlyname);
+
+ String type = config.getString(PCERT_PREFIX + certTag + ".type");
+ c.setType(type);
+ boolean enable = config.getBoolean(PCERT_PREFIX+certTag+".enable", true);
+ c.setEnable(enable);
+
+ String cert = config.getString(subsystem +"."+certTag +".cert", "");
+ String certreq =
+ config.getString(subsystem + "." +certTag +".certreq", "");
+
+ String dn = config.getString(PCERT_PREFIX + certTag + ".dn");
+ boolean override = config.getBoolean(PCERT_PREFIX + certTag +
+ ".cncomponent.override", true);
+ //o_sd is to add o=secritydomainname
+ boolean o_sd = config.getBoolean(PCERT_PREFIX + certTag +
+ "o_securitydomain", true);
+ domainname = config.getString("securitydomain.name", "");
+ CMS.debug("NamePanel: display() override is "+override);
+ CMS.debug("NamePanel: display() o_securitydomain is "+o_sd);
+ CMS.debug("NamePanel: display() domainname is "+domainname);
+
+ boolean dnUpdated = false;
+ try {
+ dnUpdated = config.getBoolean(PCERT_PREFIX+certTag+".updatedDN");
+ } catch (Exception e) {
+ }
+
+ try {
+ boolean done = config.getBoolean("preop.NamePanel.done");
+ c.setDN(dn);
+ } catch (Exception e) {
+ String instanceId = config.getString("service.instanceID", "");
+ if (select.equals("clone") || dnUpdated) {
+ c.setDN(dn);
+ } else if (count != 0 && override && (cert.equals("") || certreq.equals(""))) {
+ CMS.debug("NamePanel subsystemCount = "+count);
+ c.setDN(dn + " "+count+
+ ((!instanceId.equals(""))? (",OU=" + instanceId):"") +
+ ((o_sd)? (",O=" + domainname):""));
+ config.putBoolean(PCERT_PREFIX+certTag+".updatedDN", true);
+ } else {
+ c.setDN(dn +
+ ((!instanceId.equals(""))? (",OU=" + instanceId):"") +
+ ((o_sd)? (",O=" + domainname):""));
+ config.putBoolean(PCERT_PREFIX+certTag+".updatedDN", true);
+ }
+ }
+
+ mCerts.addElement(c);
+ CMS.debug(
+ "NamePanel: display() added cert to mCerts: certTag "
+ + certTag);
+ config.putString(PCERT_PREFIX + c.getCertTag() + ".dn", c.getDN());
+ }// while
+ } catch (EBaseException e) {
+ CMS.debug("NamePanel: display() exception caught:" + e.toString());
+ } catch (Exception e) {
+ CMS.debug("NamePanel: " + e.toString());
+ }
+
+ CMS.debug("NamePanel: Ready to get SSL EE HTTPS urls");
+ Vector v = getUrlListFromSecurityDomain(config, "CA", "SecurePort");
+ v.addElement("External CA");
+ StringBuffer list = new StringBuffer();
+ int size = v.size();
+
+ for (int i = 0; i < size; i++) {
+ if (i == size - 1) {
+ list.append(v.elementAt(i));
+ } else {
+ list.append(v.elementAt(i));
+ list.append(",");
+ }
+ }
+
+ try {
+ config.putString("preop.ca.list", list.toString());
+ config.commit(false);
+ } catch (Exception e) {}
+
+ context.put("urls", v);
+
+ context.put("certs", mCerts);
+ context.put("panel", "admin/console/config/namepanel.vm");
+ context.put("errorString", "");
+
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ Enumeration c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ // get the dn's and put in config
+ if (cert.isEnable()) {
+ String dn = HttpInput.getDN(request, cert.getCertTag());
+
+ if (dn == null || dn.length() == 0) {
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Empty DN for " + cert.getUserFriendlyName());
+ }
+ }
+ } // while
+ }
+
+ /*
+ * update some parameters for clones
+ */
+ public void updateCloneConfig(IConfigStore config)
+ throws EBaseException, IOException {
+ String cstype = config.getString("cs.type", null);
+ cstype = toLowerCaseSubsystemType(cstype);
+ if (cstype.equals("kra")) {
+ String token = config.getString(PRE_CONF_CA_TOKEN);
+ if (!token.equals("Internal Key Storage Token")) {
+ CMS.debug("NamePanel: updating configuration for KRA clone with hardware token");
+ String subsystem = config.getString(PCERT_PREFIX + "storage.subsystem");
+ String storageNickname = getNickname(config, "storage");
+ String transportNickname = getNickname(config, "transport");
+
+ config.putString(subsystem + ".storageUnit.hardware", token);
+ config.putString(subsystem + ".storageUnit.nickName", token+":"+storageNickname);
+ config.putString(subsystem + ".transportUnit.nickName", token+":"+transportNickname);
+ config.commit(false);
+ } else { // software token
+ // parameters already set
+ }
+ }
+
+ // audit signing cert
+ String audit_nn = config.getString(cstype + ".audit_signing" + ".nickname", "");
+ String audit_tk = config.getString(cstype + ".audit_signing" + ".tokenname", "");
+ if (!audit_tk.equals("Internal Key Storage Token") && !audit_tk.equals("")) {
+ config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+ audit_tk + ":" + audit_nn);
+ } else {
+ config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+ audit_nn);
+ }
+ }
+
+ /*
+ * get some of the "preop" parameters to persisting parameters
+ */
+ public void updateConfig(IConfigStore config, String certTag)
+ throws EBaseException, IOException {
+ String token = config.getString(PRE_CONF_CA_TOKEN);
+ String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem");
+ CMS.debug("NamePanel: subsystem " + subsystem);
+ String nickname = getNickname(config, certTag);
+
+ CMS.debug("NamePanel: updateConfig() for certTag " + certTag);
+ // XXX these two are used throughout the CA so have to write them
+ // should change the entire system to use the uniformed names later
+ if (certTag.equals("signing") || certTag.equals("ocsp_signing")) {
+ CMS.debug("NamePanel: setting signing nickname=" + nickname);
+ config.putString(subsystem + "." + certTag + ".cacertnickname", nickname);
+ config.putString(subsystem + "." + certTag + ".certnickname", nickname);
+ }
+
+ // if KRA, hardware token needs param "kra.storageUnit.hardware" in CS.cfg
+ String cstype = config.getString("cs.type", null);
+ cstype = toLowerCaseSubsystemType(cstype);
+ if (cstype.equals("kra")) {
+ if (!token.equals("Internal Key Storage Token")) {
+ if (certTag.equals("storage")) {
+ config.putString(subsystem + ".storageUnit.hardware", token);
+ config.putString(subsystem + ".storageUnit.nickName", token+":"+nickname);
+ } else if (certTag.equals("transport")) {
+ config.putString(subsystem + ".transportUnit.nickName", token+":"+nickname);
+ }
+ } else { // software token
+ if (certTag.equals("storage")) {
+ config.putString(subsystem + ".storageUnit.nickName", nickname);
+ } else if (certTag.equals("transport")) {
+ config.putString(subsystem + ".transportUnit.nickName", nickname);
+ }
+ }
+ }
+
+ String serverCertNickname = nickname;
+ String path = CMS.getConfigStore().getString("instanceRoot", "");
+ if (certTag.equals("sslserver")) {
+ if (!token.equals("Internal Key Storage Token")) {
+ serverCertNickname = token+":"+nickname;
+ }
+ File file = new File(path+"/conf/serverCertNick.conf");
+ PrintStream ps = new PrintStream(new FileOutputStream(path+"/conf/serverCertNick.conf"));
+ ps.println(serverCertNickname);
+ ps.close();
+ }
+
+ config.putString(subsystem + "." + certTag + ".nickname", nickname);
+ config.putString(subsystem + "." + certTag + ".tokenname", token);
+ if (certTag.equals("audit_signing")) {
+ if (!token.equals("Internal Key Storage Token") && !token.equals("")) {
+ config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+ token + ":" + nickname);
+ } else {
+ config.putString("log.instance.SignedAudit.signedAuditCertNickname",
+ nickname);
+ }
+ }
+ /*
+ config.putString(CERT_PREFIX + certTag + ".defaultSigningAlgorithm",
+ "SHA1withRSA");
+ */
+
+ // for system certs verification
+ if (!token.equals("Internal Key Storage Token") && !token.equals("")) {
+ config.putString(subsystem + ".cert." + certTag + ".nickname",
+ token + ":" + nickname);
+ } else {
+ config.putString(subsystem + ".cert." + certTag + ".nickname", nickname);
+ }
+
+ config.commit(false);
+ CMS.debug("NamePanel: updateConfig() done");
+ }
+
+ /**
+ * create and sign a cert locally (handles both "selfsign" and "local")
+ */
+ public void configCert(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context, Cert certObj) throws IOException {
+ CMS.debug("NamePanel: configCert called");
+
+ IConfigStore config = CMS.getConfigStore();
+ String caType = certObj.getType();
+ CMS.debug("NamePanel: in configCert caType is "+ caType);
+ X509CertImpl cert = null;
+ String certTag = certObj.getCertTag();
+
+ try {
+ updateConfig(config, certTag);
+ if (caType.equals("remote")) {
+ String v = config.getString("preop.ca.type", "");
+
+ CMS.debug("NamePanel configCert: remote CA");
+ String pkcs10 = CertUtil.getPKCS10(config, PCERT_PREFIX,
+ certObj, context);
+ certObj.setRequest(pkcs10);
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+ config.putString(subsystem + "." + certTag + ".certreq", pkcs10);
+ String profileId = config.getString(PCERT_PREFIX+certTag+".profile");
+ String session_id = CMS.getConfigSDSessionId();
+ String sd_hostname = "";
+ int sd_ee_port = -1;
+ try {
+ sd_hostname = config.getString("securitydomain.host", "");
+ sd_ee_port = config.getInteger("securitydomain.httpseeport", -1);
+ } catch (Exception ee) {
+ CMS.debug("NamePanel: configCert() exception caught:"+ee.toString());
+ }
+ String sysType = config.getString("cs.type", "");
+ String machineName = config.getString("machineName", "");
+ String securePort = config.getString("service.securePort", "");
+ if (certTag.equals("subsystem")) {
+ String content = "requestor_name=" + sysType + "-" + machineName + "-" + securePort + "&profileId="+profileId+"&cert_request_type=pkcs10&cert_request="+URLEncoder.encode(pkcs10, "UTF-8")+"&xmlOutput=true&sessionID="+session_id;
+ cert = CertUtil.createRemoteCert(sd_hostname, sd_ee_port,
+ content, response, this);
+ if (cert == null) {
+ throw new IOException("Error: remote certificate is null");
+ }
+ } else if (v.equals("sdca")) {
+ String ca_hostname = "";
+ int ca_port = -1;
+ try {
+ ca_hostname = config.getString("preop.ca.hostname", "");
+ ca_port = config.getInteger("preop.ca.httpsport", -1);
+ } catch (Exception ee) {
+ }
+
+ String content = "requestor_name=" + sysType + "-" + machineName + "-" + securePort + "&profileId="+profileId+"&cert_request_type=pkcs10&cert_request="+URLEncoder.encode(pkcs10, "UTF-8")+"&xmlOutput=true&sessionID="+session_id;
+ cert = CertUtil.createRemoteCert(ca_hostname, ca_port,
+ content, response, this);
+ if (cert == null) {
+ throw new IOException("Error: remote certificate is null");
+ }
+ } else if (v.equals("otherca")) {
+ config.putString(subsystem + "." + certTag + ".cert",
+ "...paste certificate here...");
+ } else {
+ CMS.debug("NamePanel: no preop.ca.type is provided");
+ }
+ } else { // not remote CA, ie, self-signed or local
+ ISubsystem ca = CMS.getSubsystem(ICertificateAuthority.ID);
+
+ if (ca == null) {
+ String s = PCERT_PREFIX + certTag + ".type";
+
+ CMS.debug(
+ "The value for " + s
+ + " should be remote, nothing else.");
+ throw new IOException(
+ "The value for " + s + " should be remote");
+ }
+
+ String pubKeyType = config.getString(
+ PCERT_PREFIX + certTag + ".keytype");
+ if (pubKeyType.equals("rsa")) {
+
+ String pubKeyModulus = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.modulus");
+ String pubKeyPublicExponent = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.exponent");
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+
+ if (certTag.equals("signing")) {
+ X509Key x509key = CryptoUtil.getPublicX509Key(
+ CryptoUtil.string2byte(pubKeyModulus),
+ CryptoUtil.string2byte(pubKeyPublicExponent));
+
+ cert = CertUtil.createLocalCert(config, x509key,
+ PCERT_PREFIX, certTag, caType, context);
+ } else {
+ String cacert = config.getString("ca.signing.cert", "");
+
+ if (cacert.equals("") || cacert.startsWith("...")) {
+ certObj.setCert(
+ "...certificate be generated internally...");
+ config.putString(subsystem + "." + certTag + ".cert",
+ "...certificate be generated internally...");
+ } else {
+ X509Key x509key = CryptoUtil.getPublicX509Key(
+ CryptoUtil.string2byte(pubKeyModulus),
+ CryptoUtil.string2byte(pubKeyPublicExponent));
+
+ cert = CertUtil.createLocalCert(config, x509key,
+ PCERT_PREFIX, certTag, caType, context);
+ }
+ }
+ } else if (pubKeyType.equals("ecc")) {
+ String pubKeyEncoded = config.getString(
+ PCERT_PREFIX + certTag + ".pubkey.encoded");
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+
+ if (certTag.equals("signing")) {
+
+ X509Key x509key = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded));
+ cert = CertUtil.createLocalCert(config, x509key,
+ PCERT_PREFIX, certTag, caType, context);
+ } else {
+ String cacert = config.getString("ca.signing.cert", "");
+
+ if (cacert.equals("") || cacert.startsWith("...")) {
+ certObj.setCert(
+ "...certificate be generated internally...");
+ config.putString(subsystem + "." + certTag + ".cert",
+ "...certificate be generated internally...");
+ } else {
+ X509Key x509key = CryptoUtil.getPublicX509ECCKey(
+ CryptoUtil.string2byte(pubKeyEncoded));
+
+ cert = CertUtil.createLocalCert(config, x509key,
+ PCERT_PREFIX, certTag, caType, context);
+ }
+ }
+ } else {
+ // invalid key type
+ CMS.debug("Invalid key type " + pubKeyType);
+ }
+ if (cert != null) {
+ if (certTag.equals("subsystem"))
+ CertUtil.addUserCertificate(cert);
+ }
+ } // done self-signed or local
+
+ if (cert != null) {
+ byte[] certb = cert.getEncoded();
+ String certs = CryptoUtil.base64Encode(certb);
+
+ // certObj.setCert(certs);
+ String subsystem = config.getString(
+ PCERT_PREFIX + certTag + ".subsystem");
+ config.putString(subsystem + "." + certTag + ".cert", certs);
+ }
+ config.commit(false);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("NamePanel configCert() exception caught:" + e.toString());
+ }
+ }
+
+ public void configCertWithTag(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context, String tag) throws IOException
+ {
+ CMS.debug("NamePanel: configCertWithTag start");
+ Enumeration c = mCerts.elements();
+ IConfigStore config = CMS.getConfigStore();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String ct = cert.getCertTag();
+ CMS.debug("NamePanel: configCertWithTag ct=" + ct +
+ " tag=" +tag);
+ if (ct.equals(tag)) {
+ try {
+ String nickname = HttpInput.getNickname(request, ct + "_nick");
+ if (nickname != null) {
+ CMS.debug("configCertWithTag: Setting nickname for " + ct + " to " + nickname);
+ config.putString(PCERT_PREFIX + ct + ".nickname", nickname);
+ cert.setNickname(nickname);
+ config.commit(false);
+ }
+ String dn = HttpInput.getDN(request, ct);
+ if (dn != null) {
+ config.putString(PCERT_PREFIX + ct + ".dn", dn);
+ config.commit(false);
+ }
+ } catch (Exception e) {
+ CMS.debug("NamePanel: configCertWithTag: Exception in setting nickname for " + ct + ": " + e.toString());
+ }
+
+ configCert(request, response, context, cert);
+ CMS.debug("NamePanel: configCertWithTag done with tag=" + tag);
+ return;
+ }
+ }
+ CMS.debug("NamePanel: configCertWithTag done");
+ }
+
+ private boolean inputChanged(HttpServletRequest request)
+ throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+
+ boolean hasChanged = false;
+ try {
+ Enumeration c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String ct = cert.getCertTag();
+ boolean enable = config.getBoolean(PCERT_PREFIX+ct+".enable", true);
+ if (!enable)
+ continue;
+
+ String olddn = config.getString(PCERT_PREFIX + cert.getCertTag() + ".dn", "");
+ // get the dn's and put in config
+ String dn = HttpInput.getDN(request, cert.getCertTag());
+
+ if (!olddn.equals(dn))
+ hasChanged = true;
+
+ String oldnick = config.getString(PCERT_PREFIX + ct + ".nickname");
+ String nick = HttpInput.getNickname(request, ct + "_nick");
+ if (!oldnick.equals(nick))
+ hasChanged = true;
+
+ }
+ } catch (Exception e) {
+ }
+
+ return hasChanged;
+ }
+
+ public String getURL(HttpServletRequest request, IConfigStore config)
+ {
+ String index = request.getParameter("urls");
+ if (index == null){
+ return null;
+ }
+ String url = "";
+ if (index.startsWith("http")) {
+ // user may submit url directlry
+ url = index;
+ } else {
+ try {
+ int x = Integer.parseInt(index);
+ String list = config.getString("preop.ca.list", "");
+ StringTokenizer tokenizer = new StringTokenizer(list, ",");
+ int counter = 0;
+
+ while (tokenizer.hasMoreTokens()) {
+ url = tokenizer.nextToken();
+ if (counter == x) {
+ break;
+ }
+ counter++;
+ }
+ } catch (Exception e) {}
+ }
+ return url;
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ CMS.debug("NamePanel: in update()");
+ boolean hasErr = false;
+
+ if (inputChanged(request)) {
+ mServlet.cleanUpFromPanel(mServlet.getPanelNo(request));
+ } else if (isPanelDone()) {
+ context.put("updateStatus", "success");
+ return;
+ }
+
+ IConfigStore config = CMS.getConfigStore();
+
+ String hselect = "";
+ ISubsystem subsystem = CMS.getSubsystem(ICertificateAuthority.ID);
+ try {
+ //if CA, at the hierarchy panel, was it root or subord?
+ hselect = config.getString("preop.hierarchy.select", "");
+ String cstype = config.getString("preop.subsystem.select", "");
+ if (cstype.equals("clone")) {
+ CMS.debug("NamePanel: clone configuration detected");
+ // still need to handle SSL certificate
+ configCertWithTag(request, response, context, "sslserver");
+ String url = getURL(request, config);
+ if (url != null && !url.equals("External CA")) {
+ // preop.ca.url and admin port are required for setting KRA connector
+ url = url.substring(url.indexOf("https"));
+ config.putString("preop.ca.url", url);
+
+ URL urlx = new URL(url);
+ updateCloneSDCAInfo(request, context, urlx.getHost(),
+ Integer.toString(urlx.getPort()));
+
+ }
+ updateCloneConfig(config);
+ CMS.debug("NamePanel: clone configuration done");
+ context.put("updateStatus", "success");
+ return;
+ }
+ } catch (Exception e) {
+ CMS.debug("NamePanel: configCertWithTag failure - " + e);
+ context.put("updateStatus", "failure");
+ return;
+ }
+
+ //if no hselect, then not CA
+ if (hselect.equals("") || hselect.equals("join")) {
+ String select = null;
+ String url = getURL(request, config);
+
+ URL urlx = null;
+
+ if (url.equals("External CA")) {
+ CMS.debug("NamePanel: external CA selected");
+ select = "otherca";
+ config.putString("preop.ca.type", "otherca");
+ if (subsystem != null) {
+ config.putString(PCERT_PREFIX+"signing.type", "remote");
+ }
+
+ config.putString("preop.ca.pkcs7", "");
+ config.putInteger("preop.ca.certchain.size", 0);
+ context.put("check_otherca", "checked");
+ CMS.debug("NamePanel: update: this is the external CA.");
+ } else {
+ CMS.debug("NamePanel: local CA selected");
+ select = "sdca";
+ // parse URL (CA1 - https://...)
+ url = url.substring(url.indexOf("https"));
+ config.putString("preop.ca.url", url);
+
+ urlx = new URL(url);
+ config.putString("preop.ca.type", "sdca");
+ CMS.debug("NamePanel: update: this is a CA in the security domain.");
+ context.put("check_sdca", "checked");
+ sdca(request, context, urlx.getHost(),
+ Integer.toString(urlx.getPort()));
+ if (subsystem != null) {
+ config.putString(PCERT_PREFIX + "signing.type", "remote");
+ config.putString(PCERT_PREFIX + "signing.profile",
+ "caInstallCACert");
+ }
+ }
+
+ try {
+ config.commit(false);
+ } catch (Exception e) {}
+
+ }
+
+ try {
+
+ Enumeration c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String ct = cert.getCertTag();
+ String tokenname = cert.getTokenname();
+ boolean enable = config.getBoolean(PCERT_PREFIX+ct+".enable", true);
+ if (!enable)
+ continue;
+
+ boolean certDone = config.getBoolean(PCERT_PREFIX+ct+".done", false);
+ if (certDone)
+ continue;
+
+ // get the nicknames and put in config
+ String nickname = HttpInput.getNickname(request, ct + "_nick");
+ if (nickname != null) {
+ CMS.debug("NamePanel: update: Setting nickname for " + ct + " to " + nickname);
+ config.putString(PCERT_PREFIX + ct + ".nickname", nickname);
+ cert.setNickname(nickname);
+ } else {
+ nickname = cert.getNickname();
+ }
+
+ // get the dn's and put in config
+ String dn = HttpInput.getDN(request, ct);
+
+ config.putString(PCERT_PREFIX + ct + ".dn", dn);
+ // commit here in case it changes
+ config.commit(false);
+
+ try {
+ configCert(request, response, context, cert);
+ config.putBoolean("preop.cert."+cert.getCertTag()+".done",
+ true);
+ config.commit(false);
+ } catch (Exception e) {
+ CMS.debug(
+ "NamePanel: update() exception caught:"
+ + e.toString());
+ hasErr = true;
+ System.err.println("Exception caught: " + e.toString());
+ }
+
+ } // while
+ if (hasErr == false) {
+ config.putBoolean("preop.NamePanel.done", true);
+ config.commit(false);
+ }
+
+ } catch (Exception e) {
+ CMS.debug("NamePanel: Exception caught: " + e.toString());
+ System.err.println("Exception caught: " + e.toString());
+ }// try
+
+
+ try {
+ config.commit(false);
+ } catch (Exception e) {}
+
+ if (!hasErr) {
+ context.put("updateStatus", "success");
+ } else {
+ context.put("updateStatus", "failure");
+ }
+ CMS.debug("NamePanel: update() done");
+ }
+
+ private void updateCloneSDCAInfo(HttpServletRequest request, Context context, String hostname, String httpsPortStr) throws IOException {
+ CMS.debug("NamePanel updateCloneSDCAInfo: selected CA hostname=" + hostname + " port=" + httpsPortStr);
+ String https_admin_port = "";
+ IConfigStore config = CMS.getConfigStore();
+
+ if (hostname == null || hostname.length() == 0) {
+ context.put("errorString", "Hostname is null");
+ throw new IOException("Hostname is null");
+ }
+
+ // Retrieve the associated HTTPS Admin port so that it
+ // may be stored for use with ImportAdminCertPanel
+ https_admin_port = getSecurityDomainAdminPort( config,
+ hostname,
+ httpsPortStr,
+ "CA" );
+
+ int httpsport = -1;
+
+ try {
+ httpsport = Integer.parseInt(httpsPortStr);
+ } catch (Exception e) {
+ CMS.debug(
+ "NamePanel update: Https port is not valid. Exception: "
+ + e.toString());
+ throw new IOException("Https Port is not valid.");
+ }
+
+ config.putString("preop.ca.hostname", hostname);
+ config.putString("preop.ca.httpsport", httpsPortStr);
+ config.putString("preop.ca.httpsadminport", https_admin_port);
+ }
+
+ private void sdca(HttpServletRequest request, Context context, String hostname, String httpsPortStr) throws IOException {
+ CMS.debug("NamePanel update: this is the CA in the security domain.");
+ CMS.debug("NamePanel update: selected CA hostname=" + hostname + " port=" + httpsPortStr);
+ String https_admin_port = "";
+ IConfigStore config = CMS.getConfigStore();
+
+ context.put("sdcaHostname", hostname);
+ context.put("sdHttpPort", httpsPortStr);
+
+ if (hostname == null || hostname.length() == 0) {
+ context.put("errorString", "Hostname is null");
+ throw new IOException("Hostname is null");
+ }
+
+ // Retrieve the associated HTTPS Admin port so that it
+ // may be stored for use with ImportAdminCertPanel
+ https_admin_port = getSecurityDomainAdminPort( config,
+ hostname,
+ httpsPortStr,
+ "CA" );
+
+ int httpsport = -1;
+
+ try {
+ httpsport = Integer.parseInt(httpsPortStr);
+ } catch (Exception e) {
+ CMS.debug(
+ "NamePanel update: Https port is not valid. Exception: "
+ + e.toString());
+ throw new IOException("Https Port is not valid.");
+ }
+
+ config.putString("preop.ca.hostname", hostname);
+ config.putString("preop.ca.httpsport", httpsPortStr);
+ config.putString("preop.ca.httpsadminport", https_admin_port);
+ ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback();
+ updateCertChainUsingSecureEEPort( config, "ca", hostname,
+ httpsport, true, context,
+ certApprovalCallback );
+ try {
+ CMS.debug("Importing CA chain");
+ importCertChain("ca");
+ } catch (Exception e1) {
+ CMS.debug("Failed in importing CA chain");
+ }
+ }
+
+
+ public void initParams(HttpServletRequest request, Context context)
+ throws IOException
+ {
+ context.put("certs", mCerts);
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ try {
+ initParams(request, context);
+ } catch (IOException e) {
+ }
+ context.put("title", "Subject Names");
+ context.put("panel", "admin/console/config/namepanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java
new file mode 100644
index 000000000..2bc5f94fc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java
@@ -0,0 +1,255 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.*;
+
+/**
+ * This servlet creates a TPS user in the CA,
+ * and it associates TPS's server certificate to
+ * the user. Finally, it addes the user to the
+ * administrator group. This procedure will
+ * allows TPS to connect to the CA for certificate
+ * issuance.
+ */
+public class RegisterUser extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+ private String mGroupName = null;
+
+ public RegisterUser() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("RegisterUser: initializing...");
+ super.init(sc);
+ CMS.debug("RegisterUser: done initializing...");
+ mGroupName = sc.getInitParameter("GroupName");
+ CMS.debug("RegisterUser: group name " + mGroupName);
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateUpdater: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(cmsReq);
+ CMS.debug("RegisterUser authentication successful.");
+ } catch (Exception e) {
+ CMS.debug("RegisterUser: authentication failed.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ if (authToken == null) {
+ CMS.debug("RegisterUser: authentication failed.");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ CMS.debug("RegisterUser authorization successful.");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ // create user and add certificate
+ String uid = httpReq.getParameter("uid");
+ String name = httpReq.getParameter("name");
+ String certsString = httpReq.getParameter("certificate");
+ CMS.debug("RegisterUser got uid=" + uid);
+ CMS.debug("RegisterUser got name=" + name);
+ CMS.debug("RegisterUser got certsString=" + certsString);
+
+ IUGSubsystem ugsys = (IUGSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ IUser user = null;
+ boolean foundByCert = false;
+ X509Certificate certs[] = new X509Certificate[1];
+ try {
+
+ byte bCert[] = null;
+ X509CertImpl cert = null;
+ bCert = (byte[]) (com.netscape.osutil.OSUtil.AtoB(certsString));
+ cert = new X509CertImpl(bCert);
+ certs[0] = (X509Certificate)cert;
+
+ // test to see if the cert already belongs to a user
+ ICertUserLocator cul = ugsys.getCertUserLocator();
+ com.netscape.certsrv.usrgrp.Certificates c =
+ new com.netscape.certsrv.usrgrp.Certificates(certs);
+ user = (IUser) cul.locateUser(c);
+ } catch (Exception ec) {
+ CMS.debug("RegisterUser: exception thrown: "+ec.toString());
+ }
+ if (user == null) {
+ CMS.debug("RegisterUser NOT found user by cert");
+ try {
+ user = ugsys.getUser(uid);
+ CMS.debug("RegisterUser found user by uid "+uid);
+ } catch (Exception eee) {
+ }
+ } else {
+ foundByCert = true;
+ CMS.debug("RegisterUser found user by cert");
+ }
+
+ try {
+
+ if (user == null) {
+ // create user only if such user does not exist
+ user = ugsys.createUser(uid);
+ user.setFullName(name);
+ user.setState("1");
+ user.setUserType("");
+ user.setEmail("");
+ user.setPhone("");
+ user.setPassword("");
+ ugsys.addUser(user);
+ CMS.debug("RegisterUser created user " + uid);
+ }
+
+ user.setX509Certificates(certs);
+ if (!foundByCert) {
+ ugsys.addUserCert(user);
+ CMS.debug("RegisterUser added user certificate");
+ } else
+ CMS.debug("RegisterUser no need to add user certificate");
+ } catch (Exception eee) {
+ CMS.debug("RegisterUser error " + eee.toString());
+ outputError(httpResp, "Error: Certificate malformed");
+ return;
+ }
+
+
+ // add user to the group
+ Enumeration groups = ugsys.findGroups(mGroupName);
+ IGroup group = (IGroup)groups.nextElement();
+ group.addMemberName(user.getUserID());
+ ugsys.modifyGroup(group);
+ CMS.debug("RegisterUser modified group");
+
+ // send success status back to the requestor
+ try {
+ CMS.debug("RegisterUser: Sending response");
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("RegisterUser: Failed to send the XML output");
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
new file mode 100644
index 000000000..d9ee171d9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
@@ -0,0 +1,693 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.security.*;
+import java.math.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.pkcs12.*;
+import org.mozilla.jss.pkcs11.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.crypto.PrivateKey.Type;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import com.netscape.cms.servlet.wizard.*;
+import netscape.ldap.*;
+import java.security.interfaces.*;
+
+public class RestoreKeyCertPanel extends WizardPanelBase {
+
+ public RestoreKeyCertPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import Keys and Certificates");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Import Keys and Certificates");
+ setId(id);
+ }
+
+ /**
+ * Should we skip this panel for the configuration.
+ */
+ public boolean shouldSkip() {
+ CMS.debug("RestoreKeyCertPanel: should skip");
+
+ IConfigStore cs = CMS.getConfigStore();
+ // if we are root, no need to get the certificate chain.
+
+ try {
+ String select = cs.getString("preop.subsystem.select","");
+ if (select.equals("clone")) {
+ return false;
+ }
+ } catch (EBaseException e) {
+ }
+
+ return true;
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ /* clean up if necessary */
+ try {
+ boolean done = cs.getBoolean("preop.restorekeycert.done");
+ cs.putBoolean("preop.restorekeycert.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.restorekeycert.done", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Import Keys and Certificates");
+ IConfigStore config = CMS.getConfigStore();
+
+ if (isPanelDone()) {
+
+ try {
+ String s = config.getString("preop.pk12.path", "");
+ String type = config.getString("preop.subsystem.select", "");
+ context.put("path", s);
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("path", "");
+ }
+
+ context.put("password", "");
+ context.put("panel", "admin/console/config/restorekeycertpanel.vm");
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String tokenname = "";
+ try {
+ tokenname = config.getString("preop.module.token", "");
+ } catch (Exception e) {
+ }
+
+ if (!tokenname.equals("Internal Key Storage Token"))
+ return;
+
+ // Path can be empty. If this case, we just want to
+ // get to the next panel. Customer has HSM.
+ String s = HttpInput.getString(request, "path");
+ // if (s == null || s.equals("")) {
+ // CMS.debug("RestoreKeyCertPanel validate: path is empty");
+ // throw new IOException("Path is empty");
+ // }
+
+
+ if (s != null && !s.equals("")) {
+ s = HttpInput.getPassword(request, "__password");
+ if (s == null || s.equals("")) {
+ CMS.debug("RestoreKeyCertPanel validate: password is empty");
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Empty password");
+ }
+ }
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException
+ {
+ IConfigStore config = CMS.getConfigStore();
+ String path = HttpInput.getString(request, "path");
+ if (path == null || path.equals("")) {
+ // skip to next panel
+ config.putBoolean("preop.restorekeycert.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+ getConfigEntriesFromMaster(request, response, context);
+ context.put("updateStatus", "success");
+ return;
+ }
+ String pwd = HttpInput.getPassword(request, "__password");
+
+ String tokenn = "";
+ String instanceRoot = "";
+
+ try {
+ tokenn = config.getString("preop.module.token");
+ instanceRoot = config.getString("instanceRoot");
+ } catch (Exception e) {
+ }
+
+ if (tokenn.equals("Internal Key Storage Token")) {
+ byte b[] = new byte[1000000];
+ FileInputStream fis = new FileInputStream(instanceRoot + "/alias/" + path);
+ while (fis.available() > 0)
+ fis.read(b);
+ fis.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(b);
+ StringBuffer reason = new StringBuffer();
+ Password password = new Password(pwd.toCharArray());
+ PFX pfx = null;
+ boolean verifypfx = false;
+ try {
+ pfx = (PFX)(new PFX.Template()).decode(bis);
+ verifypfx = pfx.verifyAuthSafes(password, reason);
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel update: Exception="+e.toString());
+ }
+
+ if (verifypfx) {
+ CMS.debug("RestoreKeyCertPanel verify the PFX.");
+ AuthenticatedSafes safes = pfx.getAuthSafes();
+ Vector pkeyinfo_collection = new Vector();
+ Vector cert_collection = new Vector();
+ for (int i=0; i<safes.getSize(); i++) {
+ try {
+ SEQUENCE scontent = safes.getSafeContentsAt(null, i);
+ for (int j=0; j<scontent.size(); j++) {
+ SafeBag bag = (SafeBag)scontent.elementAt(j);
+ OBJECT_IDENTIFIER oid = bag.getBagType();
+ if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) {
+ EncryptedPrivateKeyInfo privkeyinfo =
+ (EncryptedPrivateKeyInfo)bag.getInterpretedBagContent();
+ PasswordConverter passConverter = new PasswordConverter();
+ PrivateKeyInfo pkeyinfo = privkeyinfo.decrypt(password, new PasswordConverter());
+ Vector pkeyinfo_v = new Vector();
+ pkeyinfo_v.addElement(pkeyinfo);
+ SET bagAttrs = bag.getBagAttributes();
+ for (int k=0; k<bagAttrs.size(); k++) {
+ Attribute attrs = (Attribute)bagAttrs.elementAt(k);
+ OBJECT_IDENTIFIER aoid = attrs.getType();
+ if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
+ SET val = attrs.getValues();
+ ANY ss = (ANY)val.elementAt(0);
+ ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
+ BMPString sss = (BMPString)(new BMPString.Template()).decode(bbis);
+ String s = sss.toString();
+ pkeyinfo_v.addElement(s);
+ }
+ }
+ pkeyinfo_collection.addElement(pkeyinfo_v);
+ } else if (oid.equals(SafeBag.CERT_BAG)) {
+ CertBag cbag = (CertBag)bag.getInterpretedBagContent();
+ OCTET_STRING str = (OCTET_STRING)cbag.getInterpretedCert();
+ byte[] x509cert = str.toByteArray();
+ Vector cert_v = new Vector();
+ cert_v.addElement(x509cert);
+ SET bagAttrs = bag.getBagAttributes();
+
+ if (bagAttrs != null) {
+ for (int k=0; k<bagAttrs.size(); k++) {
+ Attribute attrs = (Attribute)bagAttrs.elementAt(k);
+ OBJECT_IDENTIFIER aoid = attrs.getType();
+ if (aoid.equals(SafeBag.FRIENDLY_NAME)) {
+ SET val = attrs.getValues();
+ ANY ss = (ANY)val.elementAt(0);
+ ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded());
+ BMPString sss = (BMPString)(new BMPString.Template()).decode(bbis);
+ String s = sss.toString();
+ cert_v.addElement(s);
+ }
+ }
+ }
+
+ cert_collection.addElement(cert_v);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel update: Exception="+e.toString());
+ }
+ }
+
+ importkeycert(pkeyinfo_collection, cert_collection);
+ } else {
+ context.put("updateStatus", "failure");
+ throw new IOException("The pkcs12 file is not correct.");
+ }
+ }
+
+ String subsystemtype = "";
+ String cstype = "";
+ try {
+ subsystemtype = config.getString("preop.subsystem.select", "");
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+ cstype = toLowerCaseSubsystemType(cstype);
+
+ if (subsystemtype.equals("clone")) {
+ CMS.debug("RestoreKeyCertPanel: this is the clone subsystem");
+ boolean cloneReady = isCertdbCloned(request, context);
+ if (!cloneReady) {
+ CMS.debug("RestoreKeyCertPanel update: clone does not have all the certificates.");
+ context.put("errorString", "Make sure you have copied the certificate database over to the clone");
+ context.put("updateStatus", "failure");
+ throw new IOException("Clone is not ready");
+ }
+ }
+
+ config.putBoolean("preop.restorekeycert.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+
+ getConfigEntriesFromMaster(request, response, context);
+ context.put("updateStatus", "success");
+ }
+
+ private void getConfigEntriesFromMaster(HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ try {
+ IConfigStore config = CMS.getConfigStore();
+ String cstype = "";
+ try {
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+ cstype = toLowerCaseSubsystemType(cstype);
+
+ String session_id = CMS.getConfigSDSessionId();
+ String sd_hostname = "";
+ int sd_port = -1;
+ String master_hostname = "";
+ int master_port = -1;
+ int master_ee_port = -1;
+ try {
+ sd_hostname = config.getString("securitydomain.host", "");
+ sd_port = config.getInteger("securitydomain.httpsadminport", -1);
+ master_hostname = config.getString("preop.master.hostname", "");
+ master_port = config.getInteger("preop.master.httpsadminport", -1);
+ master_ee_port = config.getInteger("preop.master.httpsport", -1);
+
+ String content = "";
+ if (cstype.equals("ca") || cstype.equals("kra")) {
+ content = "type=request&xmlOutput=true&sessionID="+session_id;
+ CMS.debug("http content=" + content);
+ updateNumberRange(master_hostname, master_ee_port, true, content, "request", response);
+
+ content = "type=serialNo&xmlOutput=true&sessionID="+session_id;
+ updateNumberRange(master_hostname, master_ee_port, true, content, "serialNo", response);
+
+ content = "type=replicaId&xmlOutput=true&sessionID="+session_id;
+ updateNumberRange(master_hostname, master_ee_port, true, content, "replicaId", response);
+ }
+
+ String list = "";
+ try {
+ list = config.getString("preop.cert.list", "");
+ } catch (Exception e) {
+ }
+
+ StringBuffer c1 = new StringBuffer();
+ StringBuffer s1 = new StringBuffer();
+ StringTokenizer tok = new StringTokenizer(list, ",");
+ while (tok.hasMoreTokens()) {
+ String t1 = tok.nextToken();
+ if (t1.equals("sslserver"))
+ continue;
+ c1.append(",");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".nickname,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".dn,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".keytype,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".keyalgorithm,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".privkey.id,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.exponent,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.modulus,");
+ c1.append("cloning.");
+ c1.append(t1);
+ c1.append(".pubkey.encoded");
+
+
+ if (s1.length()!=0)
+ s1.append(",");
+
+ s1.append(cstype);
+ s1.append(".");
+ s1.append(t1);
+ }
+
+ if (!cstype.equals("ca")) {
+ c1.append(",cloning.ca.hostname,cloning.ca.httpport,cloning.ca.httpsport,cloning.ca.list,cloning.ca.pkcs7,cloning.ca.type");
+ }
+
+ if (cstype.equals("ca")) {
+ /* get ca connector details */
+ if (s1.length()!=0)
+ s1.append(",");
+ s1.append("ca.connector.KRA");
+ }
+
+ content = "op=get&names=cloning.token,instanceId,internaldb.basedn,internaldb.ldapauth.password,internaldb.replication.password,internaldb.ldapconn.host,internaldb.ldapconn.port,internaldb.ldapauth.bindDN"+c1.toString()+"&substores="+s1.toString()+"&xmlOutput=true&sessionID="+session_id;
+ boolean success = updateConfigEntries(master_hostname, master_port, true,
+ "/"+cstype+"/admin/"+cstype+"/getConfigEntries", content, config, response);
+ if (!success) {
+ context.put("errorString", "Failed to get configuration entries from the master");
+ throw new IOException("Failed to get configuration entries from the master");
+ }
+ config.putString("preop.clone.configuration", "true");
+ try {
+ config.commit(false);
+ } catch (Exception ee) {
+ }
+ } catch (IOException eee) {
+ throw eee;
+ } catch (Exception eee) {
+ CMS.debug("RestoreKeyCertPanel: update exception caught:"+eee.toString());
+ }
+
+ } catch (IOException ee) {
+ throw ee;
+ } catch (Exception ee) {
+ }
+ }
+
+ private void deleteExistingCerts() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String list = cs.getString("preop.cert.list", "");
+ StringTokenizer st = new StringTokenizer(list, ",");
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ if (s.equals("sslserver"))
+ continue;
+ String name = "preop.master."+s+".nickname";
+ String nickname = cs.getString(name, "");
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate xcert = null;
+ try {
+ xcert = cm.findCertByNickname(nickname);
+ } catch (Exception ee) {
+ CMS.debug("RestoreKeyCertPanel deleteExistingCerts: Exception="+ee.toString());
+ }
+ CryptoToken ct = cm.getInternalKeyStorageToken();
+ CryptoStore store = ct.getCryptoStore();
+ try {
+ store.deleteCert(xcert);
+ } catch (Exception ee) {
+ CMS.debug("RestoreKeyCertPanel deleteExistingCerts: Exception="+ee.toString());
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel deleteExistingCerts: Exception="+e.toString());
+ }
+ }
+
+ private org.mozilla.jss.crypto.PrivateKey.Type getPrivateKeyType(PublicKey pubkey) {
+ CMS.debug("Key Algorithm '"+pubkey.getAlgorithm()+"'");
+ if (pubkey.getAlgorithm().equals("EC")) {
+ return org.mozilla.jss.crypto.PrivateKey.Type.EC;
+ }
+ return org.mozilla.jss.crypto.PrivateKey.Type.RSA;
+ }
+
+ private void importkeycert(Vector pkeyinfo_collection,
+ Vector cert_collection) throws IOException {
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ } catch (Exception e) {
+ }
+
+ // delete all existing certificates first
+ deleteExistingCerts();
+
+ for (int i=0; i<pkeyinfo_collection.size(); i++) {
+ try {
+ Vector pkeyinfo_v = (Vector)pkeyinfo_collection.elementAt(i);
+ PrivateKeyInfo pkeyinfo = (PrivateKeyInfo)pkeyinfo_v.elementAt(0);
+ String nickname = (String)pkeyinfo_v.elementAt(1);
+ byte[] x509cert = getX509Cert(nickname, cert_collection);
+ X509Certificate cert = cm.importCACertPackage(x509cert);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ pkeyinfo.encode(bos);
+ byte[] pkey = bos.toByteArray();
+
+ PublicKey publickey = cert.getPublicKey();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+ CMS.debug("RestoreKeyCertPanel deleteCert: this is pk11store");
+ try {
+ store.deleteCert(cert);
+ } catch (Exception ee) {
+ CMS.debug("RestoreKeyCertPanel importKeyCert: Exception="+ee.toString());
+ }
+
+ KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey sk = kg.generate();
+ byte iv[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
+ IVParameterSpec param = new IVParameterSpec(iv);
+ Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ c.initEncrypt(sk, param);
+ byte[] encpkey = c.doFinal(pkey);
+
+ KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initUnwrap(sk, param);
+ org.mozilla.jss.crypto.PrivateKey pp = wrapper.unwrapPrivate(encpkey, getPrivateKeyType(publickey), publickey);
+
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel importkeycert: Exception="+e.toString());
+ }
+ }
+
+ for (int i=0; i<cert_collection.size(); i++) {
+ try {
+ Vector cert_v = (Vector)cert_collection.elementAt(i);
+ byte[] cert = (byte[])cert_v.elementAt(0);
+ if (cert_v.size() > 1) {
+ String name = (String)cert_v.elementAt(1);
+ // we need to delete the trusted CA certificate if it is
+ // the same as the ca signing certificate
+ if (isCASigningCert(name)) {
+ X509Certificate certchain = getX509CertFromToken(cert);
+ if (certchain != null) {
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+ CMS.debug("RestoreKeyCertPanel deleteCert: this is pk11store");
+ if (store instanceof PK11Store) {
+ try {
+ PK11Store pk11store = (PK11Store)store;
+ pk11store.deleteCertOnly(certchain);
+ } catch (Exception ee) {
+ CMS.debug("RestoreKeyCertPanel importKeyCert: Exception="+ee.toString());
+ }
+ }
+ }
+ }
+
+ X509Certificate xcert = cm.importUserCACertPackage(cert, name);
+ if (name.startsWith("caSigningCert")) {
+ // we need to change the trust attribute to CT
+ InternalCertificate icert = (InternalCertificate)xcert;
+ icert.setSSLTrust(InternalCertificate.TRUSTED_CA
+ | InternalCertificate.TRUSTED_CLIENT_CA
+ | InternalCertificate.VALID_CA);
+ } else if (name.startsWith("auditSigningCert")) {
+ InternalCertificate icert = (InternalCertificate)xcert;
+ icert.setObjectSigningTrust(InternalCertificate.USER | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER);
+ }
+ } else
+ cm.importCACertPackage(cert);
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel importkeycert: Exception="+e.toString());
+ }
+ }
+ }
+
+ private boolean isCASigningCert(String name) {
+ String n = "preop.master.signing.nickname";
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String nickname = cs.getString(n);
+ if (nickname.equals(name))
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+
+ return false;
+ }
+
+ private X509Certificate getX509CertFromToken(byte[] cert)
+ throws IOException {
+ try {
+ X509CertImpl impl = new X509CertImpl(cert);
+ String issuer_impl = impl.getIssuerDN().toString();
+ BigInteger serial_impl = impl.getSerialNumber();
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate[] permcerts = cm.getPermCerts();
+ for (int i=0; i<permcerts.length; i++) {
+ String issuer_p = permcerts[i].getSubjectDN().toString();
+ BigInteger serial_p = permcerts[i].getSerialNumber();
+ if (issuer_p.equals(issuer_impl) && serial_p.compareTo(serial_impl) == 0) {
+ return permcerts[i];
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel getX509CertFromToken: Exception="+e.toString());
+ }
+
+ return null;
+ }
+
+ private byte[] getX509Cert(String nickname, Vector cert_collection)
+ throws IOException {
+ for (int i=0; i<cert_collection.size(); i++) {
+ Vector v = (Vector)cert_collection.elementAt(i);
+ byte[] b = (byte[])v.elementAt(0);
+ X509CertImpl impl = null;
+ try {
+ impl = new X509CertImpl(b);
+ } catch (Exception e) {
+ CMS.debug("RestoreKeyCertPanel getX509Cert: Exception="+e.toString());
+ throw new IOException( e.toString() );
+ }
+ Principal subjectdn = impl.getSubjectDN();
+ if (LDAPDN.equals(subjectdn.toString(), nickname))
+ return b;
+ }
+
+ return null;
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ context.put("title", "Import Keys and Certificates");
+ context.put("password", "");
+ context.put("path", "");
+ context.put("panel", "admin/console/config/restorekeycertpanel.vm");
+ }
+
+ private boolean isCertdbCloned(HttpServletRequest request,
+ Context context) {
+ IConfigStore config = CMS.getConfigStore();
+ String certList = "";
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ certList = config.getString("preop.cert.list");
+ StringTokenizer st = new StringTokenizer(certList, ",");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (token.equals("sslserver"))
+ continue;
+ String tokenname = config.getString("preop.module.token", "");
+ CryptoToken tok = cm.getTokenByName(tokenname);
+ CryptoStore store = tok.getCryptoStore();
+ String name1 = "preop.master."+token+".nickname";
+ String nickname = config.getString(name1, "");
+ if (!tokenname.equals("Internal Key Storage Token") &&
+ !tokenname.equals("internal"))
+ nickname = tokenname+":"+nickname;
+
+ CMS.debug("RestoreKeyCertPanel isCertdbCloned: "+nickname);
+ X509Certificate cert = cm.findCertByNickname(nickname);
+ if (cert == null)
+ return false;
+ }
+ } catch (Exception e) {
+ context.put("errorString", "Check your CS.cfg for cloning");
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java
new file mode 100644
index 000000000..f336cd84c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java
@@ -0,0 +1,159 @@
+// --- 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.servlet.csadmin;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.mozilla.jss.util.Password;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import java.io.*;
+import java.net.URL;
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.KeyPair;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs12.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.crypto.PrivateKey;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class SavePKCS12Panel extends WizardPanelBase {
+
+ public SavePKCS12Panel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Save Keys and Certificates");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Save Keys and Certificates");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ }
+
+ public boolean shouldSkip() {
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ boolean enable = cs.getBoolean("preop.backupkeys.enable", false);
+ if (!enable)
+ return true;
+ } catch (Exception e) {
+ }
+
+ return false;
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.backupkeycert.done", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ return set;
+ }
+
+ public boolean isSubPanel() {
+ return true;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Save Keys and Certificates");
+ IConfigStore config = CMS.getConfigStore();
+ String subsystemtype = "";
+ try {
+ subsystemtype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+
+ subsystemtype = toLowerCaseSubsystemType(subsystemtype);
+
+ context.put("panel", "admin/console/config/savepkcs12panel.vm");
+ context.put("subsystemtype", subsystemtype);
+ context.put("errorString", "");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ context.put("title", "Save Keys and Certificates");
+ context.put("panel", "admin/console/config/savepkcs12panel.vm");
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ context.put("title", "Save Keys and Certificates");
+ context.put("panel", "admin/console/config/savepkcs12panel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java
new file mode 100644
index 000000000..4f0a19d8b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java
@@ -0,0 +1,81 @@
+// --- 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.servlet.csadmin;
+
+
+import java.util.*;
+import java.net.*;
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+public class SecurityDomainLogin extends BaseServlet {
+
+ public boolean authenticate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ return true;
+ }
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ Template template = null;
+
+ try {
+ String url = request.getParameter("url");
+ url = URLDecoder.decode(url, "UTF-8");
+ URL u = null;
+ if (url != null) {
+ u = new URL(url);
+ }
+ int index = url.indexOf("subsystem=");
+ String subsystem = "";
+ if (index > 0) {
+ subsystem = url.substring(index+10);
+ int index1 = subsystem.indexOf("&");
+ if (index1 > 0)
+ subsystem = subsystem.substring(0, index1);
+ }
+ context.put("sd_uid", "");
+ context.put("sd_pwd", "");
+ context.put("url", url);
+ context.put("host", u.getHost());
+ context.put("sdhost", CMS.getEESSLHost());
+ if (subsystem.equals("KRA")) {
+ subsystem = "DRM";
+ }
+ context.put("subsystem", subsystem);
+ // The "securitydomain.name" property ONLY resides in the "CS.cfg"
+ // associated with the CS subsystem hosting the security domain.
+ IConfigStore cs = CMS.getConfigStore();
+ String sdname = cs.getString("securitydomain.name", "");
+ context.put("name", sdname);
+ template = Velocity.getTemplate("admin/console/config/securitydomainloginpanel.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java
new file mode 100644
index 000000000..6abdd8618
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java
@@ -0,0 +1,500 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.mozilla.jss.crypto.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmsutil.crypto.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class SecurityDomainPanel extends WizardPanelBase {
+
+ public SecurityDomainPanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Security Domain");
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Security Domain");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putString("preop.securitydomain.select", "");
+ cs.putString("securitydomain.select", "");
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String s = cs.getString("preop.securitydomain.select", "");
+ if (s == null || s.equals("")) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ context.put("title", "Security Domain");
+ IConfigStore config = CMS.getConfigStore();
+ String errorString = "";
+ String default_admin_url = "";
+ String name = "";
+ String cstype = "";
+
+ try {
+ default_admin_url = config.getString("preop.securitydomain.admin_url", "");
+ name = config.getString("preop.securitydomain.name", "");
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ if (isPanelDone()) {
+ try {
+ String s = config.getString("preop.securitydomain.select");
+
+ if (s.equals("new")) {
+ context.put("check_newdomain", "checked");
+ context.put("check_existingdomain", "");
+ } else if (s.equals("existing")) {
+ context.put("check_newdomain", "");
+ context.put("check_existingdomain", "checked");
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ } else {
+ context.put("check_newdomain", "checked");
+ context.put("check_existingdomain", "");
+ }
+
+ try {
+ context.put("cstype", config.getString("cs.type"));
+ context.put("wizardname", config.getString("preop.wizard.name"));
+ context.put("panelname", "Security Domain Configuration");
+ context.put("systemname", config.getString("preop.system.name"));
+ context.put("machineName", config.getString("machineName"));
+ context.put("http_ee_port", CMS.getEENonSSLPort());
+ context.put("https_agent_port", CMS.getAgentPort());
+ context.put("https_ee_port", CMS.getEESSLPort());
+ context.put("https_admin_port", CMS.getAdminPort());
+ context.put("sdomainAdminURL", default_admin_url);
+ } catch (EBaseException e) {}
+
+ context.put("panel", "admin/console/config/securitydomainpanel.vm");
+ context.put("errorString", errorString);
+
+ // from default_admin_url, find hostname, if fully qualified, get
+ // network domain name and generate default security domain name
+ if (name.equals("") && (default_admin_url != null)) {
+ try {
+ URL u = new URL(default_admin_url);
+
+ String hostname = u.getHost();
+ StringTokenizer st = new StringTokenizer(hostname, ".");
+ boolean first = true;
+ int numTokens = st.countTokens();
+ int count = 0;
+ String defaultDomain = "";
+ StringBuffer sb = new StringBuffer();
+ while (st.hasMoreTokens()) {
+ count++;
+ String n = st.nextToken();
+ if (first) { //skip the hostname
+ first = false;
+ continue;
+ }
+ if (count == numTokens) // skip the last element (e.g. com)
+ continue;
+ sb.append((defaultDomain.length()==0)? "":" ");
+ sb.append(capitalize(n));
+ }
+ defaultDomain = sb.toString() + " "+ "Domain";
+ name = defaultDomain;
+ CMS.debug("SecurityDomainPanel: defaultDomain generated:"+ name);
+ } catch (MalformedURLException e) {
+ errorString = "Malformed URL";
+ // not being able to come up with default domain name is ok
+ }
+ }
+ context.put("sdomainName", name);
+
+ if( default_admin_url != null ) {
+ String r = null;
+
+ try {
+ // check to see if "default" security domain exists
+ // on local machine
+ URL u = new URL( default_admin_url );
+
+ String hostname = u.getHost();
+ int port = u.getPort();
+ ConfigCertApprovalCallback
+ certApprovalCallback = new ConfigCertApprovalCallback();
+ r = pingCS( hostname, port, true, certApprovalCallback );
+ } catch (Exception e) {
+ CMS.debug( "SecurityDomainPanel: exception caught: "
+ + e.toString() );
+ }
+
+ if( r != null ) {
+ // "default" security domain exists on local machine;
+ // fill "sdomainURL" in with "default" security domain
+ // as an initial "guess"
+ CMS.debug( "SecurityDomainPanel: pingCS returns: "+r );
+ context.put( "sdomainURL", default_admin_url );
+ } else {
+ // "default" security domain does NOT exist on local machine;
+ // leave "sdomainURL" blank
+ CMS.debug( "SecurityDomainPanel: pingCS no successful response" );
+ context.put( "sdomainURL", "" );
+ }
+ }
+
+ // Information for "existing" Security Domain CAs
+ String initDaemon = "pki-cad";
+ String instanceId = "&lt;security_domain_instance_name&gt;";
+ String os = System.getProperty( "os.name" );
+ if( os.equalsIgnoreCase( "Linux" ) ) {
+ context.put( "initCommand", "/sbin/service " + initDaemon );
+ context.put( "instanceId", instanceId );
+ } else {
+ /* default case: e. g. - ( os.equalsIgnoreCase( "SunOS" ) */
+ context.put( "initCommand", "/etc/init.d/" + initDaemon );
+ context.put( "instanceId", instanceId );
+ }
+ }
+
+ public static String capitalize(String s) {
+ if (s.length() == 0) {
+ return s;
+ } else {
+ return s.substring(0,1).toUpperCase() + s.substring(1);
+ }
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+
+ String select = HttpInput.getID(request, "choice");
+ if (select.equals("newdomain")) {
+ String name = HttpInput.getSecurityDomainName(request, "sdomainName");
+ if (name == null || name.equals("")) {
+ initParams(request, context);
+ context.put("updateStatus", "validate-failure");
+ throw new IOException("Missing name value for the security domain");
+ }
+ } else if (select.equals("existingdomain")) {
+ CMS.debug( "SecurityDomainPanel: validating "
+ + "SSL Admin HTTPS . . ." );
+ String admin_url = HttpInput.getURL( request, "sdomainURL" );
+ if( admin_url == null || admin_url.equals("") ) {
+ initParams( request, context );
+ context.put("updateStatus", "validate-failure");
+ throw new IOException( "Missing SSL Admin HTTPS url value "
+ + "for the security domain" );
+ } else {
+ String r = null;
+
+ try {
+ URL u = new URL( admin_url );
+
+ String hostname = u.getHost();
+ int admin_port = u.getPort();
+ ConfigCertApprovalCallback
+ certApprovalCallback = new ConfigCertApprovalCallback();
+ r = pingCS( hostname, admin_port, true,
+ certApprovalCallback );
+ } catch( Exception e ) {
+ CMS.debug( "SecurityDomainPanel: exception caught: "
+ + e.toString() );
+ context.put("updateStatus", "validate-failure");
+ throw new IOException( "Illegal SSL Admin HTTPS url value "
+ + "for the security domain" );
+ }
+
+ if (r != null) {
+ CMS.debug("SecurityDomainPanel: pingAdminCS returns: "
+ + r );
+ context.put( "sdomainURL", admin_url );
+ } else {
+ CMS.debug( "SecurityDomainPanel: pingAdminCS "
+ + "no successful response for SSL Admin HTTPS" );
+ context.put( "sdomainURL", "" );
+ }
+ }
+ }
+ }
+
+ public void initParams(HttpServletRequest request, Context context)
+ throws IOException
+ {
+ IConfigStore config = CMS.getConfigStore();
+ try {
+ context.put("cstype", config.getString("cs.type"));
+ } catch (Exception e) {
+ }
+
+ String select = request.getParameter("choice");
+ if (select.equals("newdomain")) {
+ context.put("check_newdomain", "checked");
+ context.put("check_existingdomain", "");
+ } else if (select.equals("existingdomain")) {
+ context.put("check_newdomain", "");
+ context.put("check_existingdomain", "checked");
+ }
+
+ String name = request.getParameter("sdomainName");
+ if (name == null)
+ name = "";
+ context.put("sdomainName", name);
+
+ String admin_url = request.getParameter("sdomainURL");
+ if (admin_url == null)
+ admin_url = "";
+ context.put("sdomainURL", admin_url);
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ String errorString = "";
+ String select = HttpInput.getID(request, "choice");
+
+ if (select == null) {
+ CMS.debug("SecurityDomainPanel: choice not found");
+ context.put("updateStatus", "failure");
+ throw new IOException("choice not found");
+ }
+ IConfigStore config = CMS.getConfigStore();
+
+ if (select.equals("newdomain")) {
+ config.putString("preop.securitydomain.select", "new");
+ config.putString("securitydomain.select", "new");
+ config.putString("preop.securitydomain.name",
+ HttpInput.getDomainName(request, "sdomainName"));
+ config.putString("securitydomain.name",
+ HttpInput.getDomainName(request, "sdomainName"));
+ config.putString("securitydomain.host",
+ CMS.getEENonSSLHost());
+ config.putString("securitydomain.httpport",
+ CMS.getEENonSSLPort());
+ config.putString("securitydomain.httpsagentport",
+ CMS.getAgentPort());
+ config.putString("securitydomain.httpseeport",
+ CMS.getEESSLPort());
+ config.putString("securitydomain.httpsadminport",
+ CMS.getAdminPort());
+
+ // make sure the subsystem certificate is issued by the security
+ // domain
+ config.putString("preop.cert.subsystem.type", "local");
+ config.putString("preop.cert.subsystem.profile", "subsystemCert.profile");
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {}
+
+ String instanceRoot = "";
+ try {
+ instanceRoot = config.getString("instanceRoot", "");
+ } catch (Exception e) {
+ }
+
+ } else if (select.equals("existingdomain")) {
+ config.putString("preop.securitydomain.select", "existing");
+ config.putString("securitydomain.select", "existing");
+
+ // make sure the subsystem certificate is issued by the security
+ // domain
+ config.putString("preop.cert.subsystem.type", "remote");
+ config.putString("preop.cert.subsystem.profile", "caInternalAuthSubsystemCert");
+
+ String admin_url = HttpInput.getURL(request, "sdomainURL");
+ String hostname = "";
+ int admin_port = -1;
+
+ if( admin_url != null ) {
+ try {
+ URL admin_u = new URL( admin_url );
+
+ hostname = admin_u.getHost();
+ admin_port = admin_u.getPort();
+ } catch( MalformedURLException e ) {
+ errorString = "Malformed SSL Admin HTTPS URL";
+ context.put("updateStatus", "failure");
+ throw new IOException( errorString );
+ }
+
+ context.put( "sdomainURL", admin_url );
+ config.putString( "securitydomain.host", hostname );
+ config.putInteger( "securitydomain.httpsadminport",
+ admin_port );
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {}
+
+ ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback();
+ updateCertChain( config, "securitydomain", hostname, admin_port,
+ true, context, certApprovalCallback );
+ } else {
+ CMS.debug("SecurityDomainPanel: invalid choice " + select);
+ errorString = "Invalid choice";
+ context.put("updateStatus", "failure");
+ throw new IOException("invalid choice " + select);
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+
+ try {
+ context.put("cstype", config.getString("cs.type"));
+ context.put("wizardname", config.getString("preop.wizard.name"));
+ context.put("panelname", "Security Domain Configuration");
+ context.put("systemname", config.getString("preop.system.name"));
+ } catch (EBaseException e) {}
+
+ context.put("errorString", errorString);
+ context.put("updateStatus", "success");
+ }
+
+ /**
+ * If validate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ IConfigStore config = CMS.getConfigStore();
+ String default_admin_url = "";
+ try {
+ initParams(request, context);
+ } catch (IOException e) {
+ }
+
+ try {
+ default_admin_url = config.getString("preop.securitydomain.admin_url", "");
+ } catch (Exception e) {}
+
+ if( default_admin_url != null ) {
+ String r = null;
+
+ try {
+ // check to see if "default" security domain exists
+ // on local machine
+ URL u = new URL( default_admin_url );
+
+ String hostname = u.getHost();
+ int port = u.getPort();
+ ConfigCertApprovalCallback
+ certApprovalCallback = new ConfigCertApprovalCallback();
+ r = pingCS( hostname, port, true, certApprovalCallback );
+ } catch (Exception e) {}
+
+ if( r != null ) {
+ // "default" security domain exists on local machine;
+ // refill "sdomainURL" in with "default" security domain
+ // as an initial "guess"
+ context.put( "sdomainURL", default_admin_url );
+ } else {
+ // "default" security domain does NOT exist on local machine;
+ // leave "sdomainURL" blank
+ context.put( "sdomainURL", "" );
+ }
+ }
+
+ try {
+ context.put("machineName", config.getString("machineName"));
+ context.put("http_ee_port", CMS.getEENonSSLPort());
+ context.put("https_agent_port", CMS.getAgentPort());
+ context.put("https_ee_port", CMS.getEESSLPort());
+ context.put("https_admin_port", CMS.getAdminPort());
+ context.put("sdomainAdminURL",
+ config.getString("preop.securitydomain.admin_url"));
+ } catch (EBaseException e) {}
+
+ // Information for "existing" Security Domain CAs
+ String initDaemon = "pki-cad";
+ String instanceId = "&lt;security_domain_instance_name&gt;";
+ String os = System.getProperty( "os.name" );
+ if( os.equalsIgnoreCase( "Linux" ) ) {
+ context.put( "initCommand", "/sbin/service " + initDaemon );
+ context.put( "instanceId", instanceId );
+ } else {
+ /* default case: e. g. - ( os.equalsIgnoreCase( "SunOS" ) */
+ context.put( "initCommand", "/etc/init.d/" + initDaemon );
+ context.put( "instanceId", instanceId );
+ }
+
+ context.put("title", "Security Domain");
+ context.put("panel", "admin/console/config/securitydomainpanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java
new file mode 100644
index 000000000..dabaee410
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java
@@ -0,0 +1,100 @@
+// --- 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.servlet.csadmin;
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+
+/**
+ * This object stores the values for IP, uid and group based on the cookie id.
+ */
+public class SecurityDomainSessionTable
+ implements ISecurityDomainSessionTable {
+
+ private Hashtable m_sessions;
+ private long m_timeToLive;
+
+ public SecurityDomainSessionTable(long timeToLive) {
+ m_sessions = new Hashtable();
+ m_timeToLive = timeToLive;
+ }
+
+ public void addEntry(String sessionId, String ip,
+ String uid, String group) {
+ Vector v = new Vector();
+ v.addElement(ip);
+ v.addElement(uid);
+ v.addElement(group);
+ Date d = new Date();
+ long t = d.getTime();
+ v.addElement(Long.valueOf(t));
+ m_sessions.put(sessionId, v);
+ }
+
+ public void removeEntry(String sessionId) {
+ m_sessions.remove(sessionId);
+ }
+
+ public boolean isSessionIdExist(String sessionId) {
+ return m_sessions.containsKey(sessionId);
+ }
+
+ public Enumeration getSessionIds() {
+ return m_sessions.keys();
+ }
+
+ public String getIP(String sessionId) {
+ Vector v = (Vector)m_sessions.get(sessionId);
+ if (v != null)
+ return (String)v.elementAt(0);
+ return null;
+ }
+
+ public String getUID(String sessionId) {
+ Vector v = (Vector)m_sessions.get(sessionId);
+ if (v != null)
+ return (String)v.elementAt(1);
+ return null;
+ }
+
+ public String getGroup(String sessionId) {
+ Vector v = (Vector)m_sessions.get(sessionId);
+ if (v != null)
+ return (String)v.elementAt(2);
+ return null;
+ }
+
+ public long getBeginTime(String sessionId) {
+ Vector v = (Vector)m_sessions.get(sessionId);
+ if (v != null) {
+ Long n = (Long)v.elementAt(3);
+ if (n != null)
+ return n.longValue();
+ }
+ return -1;
+ }
+
+ public long getTimeToLive() {
+ return m_timeToLive;
+ }
+
+ public int getSize() {
+ return m_sessions.size();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java
new file mode 100644
index 000000000..91564d15e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java
@@ -0,0 +1,47 @@
+// --- 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.servlet.csadmin;
+
+import java.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+public class SessionTimer extends TimerTask {
+ private ISecurityDomainSessionTable m_sessiontable = null;
+
+ public SessionTimer(ISecurityDomainSessionTable table) {
+ super();
+ m_sessiontable = table;
+ }
+
+ public void run() {
+ Enumeration keys = m_sessiontable.getSessionIds();
+ while (keys.hasMoreElements()) {
+ String sessionId = (String)keys.nextElement();
+ long beginTime = m_sessiontable.getBeginTime(sessionId);
+ Date nowDate = new Date();
+ long nowTime = nowDate.getTime();
+ long timeToLive = m_sessiontable.getTimeToLive();
+ if ((nowTime-beginTime) > timeToLive) {
+ m_sessiontable.removeEntry(sessionId);
+ CMS.debug("SessionTimer run: successfully remove the session id entry from the table.");
+ }
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java
new file mode 100644
index 000000000..0ff27aa01
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java
@@ -0,0 +1,652 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.cmsutil.crypto.*;
+
+import java.security.interfaces.RSAPublicKey;
+import java.util.*;
+import java.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.pkcs11.PK11KeyPairGenerator;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class SizePanel extends WizardPanelBase {
+ private Vector mCerts = null;
+ private WizardServlet mServlet = null;
+
+ private String default_ecc_curve_name;
+ private String default_rsa_key_size;
+ private boolean mShowSigning = false;
+
+ public SizePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Key Pairs");
+ setId(id);
+ mServlet = servlet;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ Descriptor choiceDesc = new Descriptor(IDescriptor.CHOICE,
+ "default,custom", null, /* no default parameter */
+ "If 'default', the key size will be configured automatically. If 'custom', the key size will be set to the value of the parameter 'custom_size'.");
+
+ set.add("choice", choiceDesc);
+
+ Descriptor customSizeDesc = new Descriptor(IDescriptor.STRING, null, /* no constraint */
+ null, /* no default parameter */
+ "Custom Key Size");
+
+ set.add("custom_size", customSizeDesc);
+
+ return set;
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ /* clean up if necessary*/
+ try {
+ boolean done = cs.getBoolean("preop.SizePanel.done");
+ cs.putBoolean("preop.SizePanel.done", false);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ boolean s = cs.getBoolean("preop.SizePanel.done", false);
+ if (s != true) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (EBaseException e) {}
+
+ return false;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ CMS.debug("SizePanel: display()");
+ try {
+ initParams(request, context);
+ } catch (IOException e) {
+ }
+
+ context.put("firsttime", "false");
+ String errorString = "";
+ mCerts = new Vector();
+
+ IConfigStore config = CMS.getConfigStore();
+ try {
+ boolean done = config.getBoolean("preop.SizePanel.done");
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ try {
+ default_ecc_curve_name = config.getString("keys.ecc.curve.default", "nistp521");
+ } catch (Exception e) {
+ }
+
+ try {
+ default_rsa_key_size = config.getString("keys.rsa.keysize.default", "2048");
+ } catch (Exception e) {
+ }
+
+ try {
+ // same token for now
+ String token = config.getString(PRE_CONF_CA_TOKEN);
+ String certTags = config.getString("preop.cert.list");
+ StringTokenizer st = new StringTokenizer(certTags, ",");
+ mShowSigning = false;
+
+ while (st.hasMoreTokens()) {
+ String certTag = st.nextToken();
+ String nn = config.getString(
+ PCERT_PREFIX + certTag + ".nickname");
+ Cert c = new Cert(token, nn, certTag);
+
+ String s = config.getString(
+ PCERT_PREFIX + certTag + ".keysize.select", "default");
+
+ if (s.equals("default")) {
+ c.setKeyOption("default");
+ }
+ if (s.equals("custom")) {
+ c.setKeyOption("custom");
+ }
+
+ s = config.getString(
+ PCERT_PREFIX + certTag + ".keysize.custom_size",
+ default_rsa_key_size);
+ c.setCustomKeysize(s);
+
+ s = config.getString(
+ PCERT_PREFIX + certTag + ".curvename.custom_name",
+ default_ecc_curve_name);
+ c.setCustomCurvename(s);
+
+ boolean signingRequired = config.getBoolean(
+ PCERT_PREFIX + certTag + ".signing.required",
+ false);
+ c.setSigningRequired(signingRequired);
+ if (signingRequired) mShowSigning = true;
+
+ String userfriendlyname = config.getString(
+ PCERT_PREFIX + certTag + ".userfriendlyname");
+ c.setUserFriendlyName(userfriendlyname);
+ boolean enable = config.getBoolean(PCERT_PREFIX+certTag+".enable", true);
+ c.setEnable(enable);
+ mCerts.addElement(c);
+ }// while
+ } catch (Exception e) {
+ CMS.debug("SizePanel: display() " + e.toString());
+ }
+ CMS.debug("SizePanel: display() 1");
+
+ context.put("show_signing", mShowSigning ? "true" : "false");
+ context.put("certs", mCerts);
+ context.put("errorString", errorString);
+ context.put("default_keysize", default_rsa_key_size);
+ context.put("default_ecc_curvename", default_ecc_curve_name);
+ context.put("panel", "admin/console/config/sizepanel.vm");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException, NumberFormatException {
+ CMS.debug("SizePanel: update()");
+ boolean hasErr = false;
+ IConfigStore config = CMS.getConfigStore();
+ String select1 = "";
+ String val1 = null;
+ boolean hasChanged = false;
+ try {
+ select1 = config.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ context.put("firsttime", "false");
+ boolean done = false;
+ try {
+ done = config.getBoolean("preop.SizePanel.done");
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ if (select1.equals("clone")) {
+ // preset the sslserver dn for cloning case
+ try {
+ String val = config.getString("preop.cert.sslserver.dn", "");
+ config.putString("preop.cert.sslserver.dn", val+",o=clone");
+ } catch (Exception ee) {
+ }
+ }
+ }
+
+ String token = "";
+ try {
+ token = config.getString(PRE_CONF_CA_TOKEN, "");
+ Enumeration c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String ct = cert.getCertTag();
+ boolean enable = config.getBoolean(PCERT_PREFIX+ct+".enable", true);
+ if (!enable)
+ continue;
+
+ String keytype = HttpInput.getKeyType(request, ct + "_keytype"); // rsa or ecc
+
+ String keyalgorithm = HttpInput.getString(request, ct + "_keyalgorithm");
+ if (keyalgorithm == null) {
+ if (keytype != null && keytype.equals("ecc")) {
+ keyalgorithm = "SHA256withEC";
+ } else {
+ keyalgorithm = "SHA256withRSA";
+ }
+ }
+
+ String signingalgorithm = HttpInput.getString(request, ct + "_signingalgorithm");
+ if (signingalgorithm == null) {
+ signingalgorithm = keyalgorithm;
+ }
+
+ String select = HttpInput.getID(request, ct + "_choice");
+
+ if (select == null) {
+ CMS.debug("SizePanel: " + ct + "_choice not found");
+ throw new IOException(
+ "SizePanel: " + ct + "_choice not found");
+ }
+ CMS.debug(
+ "SizePanel: update() keysize choice selected:" + select);
+ String oldkeysize =
+ config.getString(PCERT_PREFIX+ct+".keysize.size", "");
+ String oldkeytype =
+ config.getString(PCERT_PREFIX + ct + ".keytype", "");
+ String oldkeyalgorithm =
+ config.getString(PCERT_PREFIX + ct + ".keyalgorithm", "");
+ String oldsigningalgorithm =
+ config.getString(PCERT_PREFIX + ct + ".signingalgorithm", "");
+ String oldcurvename =
+ config.getString(PCERT_PREFIX + ct + ".curvename.name", "");
+
+ if (select.equals("default")) {
+ // XXXrenaming these...keep for now just in case
+ config.putString("preop.keysize.select", "default");
+ if (keytype != null && keytype.equals("ecc")) {
+ config.putString("preop.curvename.custom_name",
+ default_ecc_curve_name);
+ config.putString("preop.curvename.name", default_ecc_curve_name);
+ } else {
+ config.putString("preop.keysize.custom_size",
+ default_rsa_key_size);
+ config.putString("preop.keysize.size", default_rsa_key_size);
+ }
+
+ config.putString(PCERT_PREFIX + ct + ".keytype", keytype);
+ config.putString(PCERT_PREFIX + ct + ".keyalgorithm", keyalgorithm);
+ config.putString(PCERT_PREFIX + ct + ".signingalgorithm", signingalgorithm);
+ config.putString(PCERT_PREFIX + ct + ".keysize.select",
+ "default");
+ if (keytype != null && keytype.equals("ecc")) {
+ config.putString(PCERT_PREFIX + ct +
+ ".curvename.custom_name",
+ default_ecc_curve_name);
+ config.putString(PCERT_PREFIX + ct + ".curvename.name",
+ default_ecc_curve_name);
+ } else {
+ config.putString(PCERT_PREFIX + ct +
+ ".keysize.custom_size",
+ default_rsa_key_size);
+ config.putString(PCERT_PREFIX + ct + ".keysize.size",
+ default_rsa_key_size);
+ }
+ } else if (select.equals("custom")) {
+ // XXXrenaming these...keep for now just in case
+ config.putString("preop.keysize.select", "custom");
+ if (keytype != null && keytype.equals("ecc")) {
+ config.putString("preop.curvename.name",
+ HttpInput.getString(request, ct + "_custom_curvename"));
+ config.putString("preop.curvename.custom_name",
+ HttpInput.getString(request, ct + "_custom_curvename"));
+ } else {
+ config.putString("preop.keysize.size",
+ HttpInput.getKeySize(request, ct + "_custom_size", keytype));
+ config.putString("preop.keysize.custom_size",
+ HttpInput.getKeySize(request, ct + "_custom_size", keytype));
+ }
+
+ config.putString(PCERT_PREFIX + ct + ".keytype", keytype);
+ config.putString(PCERT_PREFIX + ct + ".keyalgorithm", keyalgorithm);
+ config.putString(PCERT_PREFIX + ct + ".signingalgorithm", signingalgorithm);
+ config.putString(PCERT_PREFIX + ct + ".keysize.select",
+ "custom");
+
+ if (keytype != null && keytype.equals("ecc")) {
+ config.putString(PCERT_PREFIX + ct + ".curvename.custom_name",
+ HttpInput.getString(request, ct + "_custom_curvename"));
+ config.putString(PCERT_PREFIX + ct + ".curvename.name",
+ HttpInput.getString(request, ct + "_custom_curvename"));
+ } else {
+ config.putString(PCERT_PREFIX + ct + ".keysize.custom_size",
+ HttpInput.getKeySize(request, ct + "_custom_size"));
+ config.putString(PCERT_PREFIX + ct + ".keysize.size",
+ HttpInput.getKeySize(request, ct + "_custom_size"));
+ }
+ } else {
+ CMS.debug("SizePanel: invalid choice " + select);
+ throw new IOException("invalid choice " + select);
+ }
+
+ String newkeysize =
+ config.getString(PCERT_PREFIX+ct+".keysize.size", "");
+ String newkeytype =
+ config.getString(PCERT_PREFIX + ct + ".keytype", "");
+ String newkeyalgorithm =
+ config.getString(PCERT_PREFIX + ct + ".keyalgorithm", "");
+ String newsigningalgorithm =
+ config.getString(PCERT_PREFIX + ct + ".signingalgorithm", "");
+ String newcurvename =
+ config.getString(PCERT_PREFIX+ct+".curvename.name", "");
+
+ if (!oldkeysize.equals(newkeysize) ||
+ !oldkeytype.equals(newkeytype) ||
+ !oldkeyalgorithm.equals(newkeyalgorithm) ||
+ !oldsigningalgorithm.equals(newsigningalgorithm) ||
+ !oldcurvename.equals(newcurvename))
+ hasChanged = true;
+ }// while
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug("SizePanel: update() Exception caught at config commit: " + e.toString());
+ }
+
+ val1 = HttpInput.getID(request, "generateKeyPair");
+
+ if (hasChanged || (val1 != null && !val1.equals(""))) {
+ mServlet.cleanUpFromPanel(mServlet.getPanelNo(request));
+ } else if (isPanelDone()) {
+ context.put("updateStatus", "success");
+ return;
+ }
+ } catch (IOException e) {
+ CMS.debug("SizePanel: update() IOException caught: " + e.toString());
+ context.put("updateStatus", "failure");
+ throw e;
+ } catch (NumberFormatException e) {
+ CMS.debug("SizePanel: update() NumberFormatException caught: " + e.toString());
+ context.put("updateStatus", "failure");
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("SizePanel: update() Exception caught: " + e.toString());
+ }
+
+ // generate key pair
+ Enumeration c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = (Cert) c.nextElement();
+ String ct = cert.getCertTag();
+ String friendlyName = ct;
+ boolean enable = true;
+ try {
+ enable = config.getBoolean(PCERT_PREFIX+ct+".enable", true);
+ friendlyName = config.getString(PCERT_PREFIX + ct + ".userfriendlyname", ct);
+ } catch (Exception e) {
+ }
+
+ if (!enable)
+ continue;
+
+ try {
+ String keytype = config.getString(PCERT_PREFIX + ct + ".keytype");
+ String keyalgorithm = config.getString(PCERT_PREFIX + ct + ".keyalgorithm");
+
+ if (keytype.equals("rsa")) {
+ int keysize = config.getInteger(
+ PCERT_PREFIX + ct + ".keysize.size");
+
+ createRSAKeyPair(token, keysize, config, ct);
+ } else {
+ String curveName = config.getString(
+ PCERT_PREFIX + ct + ".curvename.name", default_ecc_curve_name);
+ createECCKeyPair(token, curveName, config, ct);
+ }
+ config.commit(false);
+ } catch (Exception e) {
+ CMS.debug(e);
+ CMS.debug("SizePanel: key generation failure: " + e.toString());
+ context.put("updateStatus", "failure");
+ throw new IOException("key generation failure for the certificate: " + friendlyName +
+ ". See the logs for details.");
+ }
+ } // while
+
+ if (hasErr == false) {
+ config.putBoolean("preop.SizePanel.done", true);
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug(
+ "SizePanel: update() Exception caught at config commit: "
+ + e.toString());
+ }
+ }
+ CMS.debug("SizePanel: update() done");
+ context.put("updateStatus", "success");
+
+ }
+
+ public void createECCKeyPair(String token, String curveName, IConfigStore config, String ct)
+ throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, CryptoManager.NotInitializedException
+ {
+ CMS.debug("Generating ECC key pair with curvename="+ curveName +
+ ", token="+token);
+ KeyPair pair = null;
+ /*
+ * default ssl server cert to ECDHE unless stated otherwise
+ * note: IE only supports "ECDHE", but "ECDH" is more efficient
+ *
+ * for "ECDHE", server.xml should have the following for ciphers:
+ * +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ * -TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *
+ * for "ECDH", server.xml should have the following for ciphers:
+ * -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ * +TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ */
+ String sslType = "ECDHE";
+ try {
+ sslType = config.getString(PCERT_PREFIX + ct + "ec.type", "ECDHE");
+ } catch (Exception e) {
+ CMS.debug("SizePanel: createECCKeyPair() Exception caught at config.getString for ec type");
+ }
+
+ // ECDHE needs "SIGN" but no "DERIVE"
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
+ };
+
+ // ECDH needs "DERIVE" but no any kind of "SIGN"
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage ECDH_usages_mask[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER,
+ };
+
+ do {
+ if (ct.equals("sslserver") && sslType.equalsIgnoreCase("ECDH")) {
+ CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDH. Make sure server.xml is set properly with -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+ pair = CryptoUtil.generateECCKeyPair(token, curveName,
+ null,
+ ECDH_usages_mask);
+ } else {
+ if (ct.equals("sslserver")) {
+ CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDHE. Make sure server.xml is set properly with +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+ }
+ pair = CryptoUtil.generateECCKeyPair(token, curveName,
+ null,
+ usages_mask);
+ }
+
+ // XXX - store curve , w
+ byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
+ String kid = CryptoUtil.byte2string(id);
+ config.putString(PCERT_PREFIX + ct + ".privkey.id", kid);
+
+ // try to locate the private key
+ org.mozilla.jss.crypto.PrivateKey privk =
+ CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid));
+ if (privk == null) {
+ CMS.debug("Found bad ECC key id " + kid);
+ pair = null;
+ }
+ } while (pair == null);
+
+ CMS.debug("Public key class " + pair.getPublic().getClass().getName());
+ byte encoded[] = pair.getPublic().getEncoded();
+ config.putString(PCERT_PREFIX + ct + ".pubkey.encoded",
+ CryptoUtil.byte2string(encoded));
+
+ String keyAlgo = "";
+ try {
+ keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm");
+ } catch (Exception e1) {
+ }
+
+ setSigningAlgorithm(ct, keyAlgo, config);
+ }
+
+ public void createRSAKeyPair(String token, int keysize, IConfigStore config, String ct)
+ throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, CryptoManager.NotInitializedException
+ {
+ /* generate key pair */
+ KeyPair pair = null;
+ do {
+ pair = CryptoUtil.generateRSAKeyPair(token, keysize);
+ byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
+ String kid = CryptoUtil.byte2string(id);
+ config.putString(PCERT_PREFIX + ct + ".privkey.id", kid);
+ // try to locate the private key
+ org.mozilla.jss.crypto.PrivateKey privk =
+ CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid));
+ if (privk == null) {
+ CMS.debug("Found bad RSA key id " + kid);
+ pair = null;
+ }
+ } while (pair == null);
+
+ byte modulus[] = ((RSAPublicKey) pair.getPublic()).getModulus().toByteArray();
+ byte exponent[] = ((RSAPublicKey) pair.getPublic()).getPublicExponent().toByteArray();
+
+ config.putString(PCERT_PREFIX + ct + ".pubkey.modulus",
+ CryptoUtil.byte2string(modulus));
+ config.putString(PCERT_PREFIX + ct + ".pubkey.exponent",
+ CryptoUtil.byte2string(exponent));
+
+ String keyAlgo = "";
+ try {
+ keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm");
+ } catch (Exception e1) {
+ }
+
+ setSigningAlgorithm(ct, keyAlgo, config);
+ }
+
+ public void setSigningAlgorithm(String ct, String keyAlgo, IConfigStore config) {
+ String systemType = "";
+ try {
+ systemType = config.getString("preop.system.name");
+ } catch (Exception e1) {
+ }
+ if (systemType.equalsIgnoreCase("CA")) {
+ if (ct.equals("signing")) {
+ config.putString("ca.signing.defaultSigningAlgorithm",
+ keyAlgo);
+ config.putString("ca.crl.MasterCRL.signingAlgorithm",
+ keyAlgo);
+ } else if (ct.equals("ocsp_signing")) {
+ config.putString("ca.ocsp_signing.defaultSigningAlgorithm",
+ keyAlgo);
+ }
+ } else if (systemType.equalsIgnoreCase("OCSP")) {
+ if (ct.equals("signing")) {
+ config.putString("ocsp.signing.defaultSigningAlgorithm",
+ keyAlgo);
+ }
+ } else if (systemType.equalsIgnoreCase("KRA") ||
+ systemType.equalsIgnoreCase("DRM")) {
+ if (ct.equals("transport")) {
+ config.putString("kra.transportUnit.signingAlgorithm", keyAlgo);
+ }
+ }
+ }
+
+ public void initParams(HttpServletRequest request, Context context)
+ throws IOException
+ {
+ IConfigStore config = CMS.getConfigStore();
+ String s = "";
+ try {
+ context.put("title", "Key Pairs");
+
+ s = config.getString("preop.subsystem.select", "");
+ context.put("select", s);
+
+ s = config.getString("preop.hierarchy.select", "root");
+ context.put("hselect", s);
+
+ s = config.getString("preop.ecc.algorithm.list", "SHA256withEC,SHA1withEC,SHA384withEC,SHA512withEC");
+ context.put("ecclist", s);
+
+ s = config.getString("preop.rsa.algorithm.list", "SHA256withRSA,SHA1withRSA,SHA512withRSA,MD5withRSA,MD2withRSA");
+ context.put("rsalist", s);
+
+ s = config.getString("keys.ecc.curve.list", "nistp521");
+ context.put("curvelist", s);
+
+ s = config.getString("pkicreate.subsystem_type");
+ context.put("subsystemtype", s);
+
+ } catch (Exception e) {
+ CMS.debug("SizePanel(): initParams: unable to set all initial parameters:" + e);
+ }
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ try {
+ initParams(request, context);
+ } catch (IOException e) {
+ }
+
+ context.put("certs", mCerts);
+ context.put("show_signing", mShowSigning ? "true" : "false");
+ context.put("default_keysize", default_rsa_key_size);
+ context.put("default_ecc_curvename", default_ecc_curve_name);
+
+ context.put("panel", "admin/console/config/sizepanel.vm");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java
new file mode 100644
index 000000000..ebcafe86b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java
@@ -0,0 +1,137 @@
+// --- 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.servlet.csadmin;
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.net.*;
+import org.w3c.dom.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cmsutil.xml.*;
+
+public class TokenAuthenticate extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public TokenAuthenticate() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ }
+
+ /**
+ * Process the HTTP request.
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IConfigStore config = CMS.getConfigStore();
+
+ String sessionId = httpReq.getParameter("sessionID");
+ CMS.debug("TokenAuthentication: sessionId=" + sessionId);
+ String givenHost = httpReq.getParameter("hostname");
+ CMS.debug("TokenAuthentication: givenHost=" + givenHost);
+
+ boolean checkIP = false;
+ try {
+ checkIP = config.getBoolean("securitydomain.checkIP", false);
+ } catch (Exception e) {
+ }
+
+ ISecurityDomainSessionTable table = CMS.getSecurityDomainSessionTable();
+ String uid = "";
+ String gid = "";
+ CMS.debug("TokenAuthentication: checking session in the session table");
+ if (table.isSessionIdExist(sessionId)) {
+ CMS.debug("TokenAuthentication: found session");
+ if (checkIP) {
+ String hostname = table.getIP(sessionId);
+ if (! hostname.equals(givenHost)) {
+ CMS.debug("TokenAuthentication: hostname=" + hostname + " and givenHost="
+ + givenHost + " are different");
+ CMS.debug("TokenAuthenticate authenticate failed, wrong hostname.");
+ outputError(httpResp, "Error: Failed Authentication");
+ return;
+ }
+ }
+
+ uid = table.getUID(sessionId);
+ gid = table.getGroup(sessionId);
+ } else {
+ CMS.debug("TokenAuthentication: session not found");
+ CMS.debug("TokenAuthentication authenticate failed, session id does not exist.");
+ outputError(httpResp, "Error: Failed Authentication");
+ return;
+ }
+
+ CMS.debug("TokenAuthenticate successfully authenticate");
+ try {
+ XMLObject xmlObj = null;
+
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "uid", uid);
+ xmlObj.addItemToContainer(root, "gid", gid);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
new file mode 100644
index 000000000..d5c4f017d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
@@ -0,0 +1,203 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.*;
+
+
+public class UpdateConnector extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public UpdateConnector() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("UpdateConnector: initializing...");
+ super.init(sc);
+ CMS.debug("UpdateConnector: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateConnector: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(cmsReq);
+ CMS.debug("UpdateConnector authentication successful.");
+ } catch (Exception e) {
+ CMS.debug("UpdateConnector: authentication failed.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "",
+ e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ if (authToken == null) {
+ CMS.debug("UpdateConnector: authentication failed.");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ CMS.debug("UpdateConnector authorization successful.");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ Enumeration list = httpReq.getParameterNames();
+ while (list.hasMoreElements()) {
+ String name = (String)list.nextElement();
+ String val = httpReq.getParameter(name);
+ if (name != null && name.startsWith("ca.connector")) {
+ CMS.debug("Adding connector update name=" + name + " val=" + val);
+ cs.putString(name, val);
+ } else {
+ CMS.debug("Skipping connector update name=" + name + " val=" + val);
+ }
+ }
+
+ try {
+ String nickname = cs.getString("ca.subsystem.nickname", "");
+ String tokenname = cs.getString("ca.subsystem.tokenname", "");
+ if (!tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ cs.putString("ca.connector.KRA.nickName", nickname);
+ cs.commit(false);
+ } catch (Exception e) {
+ }
+
+ // start the connector
+ try {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ ICAService caService = (ICAService)ca.getCAService();
+ IConnector kraConnector = caService.getConnector(
+ cs.getSubStore("ca.connector.KRA"));
+ caService.setKRAConnector(kraConnector);
+ kraConnector.start();
+ } catch (Exception e) {
+ CMS.debug("Failed to start connector " + e);
+ }
+
+ // send success status back to the requestor
+ try {
+ CMS.debug("UpdateConnector: Sending response");
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("UpdateConnector: Failed to send the XML output");
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java
new file mode 100644
index 000000000..b379a7899
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java
@@ -0,0 +1,486 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+public class UpdateDomainXML extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ public UpdateDomainXML() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("UpdateDomainXML: initializing...");
+ super.init(sc);
+ CMS.debug("UpdateDomainXML: done initializing...");
+ }
+
+ private String remove_from_ldap(String dn) {
+ CMS.debug("UpdateDomainXML: delete_from_ldap: starting dn: " + dn);
+ String status = SUCCESS;
+ ILdapConnFactory connFactory = null;
+ LDAPConnection conn = null;
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ IConfigStore ldapConfig = cs.getSubStore("internaldb");
+ connFactory = CMS.getLdapBoundConnFactory();
+ connFactory.init(ldapConfig);
+ conn = connFactory.getConn();
+ conn.delete(dn);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT) {
+ status = FAILED;
+ CMS.debug("Failed to delete entry" + e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug("Failed to delete entry" + e.toString());
+ } finally {
+ try {
+ if ((conn != null) && (connFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ connFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return status;
+ }
+
+ private String modify_ldap(String dn, LDAPModification mod) {
+ CMS.debug("UpdateDomainXML: modify_ldap: starting dn: " + dn);
+ String status = SUCCESS;
+ ILdapConnFactory connFactory = null;
+ LDAPConnection conn = null;
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ IConfigStore ldapConfig = cs.getSubStore("internaldb");
+ connFactory = CMS.getLdapBoundConnFactory();
+ connFactory.init(ldapConfig);
+ conn = connFactory.getConn();
+ conn.modify(dn, mod);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT) {
+ status = FAILED;
+ CMS.debug("Failed to modify entry" + e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug("Failed to modify entry" + e.toString());
+ } finally {
+ try {
+ if ((conn != null) && (connFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ connFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return status;
+ }
+
+
+ private String add_to_ldap(LDAPEntry entry, String dn) {
+ CMS.debug("UpdateDomainXML: add_to_ldap: starting");
+ String status = SUCCESS;
+ ILdapConnFactory connFactory = null;
+ LDAPConnection conn = null;
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ IConfigStore ldapConfig = cs.getSubStore("internaldb");
+ connFactory = CMS.getLdapBoundConnFactory();
+ connFactory.init(ldapConfig);
+ conn = connFactory.getConn();
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
+ CMS.debug("UpdateDomainXML: Entry already exists");
+ try {
+ conn.delete(dn);
+ conn.add(entry);
+ } catch (LDAPException ee) {
+ CMS.debug("UpdateDomainXML: Error when replacing existing entry "+ee.toString());
+ status = FAILED;
+ }
+ } else {
+ CMS.debug("UpdateDomainXML: Failed to update ldap domain info. Exception: "+e.toString());
+ status = FAILED;
+ }
+ } catch (Exception e) {
+ CMS.debug("Failed to add entry" + e.toString());
+ } finally {
+ try {
+ if ((conn != null) && (connFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ connFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return status;
+ }
+
+
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateDomainXML: processing...");
+ String status = SUCCESS;
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ CMS.debug("UpdateDomainXML process: authentication starts");
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(cmsReq);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated");
+ return;
+ }
+ if (authToken == null) {
+ CMS.debug("UpdateDomainXML process: authToken is null");
+ outputError(httpResp, AUTH_FAILURE, "Error: not authenticated");
+ return;
+ }
+ CMS.debug("UpdateDomainXML process: authentication done");
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ AUTH_FAILURE,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+ if (authzToken == null) {
+ CMS.debug("UpdateDomainXML process: authorization error");
+ outputError(httpResp, AUTH_FAILURE, "Error: Not authorized");
+ return;
+ }
+
+ String list = httpReq.getParameter("list");
+ String type = httpReq.getParameter("type");
+ String host = httpReq.getParameter("host");
+ String name = httpReq.getParameter("name");
+ String sport = httpReq.getParameter("sport");
+ String agentsport = httpReq.getParameter("agentsport");
+ String adminsport = httpReq.getParameter("adminsport");
+ String eecaport = httpReq.getParameter("eeclientauthsport");
+ String httpport = httpReq.getParameter("httpport");
+ String domainmgr = httpReq.getParameter("dm");
+ String clone = httpReq.getParameter("clone");
+ String operation = httpReq.getParameter("operation");
+
+ // ensure required parameters are present
+ // especially important for DS syntax checking
+ String missing = "";
+ if ((host == null) || host.equals("")) {
+ missing += " host ";
+ }
+ if ((name == null) || name.equals("")) {
+ missing += " name ";
+ }
+ if ((sport == null) || sport.equals("")) {
+ missing += " sport ";
+ }
+ if ((clone == null) || clone.equals("")) {
+ clone = "false";
+ }
+
+ if (! missing.equals("")) {
+ CMS.debug("UpdateDomainXML process: required parameters:" + missing + "not provided in request");
+ outputError(httpResp, "Error: required parameters: " + missing + "not provided in request");
+ return;
+ }
+
+ String basedn = null;
+ String secstore = null;
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ try {
+ basedn = cs.getString("internaldb.basedn");
+ secstore = cs.getString("securitydomain.store");
+ }
+ catch (Exception e) {
+ CMS.debug("Unable to determine security domain name or basedn. Please run the domaininfo migration script");
+ }
+
+ if ((basedn != null) && (secstore != null) && (secstore.equals("ldap"))) {
+ // update in ldap
+
+ LDAPEntry entry = null;
+ ILdapConnFactory connFactory = null;
+ LDAPConnection conn = null;
+ String listName = type + "List";
+ String cn = host + ":";
+
+ if ((adminsport!= null) && (adminsport != "")) {
+ cn += adminsport;
+ } else {
+ cn += sport;
+ }
+
+ String dn = "cn=" + cn + ",cn=" + listName + ",ou=Security Domain," + basedn;
+ CMS.debug("UpdateDomainXML: updating LDAP entry: " + dn);
+
+ LDAPAttributeSet attrs = null;
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass", "pkiSubsystem"));
+ attrs.add(new LDAPAttribute("cn", cn));
+ attrs.add(new LDAPAttribute("Host", host));
+ attrs.add(new LDAPAttribute("SecurePort", sport));
+
+ if ((agentsport != null) && (!agentsport.equals(""))) {
+ attrs.add(new LDAPAttribute("SecureAgentPort", agentsport));
+ }
+ if ((adminsport != null) && (!adminsport.equals(""))) {
+ attrs.add(new LDAPAttribute("SecureAdminPort", adminsport));
+ }
+ if ((httpport != null) && (!httpport.equals(""))) {
+ attrs.add(new LDAPAttribute("UnSecurePort", httpport));
+ }
+ if ((eecaport != null) && (!eecaport.equals(""))) {
+ attrs.add(new LDAPAttribute("SecureEEClientAuthPort", eecaport));
+ }
+ if ((domainmgr != null) && (!domainmgr.equals(""))) {
+ attrs.add(new LDAPAttribute("DomainManager", domainmgr.toUpperCase()));
+ }
+ attrs.add(new LDAPAttribute("clone", clone.toUpperCase()));
+ attrs.add(new LDAPAttribute("SubsystemName", name));
+ entry = new LDAPEntry(dn, attrs);
+
+ if ((operation != null) && (operation.equals("remove"))) {
+ status = remove_from_ldap(dn);
+ String adminUserDN = "uid=" + type + "-" + host + "-" + agentsport + ",ou=People," + basedn;
+ if (status.equals(SUCCESS)) {
+ // remove the client cert for this subsystem's admin
+ status = remove_from_ldap(adminUserDN);
+ if (status.equals(SUCCESS)) {
+ // remove this user from the subsystem group
+ dn = "cn=Subsystem Group, ou=groups," + basedn;
+ LDAPModification mod = new LDAPModification(LDAPModification.DELETE,
+ new LDAPAttribute("uniqueMember", adminUserDN));
+ status = modify_ldap(dn, mod);
+ }
+ }
+ } else {
+ status = add_to_ldap(entry, dn);
+ }
+
+ }
+ else {
+ // update the domain.xml file
+ String path = CMS.getConfigStore().getString("instanceRoot", "")
+ + "/conf/domain.xml";
+
+ CMS.debug("UpdateDomainXML: got path=" + path);
+
+ try {
+ // using domain.xml file
+ CMS.debug("UpdateDomainXML: Inserting new domain info");
+ XMLObject parser = new XMLObject(new FileInputStream(path));
+ Node n = parser.getContainer(list);
+ int count =0;
+
+ if ((operation != null) && (operation.equals("remove"))) {
+ // delete node
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName(type);
+ int len = nodeList.getLength();
+
+ for (int i = 0; i < len; i++) {
+ Node nn = (Node) nodeList.item(i);
+ Vector v_name = parser.getValuesFromContainer(nn, "SubsystemName");
+ Vector v_host = parser.getValuesFromContainer(nn, "Host");
+ Vector v_adminport = parser.getValuesFromContainer(nn, "SecureAdminPort");
+ if ((v_name.elementAt(0).equals(name)) && (v_host.elementAt(0).equals(host))
+ && (v_adminport.elementAt(0).equals(adminsport))) {
+ Node parent = nn.getParentNode();
+ Node remNode = parent.removeChild(nn);
+ count --;
+ break;
+ }
+ }
+ } else {
+ // add node
+ Node parent = parser.createContainer(n, type);
+ parser.addItemToContainer(parent, "SubsystemName", name);
+ parser.addItemToContainer(parent, "Host", host);
+ parser.addItemToContainer(parent, "SecurePort", sport);
+ parser.addItemToContainer(parent, "SecureAgentPort", agentsport);
+ parser.addItemToContainer(parent, "SecureAdminPort", adminsport);
+ parser.addItemToContainer(parent, "SecureEEClientAuthPort", eecaport);
+ parser.addItemToContainer(parent, "UnSecurePort", httpport);
+ parser.addItemToContainer(parent, "DomainManager", domainmgr.toUpperCase());
+ parser.addItemToContainer(parent, "Clone", clone.toUpperCase());
+ count ++;
+ }
+ //update count
+
+ String countS = "";
+ NodeList nlist = n.getChildNodes();
+ Node countnode = null;
+ for (int i=0; i<nlist.getLength(); i++) {
+ Element nn = (Element)nlist.item(i);
+ String tagname = nn.getTagName();
+ if (tagname.equals("SubsystemCount")) {
+ countnode = nn;
+ NodeList nlist1 = nn.getChildNodes();
+ Node nn1 = nlist1.item(0);
+ countS = nn1.getNodeValue();
+ break;
+ }
+ }
+
+ CMS.debug("UpdateDomainXML process: SubsystemCount="+countS);
+ try {
+ count += Integer.parseInt(countS);
+ } catch (Exception ee) {
+ }
+
+ Node nn2 = n.removeChild(countnode);
+ parser.addItemToContainer(n, "SubsystemCount", ""+count);
+
+ // recreate domain.xml
+ CMS.debug("UpdateDomainXML: Recreating domain.xml");
+ byte[] b = parser.toByteArray();
+ FileOutputStream fos = new FileOutputStream(path);
+ fos.write(b);
+ fos.close();
+ } catch (Exception e) {
+ CMS.debug("Failed to update domain.xml file" + e.toString());
+ status = FAILED;
+ }
+ }
+
+ try {
+ // send success status back to the requestor
+ CMS.debug("UpdateDomainXML: Sending response");
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", status);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("UpdateDomainXML: Failed to send the XML output" + e.toString());
+ }
+ }
+
+ protected String securityDomainXMLtoLDAP(String xmltag) {
+ if (xmltag.equals("Host")) return "host";
+ else return xmltag;
+ }
+
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
new file mode 100644
index 000000000..890d6dfb1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
@@ -0,0 +1,284 @@
+// --- 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.servlet.csadmin;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+public class UpdateNumberRange extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public UpdateNumberRange() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("UpdateNumberRange: initializing...");
+ super.init(sc);
+ CMS.debug("UpdateNumberRange: done initializing...");
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateNumberRange: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ CMS.debug("UpdateNumberRange process: authentication starts");
+ IAuthToken authToken = authenticate(cmsReq);
+ if (authToken == null) {
+ CMS.debug("UpdateNumberRange process: authToken is null");
+ outputError(httpResp, AUTH_FAILURE, "Error: not authenticated");
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ try {
+ String type = httpReq.getParameter("type");
+ IConfigStore cs = CMS.getConfigStore();
+ String cstype = cs.getString("cs.type", "");
+
+ BigInteger beginNum = null;
+ BigInteger endNum = null;
+ BigInteger oneNum = new BigInteger("1");
+ String endNumConfig = null;
+ String cloneNumConfig = null;
+ String nextEndConfig = null;
+ int radix = 10;
+
+ IRepository repo = null;
+ if (cstype.equals("KRA")) {
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority) CMS.getSubsystem(
+ IKeyRecoveryAuthority.ID);
+ if (type.equals("request")) {
+ repo = kra.getRequestQueue().getRequestRepository();
+ } else if (type.equals("serialNo")) {
+ repo = kra.getKeyRepository();
+ } else if (type.equals("replicaId")) {
+ repo = kra.getReplicaRepository();
+ }
+ } else { // CA
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(
+ ICertificateAuthority.ID);
+ if (type.equals("request")) {
+ repo = ca.getRequestQueue().getRequestRepository();
+ } else if (type.equals("serialNo")) {
+ repo = ca.getCertificateRepository();
+ } else if (type.equals("replicaId")) {
+ repo = ca.getReplicaRepository();
+ }
+ }
+
+ // checkRanges for replicaID - we do this each time a replica is created.
+ // This needs to be done beforehand to ensure that we always have enough
+ // replica numbers
+ if (type.equals("replicaId")) {
+ CMS.debug("Checking replica number ranges");
+ repo.checkRanges();
+ }
+
+ if (type.equals("request")) {
+ radix = 10;
+ endNumConfig = "dbs.endRequestNumber";
+ cloneNumConfig = "dbs.requestCloneTransferNumber";
+ nextEndConfig = "dbs.nextEndRequestNumber";
+ } else if (type.equals("serialNo")) {
+ radix=16;
+ endNumConfig = "dbs.endSerialNumber";
+ cloneNumConfig = "dbs.serialCloneTransferNumber";
+ nextEndConfig = "dbs.nextEndSerialNumber";
+ } else if (type.equals("replicaId")) {
+ radix=10;
+ endNumConfig = "dbs.endReplicaNumber";
+ cloneNumConfig = "dbs.replicaCloneTransferNumber";
+ nextEndConfig = "dbs.nextEndReplicaNumber";
+ }
+
+ String endNumStr = cs.getString(endNumConfig, "");
+ endNum = new BigInteger(endNumStr, radix);
+ if ( endNum == null ) {
+ CMS.debug( "UpdateNumberRange::process() - " +
+ "request endNum is null!" );
+ return;
+ }
+
+ String decrementStr = cs.getString(cloneNumConfig, "");
+ BigInteger decrement = new BigInteger(decrementStr, radix);
+ if (decrement == null) {
+ CMS.debug("UpdateNumberRange::process() - " +
+ "request decrement string is null!" );
+ return;
+ }
+
+ beginNum = endNum.subtract(decrement).add(oneNum);
+
+ if (beginNum.compareTo(repo.getTheSerialNumber()) < 0) {
+ String nextEndNumStr = cs.getString(nextEndConfig, "");
+ BigInteger endNum2 = new BigInteger(nextEndNumStr, radix);
+ if (endNum2 == null) {
+ CMS.debug("UpdateNumberRange::process() - " +
+ "Unused requests less than cloneTransferNumber!" );
+ return;
+ } else {
+ CMS.debug("Transferring from the end of on-deck range");
+ String newValStr = endNum2.subtract(decrement).toString(radix);
+ repo.setNextMaxSerial(newValStr);
+ cs.putString(nextEndConfig, newValStr);
+ beginNum = endNum2.subtract(decrement).add(oneNum);
+ endNum = endNum2;
+ }
+ } else {
+ CMS.debug("Transferring from the end of the current range");
+ String newValStr = beginNum.subtract(oneNum).toString(radix);
+ repo.setMaxSerial(newValStr);
+ cs.putString(endNumConfig, newValStr);
+ }
+
+
+ if( beginNum == null ) {
+ CMS.debug( "UpdateNumberRange::process() - " +
+ "beginNum is null!" );
+ return;
+ }
+
+ if( endNum == null ) {
+ CMS.debug( "UpdateNumberRange::process() - " +
+ "endNum is null!" );
+ return;
+ }
+
+ // Enable serial number management in master for certs and requests
+ if (type.equals("replicaId")) {
+ repo.setEnableSerialMgmt(true);
+ }
+
+ // insert info
+ CMS.debug("UpdateNumberRange: Sending response");
+
+ // send success status back to the requestor
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ xmlObj.addItemToContainer(root, "beginNumber", beginNum.toString(radix));
+ xmlObj.addItemToContainer(root, "endNumber", endNum.toString(radix));
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ cs.commit(false);
+ } catch (Exception e) {
+ CMS.debug("UpdateNumberRange: Failed to update number range. Exception: "+e.toString());
+ outputError(httpResp, "Error: Failed to update number range.");
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java
new file mode 100644
index 000000000..b2b8b5d28
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java
@@ -0,0 +1,180 @@
+// --- 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.servlet.csadmin;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.xml.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+public class UpdateOCSPConfig extends CMSServlet {
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+
+ public UpdateOCSPConfig() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ CMS.debug("UpdateOCSPConfig: initializing...");
+ super.init(sc);
+ CMS.debug("UpdateOCSPConfig: done initializing...");
+ }
+
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("UpdateOCSPConfig: processing...");
+
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ CMS.debug("UpdateOCSPConfig process: authentication starts");
+ IAuthToken authToken = authenticate(cmsReq);
+ if (authToken == null) {
+ CMS.debug("UpdateOCSPConfig process: authToken is null");
+ outputError(httpResp, AUTH_FAILURE, "Error: not authenticated");
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName,
+ "modify");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ outputError(httpResp,
+ "Error: Encountered problem during authorization.");
+ return;
+ }
+ if (authzToken == null) {
+ outputError(httpResp, "Error: Not authorized");
+ return;
+ }
+
+ IConfigStore cs = CMS.getConfigStore();
+ String nickname = "";
+
+ // get nickname
+ try {
+ nickname = cs.getString("ca.subsystem.nickname", "");
+ String tokenname = cs.getString("ca.subsystem.tokenname", "");
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ } catch (Exception e) {
+ }
+
+ CMS.debug("UpdateOCSPConfig process: nickname="+nickname);
+
+ String ocsphost = httpReq.getParameter("ocsp_host");
+ String ocspport = httpReq.getParameter("ocsp_port");
+ try {
+ cs.putString("ca.publish.enable", "true");
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.host",
+ ocsphost);
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.port",
+ ocspport);
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.nickName",
+ nickname);
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.path",
+ "/ocsp/agent/ocsp/addCRL");
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.pluginName", "OCSPPublisher");
+ cs.putString("ca.publish.publisher.instance.OCSPPublisher.enableClientAuth", "true");
+ cs.putString("ca.publish.rule.instance.ocsprule.enable", "true");
+ cs.putString("ca.publish.rule.instance.ocsprule.mapper", "NoMap");
+ cs.putString("ca.publish.rule.instance.ocsprule.pluginName", "Rule");
+ cs.putString("ca.publish.rule.instance.ocsprule.publisher",
+ "OCSPPublisher");
+ cs.putString("ca.publish.rule.instance.ocsprule.type", "crl");
+ cs.commit(false);
+ // insert info
+ CMS.debug("UpdateOCSPConfig: Sending response");
+
+ // send success status back to the requestor
+ XMLObject xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ byte[] cb = xmlObj.toByteArray();
+
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("UpdateOCSPConfig: Failed to update OCSP configuration. Exception: "+e.toString());
+ outputError(httpResp, "Error: Failed to update OCSP configuration.");
+ }
+ }
+
+ protected void setDefaultTemplates(ServletConfig sc) {}
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {// do nothing
+ }
+
+ protected void renderResult(CMSRequest cmsReq) throws IOException {// do nothing, ie, it will not return the default javascript.
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
new file mode 100644
index 000000000..cb3cf7543
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
@@ -0,0 +1,123 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+
+import com.netscape.cms.servlet.wizard.*;
+
+public class WelcomePanel extends WizardPanelBase {
+
+ public WelcomePanel() {}
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException {
+ setPanelNo(panelno);
+ setName("Welcome");
+ setId(id);
+ }
+
+ public void cleanUp() throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ cs.putBoolean("preop.welcome.done", false);
+ }
+
+ public boolean isPanelDone() {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ return cs.getBoolean("preop.welcome.done");
+ } catch (EBaseException e) {}
+ return false;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = new PropertySet();
+
+ /* XXX */
+
+ return set;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+ IConfigStore cs = CMS.getConfigStore();
+ CMS.debug("WelcomePanel: display()");
+ context.put("title", "Welcome");
+ try {
+ context.put("cstype", cs.getString("cs.type"));
+ context.put("wizardname", cs.getString("preop.wizard.name"));
+ context.put("panelname",
+ cs.getString("preop.system.fullname") + " Configuration Wizard");
+ context.put("systemname",
+ cs.getString("preop.system.name"));
+ context.put("fullsystemname",
+ cs.getString("preop.system.fullname"));
+ context.put("productname",
+ cs.getString("preop.product.name"));
+ context.put("productversion",
+ cs.getString("preop.product.version"));
+ } catch (EBaseException e) {}
+ context.put("panel", "admin/console/config/welcomepanel.vm");
+ }
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ cs.putBoolean("preop.welcome.done", true);
+ cs.commit(false);
+ } catch (EBaseException e) {}
+ }
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {/* This should never be called */}
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java
new file mode 100644
index 000000000..2871b9e41
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java
@@ -0,0 +1,45 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+
+
+public class WelcomeServlet extends BaseServlet {
+
+ public Template process(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {
+
+ Template template = null;
+
+ try {
+ context.put("name", "Velocity Test");
+ template = Velocity.getTemplate("admin/console/config/welcome.vm");
+ } catch (Exception e) {
+ System.err.println("Exception caught: " + e.getMessage());
+ }
+
+ return template;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java
new file mode 100644
index 000000000..c34adc408
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java
@@ -0,0 +1,1603 @@
+// --- 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.servlet.csadmin;
+
+
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+import javax.servlet.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cms.servlet.wizard.*;
+import com.netscape.cms.servlet.base.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.util.Base64OutputStream;
+import org.mozilla.jss.pkcs11.*;
+import netscape.security.x509.*;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.http.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import java.security.cert.*;
+import java.security.*;
+import netscape.ldap.*;
+
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.cms.servlet.wizard.*;
+
+public class WizardPanelBase implements IWizardPanel {
+ public static String PCERT_PREFIX = "preop.cert.";
+ public static String SUCCESS = "0";
+ public static String FAILURE = "1";
+ public static String AUTH_FAILURE = "2";
+
+ /**
+ * Definition for static variables in CS.cfg
+ */
+ public static final String CONF_CA_CERT = "ca.signing.cert";
+ public static final String CONF_CA_CERTREQ = "ca.signing.certreq";
+ public static final String CONF_CA_CERTNICKNAME = "ca.signing.certnickname";
+
+ public static final String PRE_CONF_ADMIN_NAME = "preop.admin.name";
+ public static final String PRE_CONF_AGENT_GROUP = "preop.admin.group";
+
+ /**
+ * Definition for "preop" static variables in CS.cfg
+ * -- "preop" config parameters should not assumed to exist after configuation
+ */
+
+ public static final String PRE_CONF_CA_TOKEN = "preop.module.token";
+ public static final String PRE_CA_TYPE = "preop.ca.type";
+ public static final String PRE_OTHER_CA = "otherca";
+ public static final String PRE_ROOT_CA = "rootca";
+
+ private String mName = null;
+ private int mPanelNo = 0;
+ private String mId = null;
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException
+ {
+ mPanelNo = panelno;
+ }
+
+ public void init(WizardServlet servlet, ServletConfig config, int panelno, String id)
+ throws ServletException
+ {
+ mPanelNo = panelno;
+ }
+
+ /**
+ * Cleans up this panel so that isPanelDone() will return false.
+ */
+ public void cleanUp() throws IOException {
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public int getPanelNo() {
+ return mPanelNo;
+ }
+
+ public void setPanelNo(int num) {
+ mPanelNo = num;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public PropertySet getUsage() {
+ PropertySet set = null;
+
+ return set;
+ }
+
+ /**
+ * Should we skip this panel?
+ */
+ public boolean shouldSkip() {
+ return false;
+ }
+
+ /**
+ * Is this panel done
+ */
+ public boolean isPanelDone() {
+ return false;
+ }
+
+ /**
+ * Show "Apply" button on frame?
+ */
+ public boolean showApplyButton() {
+ return false;
+ }
+
+ /**
+ * Is this a subPanel?
+ */
+ public boolean isSubPanel() {
+ return false;
+ }
+
+ public boolean isLoopbackPanel() {
+ return false;
+ }
+
+ /**
+ * has subPanels?
+ */
+ public boolean hasSubPanel() {
+ return false;
+ }
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {}
+
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ }
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {}
+
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) {}
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ public Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ public String getNickname(IConfigStore config, String certTag) {
+ String instanceID = "";
+
+ try {
+ instanceID = config.getString("instanceId", "");
+ } catch (Exception e) {}
+
+ String nickname = certTag + "Cert cert-" + instanceID;
+ String preferredNickname = null;
+
+ try {
+ preferredNickname = config.getString(
+ PCERT_PREFIX + certTag + ".nickname", null);
+ } catch (Exception e) {}
+
+ if (preferredNickname != null) {
+ nickname = preferredNickname;
+ }
+ return nickname;
+ }
+
+ public void updateDomainXML(String hostname, int port, boolean https,
+ String servlet, String uri) throws IOException {
+ CMS.debug("WizardPanelBase updateDomainXML start hostname=" + hostname + " port=" + port);
+ IConfigStore cs = CMS.getConfigStore();
+ String nickname = "";
+ String tokenname = "";
+ try {
+ nickname = cs.getString("preop.cert.subsystem.nickname", "");
+ tokenname = cs.getString("preop.module.token", "");
+ } catch (Exception e) {}
+
+ if (!tokenname.equals("") &&
+ !tokenname.equals("Internal Key Storage Token") &&
+ !tokenname.equals("internal")) {
+ nickname = tokenname+":"+nickname;
+ }
+
+ CMS.debug("WizardPanelBase updateDomainXML nickname=" + nickname);
+ CMS.debug("WizardPanelBase: start sending updateDomainXML request");
+ String c = getHttpResponse(hostname, port, https, servlet, uri, nickname);
+ CMS.debug("WizardPanelBase: done sending updateDomainXML request");
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject obj = null;
+ try {
+ obj = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::updateDomainXML() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = obj.getValue("Status");
+ CMS.debug("WizardPanelBase updateDomainXML: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ return;
+ } else {
+ String error = obj.getValue("Error");
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: updateDomainXML: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: updateDomainXML: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+ }
+
+ public int getSubsystemCount( String hostname, int https_admin_port,
+ boolean https, String type )
+ throws IOException {
+ CMS.debug("WizardPanelBase getSubsystemCount start");
+ String c = getDomainXML(hostname, https_admin_port, true);
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject obj = new XMLObject(bis);
+ String containerName = type+"List";
+ Node n = obj.getContainer(containerName);
+ NodeList nlist = n.getChildNodes();
+ String countS = "";
+ for (int i=0; i<nlist.getLength(); i++) {
+ Element nn = (Element)nlist.item(i);
+ String tagname = nn.getTagName();
+ if (tagname.equals("SubsystemCount")) {
+ NodeList nlist1 = nn.getChildNodes();
+ Node nn1 = nlist1.item(0);
+ countS = nn1.getNodeValue();
+ break;
+ }
+ }
+ CMS.debug("WizardPanelBase getSubsystemCount: SubsystemCount="+countS);
+ int num = 0;
+
+ if (countS != null && !countS.equals("")) {
+ try {
+ num = Integer.parseInt(countS);
+ } catch (Exception ee) {
+ }
+ }
+
+ return num;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getSubsystemCount: "+e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return -1;
+ }
+
+ public String getDomainXML( String hostname, int https_admin_port,
+ boolean https )
+ throws IOException {
+ CMS.debug("WizardPanelBase getDomainXML start");
+ String c = getHttpResponse( hostname, https_admin_port, https,
+ "/ca/admin/ca/getDomainXML", null, null );
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getDomainXML() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase getDomainXML: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String domainInfo = parser.getValue("DomainInfo");
+
+ CMS.debug(
+ "WizardPanelBase getDomainXML: domainInfo="
+ + domainInfo);
+ return domainInfo;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: getDomainXML: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getDomainXML: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public String getSubsystemCert(String host, int port, boolean https)
+ throws IOException {
+ CMS.debug("WizardPanelBase getSubsystemCert start");
+ String c = getHttpResponse(host, port, https,
+ "/ca/admin/ca/getSubsystemCert", null, null);
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis =
+ new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getSubsystemCert() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+ String status = parser.getValue("Status");
+ if (status.equals(SUCCESS)) {
+ String s = parser.getValue("Cert");
+ return s;
+ } else
+ return null;
+ } catch (Exception e) {
+ }
+ }
+
+ return null;
+ }
+
+ public void updateConnectorInfo(String host, int port, boolean https,
+ String content) throws IOException {
+ CMS.debug("WizardPanelBase updateConnectorInfo start");
+ String c = getHttpResponse(host, port, https,
+ "/ca/admin/ca/updateConnector", content, null);
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::updateConnectorInfo() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase updateConnectorInfo: status=" + status);
+
+ if (!status.equals(SUCCESS)) {
+ String error = parser.getValue("Error");
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: updateConnectorInfo: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: updateConnectorInfo: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+ }
+
+ public String getCertChainUsingSecureAdminPort( String hostname,
+ int https_admin_port,
+ boolean https,
+ ConfigCertApprovalCallback
+ certApprovalCallback )
+ throws IOException {
+ CMS.debug("WizardPanelBase getCertChainUsingSecureAdminPort start");
+ String c = getHttpResponse( hostname, https_admin_port, https,
+ "/ca/admin/ca/getCertChain", null, null,
+ certApprovalCallback );
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getCertChainUsingSecureAdminPort() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase getCertChainUsingSecureAdminPort: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String certchain = parser.getValue("ChainBase64");
+
+ certchain = CryptoUtil.normalizeCertStr(certchain);
+ CMS.debug(
+ "WizardPanelBase getCertChainUsingSecureAdminPort: certchain="
+ + certchain);
+ return certchain;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: getCertChainUsingSecureAdminPort: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getCertChainUsingSecureAdminPort: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public String getCertChainUsingSecureEEPort( String hostname,
+ int https_ee_port,
+ boolean https,
+ ConfigCertApprovalCallback
+ certApprovalCallback )
+ throws IOException {
+ CMS.debug("WizardPanelBase getCertChainUsingSecureEEPort start");
+ String c = getHttpResponse( hostname, https_ee_port, https,
+ "/ca/ee/ca/getCertChain", null, null,
+ certApprovalCallback );
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getCertChainUsingSecureEEPort() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase getCertChainUsingSecureEEPort: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String certchain = parser.getValue("ChainBase64");
+
+ certchain = CryptoUtil.normalizeCertStr(certchain);
+ CMS.debug(
+ "WizardPanelBase getCertChainUsingSecureEEPort: certchain="
+ + certchain);
+ return certchain;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: getCertChainUsingSecureEEPort: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getCertChainUsingSecureEEPort: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public boolean updateConfigEntries(String hostname, int port, boolean https,
+ String servlet, String uri, IConfigStore config,
+ HttpServletResponse response) throws IOException {
+ CMS.debug("WizardPanelBase updateConfigEntries start");
+ String c = getHttpResponse(hostname, port, https, servlet, uri, null);
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::updateConfigEntries() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase updateConfigEntries: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String cstype = "";
+ try {
+ cstype = config.getString("cs.type", "");
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase::updateConfigEntries() - unable to get cs.type: " + e.toString());
+ }
+
+ Document doc = parser.getDocument();
+ NodeList list = doc.getElementsByTagName("name");
+ int len = list.getLength();
+ for (int i=0; i<len; i++) {
+ Node n = list.item(i);
+ NodeList nn = n.getChildNodes();
+ String name = nn.item(0).getNodeValue();
+ Node parent = n.getParentNode();
+ nn = parent.getChildNodes();
+ int len1 = nn.getLength();
+ String v = "";
+ for (int j=0; j<len1; j++) {
+ Node nv = nn.item(j);
+ String val = nv.getNodeName();
+ if (val.equals("value")) {
+ NodeList n2 = nv.getChildNodes();
+ if (n2.getLength() > 0)
+ v = n2.item(0).getNodeValue();
+ break;
+ }
+ }
+
+ if (name.equals("internaldb.ldapconn.host")) {
+ config.putString("preop.internaldb.master.hostname", v);
+ } else if (name.equals("internaldb.ldapconn.port")) {
+ config.putString("preop.internaldb.master.port", v);
+ } else if (name.equals("internaldb.ldapauth.bindDN")) {
+ config.putString("preop.internaldb.master.binddn", v);
+ } else if (name.equals("internaldb.basedn")) {
+ config.putString(name, v);
+ config.putString("preop.internaldb.master.basedn", v);
+ } else if (name.equals("internaldb.ldapauth.password")) {
+ config.putString("preop.internaldb.master.bindpwd", v);
+ } else if (name.equals("internaldb.replication.password")) {
+ config.putString("preop.internaldb.master.replicationpwd", v);
+ } else if (name.equals("instanceId")) {
+ config.putString("preop.master.instanceId", v);
+ } else if (name.equals("cloning.cert.signing.nickname")) {
+ config.putString("preop.master.signing.nickname", v);
+ config.putString("preop.cert.signing.nickname", v);
+ } else if (name.equals("cloning.ocsp_signing.nickname")) {
+ config.putString("preop.master.ocsp_signing.nickname", v);
+ config.putString("preop.cert.ocsp_signing.nickname", v);
+ } else if (name.equals("cloning.subsystem.nickname")) {
+ config.putString("preop.master.subsystem.nickname", v);
+ config.putString("preop.cert.subsystem.nickname", v);
+ } else if (name.equals("cloning.transport.nickname")) {
+ config.putString("preop.master.transport.nickname", v);
+ config.putString("kra.transportUnit.nickName", v);
+ config.putString("preop.cert.transport.nickname", v);
+ } else if (name.equals("cloning.storage.nickname")) {
+ config.putString("preop.master.storage.nickname", v);
+ config.putString("kra.storageUnit.nickName", v);
+ config.putString("preop.cert.storage.nickname", v);
+ } else if (name.equals("cloning.audit_signing.nickname")) {
+ config.putString("preop.master.audit_signing.nickname", v);
+ config.putString("preop.cert.audit_signing.nickname", v);
+ config.putString(name, v);
+ } else if (name.startsWith("cloning.ca")) {
+ config.putString(name.replaceFirst("cloning", "preop"), v);
+ } else if (name.equals("cloning.signing.keyalgorithm")) {
+ config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+ if (cstype.equals("CA")) {
+ config.putString("ca.crl.MasterCRL.signingAlgorithm", v);
+ config.putString("ca.signing.defaultSigningAlgorithm", v);
+ } else if (cstype.equals("OCSP")) {
+ config.putString("ocsp.signing.defaultSigningAlgorithm", v);
+ }
+ } else if (name.equals("cloning.transport.keyalgorithm")) {
+ config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+ config.putString("kra.transportUnit.signingAlgorithm", v);
+ } else if (name.equals("cloning.ocsp_signing.keyalgorithm")) {
+ config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+ if (cstype.equals("CA")) {
+ config.putString("ca.ocsp_signing.defaultSigningAlgorithm", v);
+ }
+ } else if (name.startsWith("cloning")) {
+ config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+ } else {
+ config.putString(name, v);
+ }
+ }
+
+ return true;
+ } else if (status.equals(AUTH_FAILURE)) {
+ reloginSecurityDomain(response);
+ return false;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: updateConfigEntries: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: updateConfigEntries: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return false;
+ }
+
+ public boolean authenticate(String hostname, int port, boolean https,
+ String servlet, String uri) throws IOException {
+ CMS.debug("WizardPanelBase authenticate start");
+ String c = getHttpResponse(hostname, port, https, servlet, uri, null);
+ IConfigStore cs = CMS.getConfigStore();
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::authenticate() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase authenticate: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String cookie = parser.getValue("Cookie");
+ cs.putString("preop.cookie", cookie);
+ return true;
+ } else {
+ String error = parser.getValue("Error");
+ return false;
+ }
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: authenticate: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return false;
+ }
+
+ public void updateOCSPConfig(String hostname, int port, boolean https,
+ String content, HttpServletResponse response)
+ throws IOException {
+ CMS.debug("WizardPanelBase updateOCSPConfig start");
+ String c = getHttpResponse(hostname, port, https,
+ "/ca/ee/ca/updateOCSPConfig", content, null);
+ if (c == null || c.equals("")) {
+ CMS.debug("WizardPanelBase updateOCSPConfig: content is null.");
+ throw new IOException("The server you want to contact is not available");
+ } else {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::updateOCSPConfig() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase updateOCSPConfig: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ CMS.debug("WizardPanelBase updateOCSPConfig: Successfully update the OCSP configuration in the CA.");
+ } else if (status.equals(AUTH_FAILURE)) {
+ reloginSecurityDomain(response);
+ return;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase updateOCSPConfig: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase updateOCSPConfig: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+ }
+
+ public void updateNumberRange(String hostname, int port, boolean https,
+ String content, String type, HttpServletResponse response)
+ throws IOException {
+ CMS.debug("WizardPanelBase updateNumberRange start host=" + hostname +
+ " port=" + port);
+ IConfigStore cs = CMS.getConfigStore();
+ String cstype = "";
+ try {
+ cstype = cs.getString("cs.type", "");
+ } catch (Exception e) {
+ }
+
+ cstype = toLowerCaseSubsystemType(cstype);
+ String c = getHttpResponse(hostname, port, https,
+ "/"+cstype+"/ee/"+cstype+"/updateNumberRange", content, null);
+ if (c == null || c.equals("")) {
+ CMS.debug("WizardPanelBase updateNumberRange: content is null.");
+ throw new IOException("The server you want to contact is not available");
+ } else {
+ CMS.debug("content="+c);
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::updateNumberRange() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase updateNumberRange: status=" + status);
+ if (status.equals(SUCCESS)) {
+ String beginNum = parser.getValue("beginNumber");
+ String endNum = parser.getValue("endNumber");
+ if (type.equals("request")) {
+ cs.putString("dbs.beginRequestNumber", beginNum);
+ cs.putString("dbs.endRequestNumber", endNum);
+ } else if (type.equals("serialNo")) {
+ cs.putString("dbs.beginSerialNumber", beginNum);
+ cs.putString("dbs.endSerialNumber", endNum);
+ } else if (type.equals("replicaId")) {
+ cs.putString("dbs.beginReplicaNumber", beginNum);
+ cs.putString("dbs.endReplicaNumber", endNum);
+ }
+ // enable serial number management in clone
+ cs.putString("dbs.enableSerialManagement", "true");
+ cs.commit(false);
+ } else if (status.equals(AUTH_FAILURE)) {
+ reloginSecurityDomain(response);
+ return;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: updateNumberRange: " + e.toString());
+ CMS.debug(e);
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: updateNumberRange: " + e.toString());
+ CMS.debug(e);
+ throw new IOException(e.toString());
+ }
+ }
+ }
+
+ public int getPort(String hostname, int port, boolean https,
+ String portServlet, boolean sport)
+ throws IOException {
+ CMS.debug("WizardPanelBase getPort start");
+ String c = getHttpResponse(hostname, port, https, portServlet,
+ "secure=" + sport, null);
+
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getPort() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase getPort: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ String portStr = parser.getValue("Port");
+
+ port = Integer.parseInt(portStr);
+ return port;
+ } else {
+ String error = parser.getValue("Error");
+
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: getPort: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getPort: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ return -1;
+ }
+
+ public String getHttpResponse(String hostname, int port, boolean secure,
+ String uri, String content, String clientnickname) throws IOException {
+ return getHttpResponse(hostname, port, secure, uri, content, clientnickname, null);
+ }
+
+ public String getHttpResponse(String hostname, int port, boolean secure,
+ String uri, String content, String clientnickname,
+ SSLCertificateApprovalCallback certApprovalCallback)
+ throws IOException {
+ HttpClient httpclient = null;
+ String c = null;
+
+ try {
+ if (secure) {
+ JssSSLSocketFactory factory = null;
+ if (clientnickname != null && clientnickname.length() > 0)
+ factory = new JssSSLSocketFactory(clientnickname);
+ else
+ factory = new JssSSLSocketFactory();
+
+ httpclient = new HttpClient(factory, certApprovalCallback);
+ } else {
+ httpclient = new HttpClient();
+ }
+ httpclient.connect(hostname, port);
+ HttpRequest httprequest = new HttpRequest();
+
+ httprequest.setMethod(HttpRequest.POST);
+ httprequest.setURI(uri);
+ // httprequest.setURI("/ca/ee/ca/ports");
+ httprequest.setHeader("user-agent", "HTTPTool/1.0");
+ // String content_c = "secure="+secure;
+ httprequest.setHeader("content-type",
+ "application/x-www-form-urlencoded");
+ if (content != null && content.length() > 0) {
+ String content_c = content;
+
+ httprequest.setHeader("content-length", "" + content_c.length());
+ httprequest.setContent(content_c);
+ }
+ HttpResponse httpresponse = httpclient.send(httprequest);
+
+ c = httpresponse.getContent();
+ } catch (ConnectException e) {
+ CMS.debug("WizardPanelBase getHttpResponse: " + e.toString());
+ throw new IOException("The server you tried to contact is not running.");
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase getHttpResponse: " + e.toString());
+ throw new IOException(e.toString());
+ } finally {
+ if (httpclient.connected()) {
+ httpclient.disconnect();
+ }
+ }
+
+ return c;
+ }
+
+ public boolean isSDHostDomainMaster (IConfigStore config) {
+ String dm="false";
+ try {
+ String hostname = config.getString("securitydomain.host");
+ int httpsadminport = config.getInteger("securitydomain.httpsadminport");
+
+ CMS.debug("Getting domain.xml from CA...");
+ String c = getDomainXML(hostname, httpsadminport, true);
+
+ CMS.debug("Getting DomainMaster from security domain");
+
+ ByteArrayInputStream bis = new ByteArrayInputStream( c.getBytes() );
+ XMLObject parser = new XMLObject( bis );
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName( "CA" );
+
+ int len = nodeList.getLength();
+ for( int i = 0; i < len; i++ ) {
+ Vector v_hostname =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "Host" );
+
+ Vector v_https_admin_port =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "SecureAdminPort" );
+
+ Vector v_domain_mgr =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "DomainManager" );
+
+ if( v_hostname.elementAt( 0 ).equals( hostname ) &&
+ v_https_admin_port.elementAt( 0 ).equals( Integer.toString(httpsadminport) ) ) {
+ dm = v_domain_mgr.elementAt( 0 ).toString();
+ break;
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug( e.toString() );
+ }
+ return dm.equalsIgnoreCase("true");
+ }
+
+ public Vector getMasterUrlListFromSecurityDomain( IConfigStore config,
+ String type,
+ String portType ) {
+ Vector v = new Vector();
+
+ try {
+ String hostname = config.getString("securitydomain.host");
+ int httpsadminport = config.getInteger("securitydomain.httpsadminport");
+
+ CMS.debug("Getting domain.xml from CA...");
+ String c = getDomainXML(hostname, httpsadminport, true);
+ String list = "";
+
+ CMS.debug("Type " + type);
+ if (type.equals("CA")) {
+ list = "CAList";
+ } else if (type.equals("KRA")) {
+ list = "KRAList";
+ } else if (type.equals("OCSP")) {
+ list = "OCSPList";
+ } else if (type.equals("TKS")) {
+ list = "TKSList";
+ }
+
+ CMS.debug( "Getting " + portType + " from Security Domain ..." );
+ if( !portType.equals( "UnSecurePort" ) &&
+ !portType.equals( "SecureAgentPort" ) &&
+ !portType.equals( "SecurePort" ) &&
+ !portType.equals( "SecureAdminPort" ) ) {
+ CMS.debug( "getPortFromSecurityDomain: " +
+ "unknown port type " + portType );
+ return v;
+ }
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = new XMLObject(bis);
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName(type);
+
+ // save domain name in cfg
+ config.putString("securitydomain.name",
+ parser.getValue("Name"));
+
+ int len = nodeList.getLength();
+
+ CMS.debug("Len " + len);
+ for (int i = 0; i < len; i++) {
+ Vector v_clone = parser.getValuesFromContainer(nodeList.item(i),
+ "Clone");
+ String clone = (String)v_clone.elementAt(0);
+ if (clone.equalsIgnoreCase("true"))
+ continue;
+ Vector v_name = parser.getValuesFromContainer(nodeList.item(i),
+ "SubsystemName");
+ Vector v_host = parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+ Vector v_port = parser.getValuesFromContainer(nodeList.item(i),
+ portType);
+
+ v.addElement( v_name.elementAt(0)
+ + " - https://"
+ + v_host.elementAt(0)
+ + ":"
+ + v_port.elementAt(0) );
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+
+ return v;
+ }
+
+ public Vector getUrlListFromSecurityDomain( IConfigStore config,
+ String type,
+ String portType ) {
+ Vector v = new Vector();
+
+ try {
+ String hostname = config.getString("securitydomain.host");
+ int httpsadminport = config.getInteger("securitydomain.httpsadminport");
+
+ CMS.debug("Getting domain.xml from CA...");
+ String c = getDomainXML(hostname, httpsadminport, true);
+ String list = "";
+
+ CMS.debug("Subsystem Type " + type);
+ if (type.equals("CA")) {
+ list = "CAList";
+ } else if (type.equals("KRA")) {
+ list = "KRAList";
+ } else if (type.equals("OCSP")) {
+ list = "OCSPList";
+ } else if (type.equals("TKS")) {
+ list = "TKSList";
+ }
+
+ CMS.debug( "Getting " + portType + " from Security Domain ..." );
+ if( !portType.equals( "UnSecurePort" ) &&
+ !portType.equals( "SecureAgentPort" ) &&
+ !portType.equals( "SecurePort" ) &&
+ !portType.equals( "SecureAdminPort" ) ) {
+ CMS.debug( "getPortFromSecurityDomain: " +
+ "unknown port type " + portType );
+ return v;
+ }
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = new XMLObject(bis);
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName(type);
+
+ // save domain name in cfg
+ config.putString("securitydomain.name",
+ parser.getValue("Name"));
+
+ int len = nodeList.getLength();
+
+ CMS.debug("Len " + len);
+ for (int i = 0; i < len; i++) {
+ Vector v_name = parser.getValuesFromContainer(nodeList.item(i),
+ "SubsystemName");
+ Vector v_host = parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+ Vector v_port = parser.getValuesFromContainer(nodeList.item(i),
+ portType);
+ Vector v_admin_port = parser.getValuesFromContainer(nodeList.item(i),
+ "SecureAdminPort");
+
+ if (v_host.elementAt(0).equals(hostname) && v_admin_port.elementAt(0).equals(new Integer(httpsadminport).toString())) {
+ // add security domain CA to the beginning of list
+ v.add( 0, v_name.elementAt(0)
+ + " - https://"
+ + v_host.elementAt(0)
+ + ":"
+ + v_port.elementAt(0) );
+ } else {
+ v.addElement( v_name.elementAt(0)
+ + " - https://"
+ + v_host.elementAt(0)
+ + ":"
+ + v_port.elementAt(0) );
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+
+ return v;
+ }
+
+ // Given an HTTPS Hostname and EE port,
+ // retrieve the associated HTTPS Admin port
+ public String getSecurityDomainAdminPort( IConfigStore config,
+ String hostname,
+ String https_ee_port,
+ String cstype ) {
+ String https_admin_port = new String();
+
+ try {
+ String sd_hostname = config.getString( "securitydomain.host" );
+ int sd_httpsadminport =
+ config.getInteger( "securitydomain.httpsadminport" );
+
+ CMS.debug( "Getting domain.xml from CA ..." );
+ String c = getDomainXML( sd_hostname, sd_httpsadminport, true );
+
+ CMS.debug( "Getting associated HTTPS Admin port from " +
+ "HTTPS Hostname '" + hostname +
+ "' and EE port '" + https_ee_port + "'" );
+ ByteArrayInputStream bis = new ByteArrayInputStream( c.getBytes() );
+ XMLObject parser = new XMLObject( bis );
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName( cstype.toUpperCase() );
+
+ int len = nodeList.getLength();
+ for( int i = 0; i < len; i++ ) {
+ Vector v_hostname =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "Host" );
+
+ Vector v_https_ee_port =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "SecurePort" );
+
+ Vector v_https_admin_port =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "SecureAdminPort" );
+
+ if( v_hostname.elementAt( 0 ).equals( hostname ) &&
+ v_https_ee_port.elementAt( 0 ).equals( https_ee_port ) ) {
+ https_admin_port =
+ v_https_admin_port.elementAt( 0 ).toString();
+ break;
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug( e.toString() );
+ }
+
+ return( https_admin_port );
+ }
+
+ public String getSecurityDomainPort( IConfigStore config,
+ String portType ) {
+ String port = new String();
+
+ try {
+ String hostname = config.getString( "securitydomain.host" );
+ int httpsadminport =
+ config.getInteger( "securitydomain.httpsadminport" );
+
+ CMS.debug( "Getting domain.xml from CA ..." );
+ String c = getDomainXML( hostname, httpsadminport, true );
+
+ CMS.debug( "Getting " + portType + " from Security Domain ..." );
+ if( !portType.equals( "UnSecurePort" ) &&
+ !portType.equals( "SecureAgentPort" ) &&
+ !portType.equals( "SecurePort" ) &&
+ !portType.equals( "SecureAdminPort" ) ) {
+ CMS.debug( "getPortFromSecurityDomain: " +
+ "unknown port type " + portType );
+ return "";
+ }
+
+ ByteArrayInputStream bis = new ByteArrayInputStream( c.getBytes() );
+ XMLObject parser = new XMLObject( bis );
+ Document doc = parser.getDocument();
+ NodeList nodeList = doc.getElementsByTagName( "CA" );
+
+ int len = nodeList.getLength();
+ for( int i = 0; i < len; i++ ) {
+ Vector v_admin_port =
+ parser.getValuesFromContainer( nodeList.item(i),
+ "SecureAdminPort" );
+
+ Vector v_port = null;
+ if( portType.equals( "UnSecurePort" ) ) {
+ v_port = parser.getValuesFromContainer( nodeList.item(i),
+ "UnSecurePort" );
+ } else if( portType.equals( "SecureAgentPort" ) ) {
+ v_port = parser.getValuesFromContainer( nodeList.item(i),
+ "SecureAgentPort" );
+ } else if( portType.equals( "SecurePort" ) ) {
+ v_port = parser.getValuesFromContainer( nodeList.item(i),
+ "SecurePort" );
+ } else if( portType.equals( "SecureAdminPort" ) ) {
+ v_port = parser.getValuesFromContainer( nodeList.item(i),
+ "SecureAdminPort" );
+ }
+
+ if( ( v_port != null ) &&
+ ( v_admin_port.elementAt( 0 ).equals(
+ Integer.toString( httpsadminport ) ) ) ) {
+ port = v_port.elementAt( 0 ).toString();
+ break;
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug( e.toString() );
+ }
+
+ return( port );
+ }
+
+ public String pingCS( String hostname, int port, boolean https,
+ SSLCertificateApprovalCallback certApprovalCallback )
+ throws IOException {
+ CMS.debug( "WizardPanelBase pingCS: started" );
+
+ String c = getHttpResponse( hostname, port, https,
+ "/ca/admin/ca/getStatus",
+ null, null, certApprovalCallback );
+
+ if( c != null ) {
+ try {
+ ByteArrayInputStream bis = new
+ ByteArrayInputStream( c.getBytes() );
+ XMLObject parser = null;
+ String state = null;
+
+ try {
+ parser = new XMLObject( bis );
+ CMS.debug( "WizardPanelBase pingCS: got XML parsed" );
+ state = parser.getValue( "State" );
+
+ if( state != null ) {
+ CMS.debug( "WizardPanelBase pingCS: state=" + state );
+ }
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase: pingCS: parser failed"
+ + e.toString() );
+ }
+
+ return state;
+ } catch( Exception e ) {
+ CMS.debug( "WizardPanelBase: pingCS: " + e.toString() );
+ throw new IOException( e.toString() );
+ }
+ }
+
+ CMS.debug( "WizardPanelBase pingCS: stopped" );
+ return null;
+ }
+
+ public String toLowerCaseSubsystemType(String s) {
+ String x = null;
+ if (s.equals("CA")) {
+ x = "ca";
+ } else if (s.equals("KRA")) {
+ x = "kra";
+ } else if (s.equals("OCSP")) {
+ x = "ocsp";
+ } else if (s.equals("TKS")) {
+ x = "tks";
+ }
+
+ return x;
+ }
+
+ public void getTokenInfo(IConfigStore config, String type, String host,
+ int https_ee_port, boolean https, Context context,
+ ConfigCertApprovalCallback certApprovalCallback) throws IOException {
+ CMS.debug("WizardPanelBase getTokenInfo start");
+ String uri = "/"+type+"/ee/"+type+"/getTokenInfo";
+ CMS.debug("WizardPanelBase getTokenInfo: uri="+uri);
+ String c = getHttpResponse(host, https_ee_port, https, uri, null, null,
+ certApprovalCallback);
+ if (c != null) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
+ XMLObject parser = null;
+
+ try {
+ parser = new XMLObject(bis);
+ } catch (Exception e) {
+ CMS.debug( "WizardPanelBase::getTokenInfo() - "
+ + "Exception="+e.toString() );
+ throw new IOException( e.toString() );
+ }
+
+ String status = parser.getValue("Status");
+
+ CMS.debug("WizardPanelBase getTokenInfo: status=" + status);
+
+ if (status.equals(SUCCESS)) {
+ Document doc = parser.getDocument();
+ NodeList list = doc.getElementsByTagName("name");
+ int len = list.getLength();
+ for (int i=0; i<len; i++) {
+ Node n = list.item(i);
+ NodeList nn = n.getChildNodes();
+ String name = nn.item(0).getNodeValue();
+ Node parent = n.getParentNode();
+ nn = parent.getChildNodes();
+ int len1 = nn.getLength();
+ String v = "";
+ for (int j=0; j<len1; j++) {
+ Node nv = nn.item(j);
+ String val = nv.getNodeName();
+ if (val.equals("value")) {
+ NodeList n2 = nv.getChildNodes();
+ if (n2.getLength() > 0)
+ v = n2.item(0).getNodeValue();
+ break;
+ }
+ }
+ if (name.equals("cloning.signing.nickname")) {
+ config.putString("preop.master.signing.nickname", v);
+ config.putString(type + ".cert.signing.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.ocsp_signing.nickname")) {
+ config.putString("preop.master.ocsp_signing.nickname", v);
+ config.putString(type + ".cert.ocsp_signing.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.subsystem.nickname")) {
+ config.putString("preop.master.subsystem.nickname", v);
+ config.putString(type + ".cert.subsystem.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.transport.nickname")) {
+ config.putString("preop.master.transport.nickname", v);
+ config.putString("kra.transportUnit.nickName", v);
+ config.putString("kra.cert.transport.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.storage.nickname")) {
+ config.putString("preop.master.storage.nickname", v);
+ config.putString("kra.storageUnit.nickName", v);
+ config.putString("kra.cert.storage.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.audit_signing.nickname")) {
+ config.putString("preop.master.audit_signing.nickname", v);
+ config.putString(type + ".cert.audit_signing.nickname", v);
+ config.putString(name, v);
+ } else if (name.equals("cloning.module.token")) {
+ config.putString("preop.module.token", v);
+ } else if (name.startsWith("cloning.ca")) {
+ config.putString(name.replaceFirst("cloning", "preop"), v);
+ } else if (name.startsWith("cloning")) {
+ config.putString(name.replaceFirst("cloning", "preop.cert"), v);
+ } else {
+ config.putString(name, v);
+ }
+ }
+ } else {
+ String error = parser.getValue("Error");
+ throw new IOException(error);
+ }
+ } catch (IOException e) {
+ CMS.debug("WizardPanelBase: getTokenInfo: " + e.toString());
+ throw e;
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase: getTokenInfo: " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+ }
+
+ public void importCertChain(String id) throws IOException {
+ CMS.debug("DisplayCertChainPanel importCertChain");
+ IConfigStore config = CMS.getConfigStore();
+ String configName = "preop." + id + ".pkcs7";
+ String pkcs7 = "";
+
+ try {
+ pkcs7 = config.getString(configName, "");
+ } catch (Exception e) {}
+
+ if (pkcs7.length() > 0) {
+ try {
+ CryptoUtil.importCertificateChain(pkcs7);
+ } catch (Exception e) {
+ CMS.debug("DisplayCertChainPanel importCertChain: Exception: "+e.toString());
+ }
+ }
+ }
+
+ public void updateCertChain(IConfigStore config, String name, String host,
+ int https_admin_port, boolean https, Context context) throws IOException {
+ updateCertChain( config, name, host, https_admin_port,
+ https, context, null );
+ }
+
+ public void updateCertChain(IConfigStore config, String name, String host,
+ int https_admin_port, boolean https, Context context,
+ ConfigCertApprovalCallback certApprovalCallback) throws IOException {
+ String certchain = getCertChainUsingSecureAdminPort( host,
+ https_admin_port,
+ https,
+ certApprovalCallback );
+ config.putString("preop."+name+".pkcs7", certchain);
+
+ byte[] decoded = CryptoUtil.base64Decode(certchain);
+ java.security.cert.X509Certificate[] b_certchain = null;
+
+ try {
+ b_certchain = CryptoUtil.getX509CertificateFromPKCS7(decoded);
+ } catch (Exception e) {
+ context.put("errorString",
+ "Failed to get the certificate chain.");
+ return;
+ }
+
+ int size = 0;
+ if (b_certchain != null) {
+ size = b_certchain.length;
+ }
+ config.putInteger("preop."+name+".certchain.size", size);
+ for (int i = 0; i < size; i++) {
+ byte[] bb = null;
+
+ try {
+ bb = b_certchain[i].getEncoded();
+ } catch (Exception e) {
+ context.put("errorString",
+ "Failed to get the der-encoded certificate chain.");
+ return;
+ }
+ config.putString("preop."+name+".certchain." + i,
+ CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bb)));
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public void updateCertChainUsingSecureEEPort( IConfigStore config,
+ String name, String host,
+ int https_ee_port,
+ boolean https,
+ Context context,
+ ConfigCertApprovalCallback certApprovalCallback ) throws IOException {
+ String certchain = getCertChainUsingSecureEEPort( host, https_ee_port,
+ https,
+ certApprovalCallback);
+ config.putString("preop."+name+".pkcs7", certchain);
+
+ byte[] decoded = CryptoUtil.base64Decode(certchain);
+ java.security.cert.X509Certificate[] b_certchain = null;
+
+ try {
+ b_certchain = CryptoUtil.getX509CertificateFromPKCS7(decoded);
+ } catch (Exception e) {
+ context.put("errorString",
+ "Failed to get the certificate chain.");
+ return;
+ }
+
+ int size = 0;
+ if (b_certchain != null) {
+ size = b_certchain.length;
+ }
+ config.putInteger("preop."+name+".certchain.size", size);
+ for (int i = 0; i < size; i++) {
+ byte[] bb = null;
+
+ try {
+ bb = b_certchain[i].getEncoded();
+ } catch (Exception e) {
+ context.put("errorString",
+ "Failed to get the der-encoded certificate chain.");
+ return;
+ }
+ config.putString("preop."+name+".certchain." + i,
+ CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bb)));
+ }
+
+ try {
+ config.commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public void deleteCert(String tokenname, String nickname) {
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken tok = cm.getTokenByName(tokenname);
+ CryptoStore store = tok.getCryptoStore();
+ String fullnickname = nickname;
+ if (!tokenname.equals("") &&
+ !tokenname.equals("Internal Key Storage Token") &&
+ !tokenname.equals("internal"))
+ fullnickname = tokenname+":"+nickname;
+
+ CMS.debug("WizardPanelBase deleteCert: nickname="+fullnickname);
+ org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(fullnickname);
+
+ if (store instanceof PK11Store) {
+ CMS.debug("WizardPanelBase deleteCert: this is pk11store");
+ PK11Store pk11store = (PK11Store)store;
+ pk11store.deleteCertOnly(cert);
+ CMS.debug("WizardPanelBase deleteCert: cert deleted successfully");
+ }
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase deleteCert: Exception="+e.toString());
+ }
+ }
+
+ public void deleteEntries(LDAPSearchResults res, LDAPConnection conn,
+ String dn, String[] entries) {
+ String[] attrs = null;
+ LDAPSearchConstraints cons = null;
+ String filter = "objectclass=*";
+
+ try {
+ if (res.getCount() == 0)
+ return;
+ else {
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = res.next();
+ String dn1 = entry.getDN();
+ LDAPSearchResults res1 = conn.search(dn1, 1, filter, attrs, true, cons);
+ deleteEntries(res1, conn, dn1, entries);
+ deleteEntry(conn, dn1, entries);
+ }
+ }
+ } catch (Exception ee) {
+ CMS.debug("WizardPanelBase deleteEntries: Exception="+ee.toString());
+ }
+ }
+
+ public void deleteEntry(LDAPConnection conn, String dn, String[] entries) {
+ try {
+ for (int i=0; i<entries.length; i++) {
+ if (LDAPDN.equals(dn, entries[i])) {
+ CMS.debug("WizardPanelBase deleteEntry: entry with this dn "+dn+" is not deleted.");
+ return;
+ }
+ }
+
+ CMS.debug("WizardPanelBase deleteEntry: deleting dn="+dn);
+ conn.delete(dn);
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase deleteEntry: Exception="+e.toString());
+ }
+ }
+
+ public void reloginSecurityDomain(HttpServletResponse response) {
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ String hostname = cs.getString("securitydomain.host", "");
+ int port = cs.getInteger("securitydomain.httpsadminport", -1);
+ String cs_hostname = cs.getString("machineName", "");
+ int cs_port = cs.getInteger("pkicreate.admin_secure_port", -1);
+ int panel = getPanelNo();
+ String subsystem = cs.getString("cs.type", "");
+ String urlVal = "https://"+cs_hostname+":"+cs_port+"/"+toLowerCaseSubsystemType(subsystem)+"/admin/console/config/wizard?p="+panel+"&subsystem="+subsystem;
+ String encodedValue = URLEncoder.encode(urlVal, "UTF-8");
+ String sdurl = "https://"+hostname+":"+port+"/ca/admin/ca/securityDomainLogin?url="+encodedValue;
+ response.sendRedirect(sdurl);
+ } catch (Exception e) {
+ CMS.debug("WizardPanelBase reloginSecurityDomain: Exception="+e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java b/pki/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java
new file mode 100644
index 000000000..75e02a24b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java
@@ -0,0 +1,131 @@
+// --- 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) 2009 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.http.*;
+import javax.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+public class AdminRequestFilter implements Filter
+{
+ private static final String HTTPS_SCHEME = "https";
+ private static final String HTTPS_PORT = "https_port";
+ private static final String HTTPS_ROLE = "Admin";
+ private static final String PROXY_PORT = "proxy_port";
+
+ private FilterConfig config;
+
+ /* Create a new AdminRequestFilter */
+ public AdminRequestFilter() {}
+
+ public void init( FilterConfig filterConfig )
+ throws ServletException
+ {
+ this.config = filterConfig;
+ }
+
+ public void doFilter( ServletRequest request,
+ ServletResponse response,
+ FilterChain chain )
+ throws java.io.IOException,
+ ServletException
+ {
+ String filterName = getClass().getName();
+
+ String scheme = null;
+ int port = 0;
+
+ String request_port = null;
+ String param_https_port = null;
+ String param_proxy_port = null;
+ String msg = null;
+ String param_active = null;
+
+ // CMS.debug("Entering the admin filter");
+ param_active = config.getInitParameter( "active");
+
+ if( request instanceof HttpServletRequest ) {
+ HttpServletResponse resp = ( HttpServletResponse ) response;
+
+ // RFC 1738: verify that scheme is "https"
+ scheme = request.getScheme();
+ if( ! scheme.equals( HTTPS_SCHEME ) ) {
+ msg = "The scheme MUST be '" + HTTPS_SCHEME
+ + "', NOT '" + scheme + "'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_UNAUTHORIZED, msg );
+ return;
+ }
+
+ // Always obtain an "https" port from request
+ port = request.getLocalPort();
+ request_port = Integer.toString( port );
+
+ // Always obtain the "https" port passed in as a parameter
+ param_https_port = config.getInitParameter( HTTPS_PORT );
+ if( param_https_port == null ) {
+ msg = "The <param-name> '" + HTTPS_PORT
+ + "' </param-name> " + "MUST be specified in 'web.xml'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, msg );
+ return;
+ }
+
+ param_proxy_port = config.getInitParameter(PROXY_PORT);
+ boolean bad_port = false;
+
+ // Compare the request and param "https" ports
+ if( ! param_https_port.equals( request_port ) ) {
+ String uri = ((HttpServletRequest) request).getRequestURI();
+ if (param_proxy_port != null) {
+ if (!param_proxy_port.equals(request_port)) {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' or proxy port '" + param_proxy_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ } else {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ if (bad_port) {
+ CMS.debug( filterName + ": " + msg );
+ CMS.debug( filterName + ": uri is " + uri);
+ if ((param_active != null) &&(param_active.equals("false"))) {
+ CMS.debug("Filter is disabled .. continuing");
+ } else {
+ resp.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
+ return;
+ }
+ }
+ }
+ }
+
+ // CMS.debug("Exiting the admin filter");
+
+ chain.doFilter( request, response );
+ }
+
+ public void destroy()
+ {
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java b/pki/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java
new file mode 100644
index 000000000..da16dc01d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java
@@ -0,0 +1,131 @@
+// --- 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) 2009 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.http.*;
+import javax.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+public class AgentRequestFilter implements Filter
+{
+ private static final String HTTPS_SCHEME = "https";
+ private static final String HTTPS_PORT = "https_port";
+ private static final String HTTPS_ROLE = "Agent";
+ private static final String PROXY_PORT = "proxy_port";
+
+ private FilterConfig config;
+
+ /* Create a new AgentRequestFilter */
+ public AgentRequestFilter() {}
+
+ public void init( FilterConfig filterConfig )
+ throws ServletException
+ {
+ this.config = filterConfig;
+ }
+
+ public void doFilter( ServletRequest request,
+ ServletResponse response,
+ FilterChain chain )
+ throws java.io.IOException,
+ ServletException
+ {
+ String filterName = getClass().getName();
+
+ String scheme = null;
+ int port = 0;
+
+ String request_port = null;
+ String param_https_port = null;
+ String param_proxy_port = null;
+ String msg = null;
+
+ String param_active = null;
+
+ // CMS.debug("Entering the agent filter");
+ param_active = config.getInitParameter( "active");
+
+ if( request instanceof HttpServletRequest ) {
+ HttpServletResponse resp = ( HttpServletResponse ) response;
+
+ // RFC 1738: verify that scheme is "https"
+ scheme = request.getScheme();
+ if( ! scheme.equals( HTTPS_SCHEME ) ) {
+ msg = "The scheme MUST be '" + HTTPS_SCHEME
+ + "', NOT '" + scheme + "'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_UNAUTHORIZED, msg );
+ return;
+ }
+
+ // Always obtain an "https" port from request
+ port = request.getLocalPort();
+ request_port = Integer.toString( port );
+
+ // Always obtain the "https" port passed in as a parameter
+ param_https_port = config.getInitParameter( HTTPS_PORT );
+ if( param_https_port == null ) {
+ msg = "The <param-name> '" + HTTPS_PORT
+ + "' </param-name> " + "MUST be specified in 'web.xml'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, msg );
+ return;
+ }
+
+ param_proxy_port = config.getInitParameter(PROXY_PORT);
+ boolean bad_port = false;
+
+ // Compare the request and param "https" ports
+ if( ! param_https_port.equals( request_port ) ) {
+ String uri = ((HttpServletRequest) request).getRequestURI();
+ if (param_proxy_port != null) {
+ if (!param_proxy_port.equals(request_port)) {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' or proxy port '" + param_proxy_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ } else {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ if (bad_port) {
+ CMS.debug( filterName + ": " + msg );
+ CMS.debug( filterName + ": uri is " + uri);
+ if ((param_active != null) &&(param_active.equals("false"))) {
+ CMS.debug("Filter is disabled .. continuing");
+ } else {
+ resp.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
+ return;
+ }
+ }
+ }
+ }
+ // CMS.debug("Exiting the Agent filter");
+
+ chain.doFilter( request, response );
+ }
+
+ public void destroy()
+ {
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java b/pki/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java
new file mode 100644
index 000000000..3c11dbd55
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java
@@ -0,0 +1,130 @@
+// --- 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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.http.*;
+import javax.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+public class EEClientAuthRequestFilter implements Filter
+{
+ private static final String HTTPS_SCHEME = "https";
+ private static final String HTTPS_PORT = "https_port";
+ private static final String HTTPS_ROLE = "EE Client Auth";
+ private static final String PROXY_PORT = "proxy_port";
+
+ private FilterConfig config;
+
+ /* Create a new EEClientAuthRequestFilter */
+ public EEClientAuthRequestFilter() {}
+
+ public void init( FilterConfig filterConfig )
+ throws ServletException
+ {
+ this.config = filterConfig;
+ }
+
+ public void doFilter( ServletRequest request,
+ ServletResponse response,
+ FilterChain chain )
+ throws java.io.IOException,
+ ServletException
+ {
+ String filterName = getClass().getName();
+
+ String scheme = null;
+ int port = 0;
+
+ String request_port = null;
+ String param_https_port = null;
+ String msg = null;
+ String param_active = null;
+ String param_proxy_port = null;
+
+ // CMS.debug("Entering the EECA filter");
+ param_active = config.getInitParameter( "active");
+
+ if( request instanceof HttpServletRequest ) {
+ HttpServletResponse resp = ( HttpServletResponse ) response;
+
+ // RFC 1738: verify that scheme is "https"
+ scheme = request.getScheme();
+ if( ! scheme.equals( HTTPS_SCHEME ) ) {
+ msg = "The scheme MUST be '" + HTTPS_SCHEME
+ + "', NOT '" + scheme + "'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_UNAUTHORIZED, msg );
+ return;
+ }
+
+ // Always obtain an "https" port from request
+ port = request.getLocalPort();
+ request_port = Integer.toString( port );
+
+ // Always obtain the "https" port passed in as a parameter
+ param_https_port = config.getInitParameter( HTTPS_PORT );
+ if( param_https_port == null ) {
+ msg = "The <param-name> '" + HTTPS_PORT
+ + "' </param-name> " + "MUST be specified in 'web.xml'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, msg );
+ return;
+ }
+
+ param_proxy_port = config.getInitParameter(PROXY_PORT);
+ boolean bad_port = false;
+
+ // Compare the request and param "https" ports
+ if( ! param_https_port.equals( request_port ) ) {
+ String uri = ((HttpServletRequest) request).getRequestURI();
+ if (param_proxy_port != null) {
+ if (!param_proxy_port.equals(request_port)) {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' or proxy port '" + param_proxy_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ } else {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ if (bad_port) {
+ CMS.debug( filterName + ": " + msg );
+ CMS.debug( filterName + ": uri is " + uri);
+ if ((param_active != null) &&(param_active.equals("false"))) {
+ CMS.debug("Filter is disabled .. continuing");
+ } else {
+ resp.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
+ return;
+ }
+ }
+ }
+ }
+ // CMS.debug("exiting the EECA filter");
+
+ chain.doFilter( request, response );
+ }
+
+ public void destroy()
+ {
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java b/pki/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java
new file mode 100644
index 000000000..69634506e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java
@@ -0,0 +1,183 @@
+// --- 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) 2009 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.http.*;
+import javax.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+public class EERequestFilter implements Filter
+{
+ private static final String HTTP_SCHEME = "http";
+ private static final String HTTP_PORT = "http_port";
+ private static final String HTTP_ROLE = "EE";
+ private static final String HTTPS_SCHEME = "https";
+ private static final String HTTPS_PORT = "https_port";
+ private static final String HTTPS_ROLE = "EE";
+ private static final String PROXY_PORT = "proxy_port";
+ private static final String PROXY_HTTP_PORT = "proxy_http_port";
+
+ private FilterConfig config;
+
+ /* Create a new EERequestFilter */
+ public EERequestFilter() {}
+
+ public void init( FilterConfig filterConfig )
+ throws ServletException
+ {
+ this.config = filterConfig;
+ }
+
+ public void doFilter( ServletRequest request,
+ ServletResponse response,
+ FilterChain chain )
+ throws java.io.IOException,
+ ServletException
+ {
+ String filterName = getClass().getName();
+
+ String scheme = null;
+ int port = 0;
+
+ String request_port = null;
+ String param_http_port = null;
+ String param_https_port = null;
+ String param_proxy_port = null;
+ String param_proxy_http_port = null;
+ String msg = null;
+ String param_active = null;
+
+ // CMS.debug("Entering the EE filter");
+ param_active = config.getInitParameter( "active");
+
+ if( request instanceof HttpServletRequest ) {
+ HttpServletResponse resp = ( HttpServletResponse ) response;
+
+ // RFC 1738: verify that scheme is either "http" or "https"
+ scheme = request.getScheme();
+ if( ( ! scheme.equals( HTTP_SCHEME ) ) &&
+ ( ! scheme.equals( HTTPS_SCHEME ) ) ) {
+ msg = "The scheme MUST be either '" + HTTP_SCHEME
+ + "' or '" + HTTPS_SCHEME
+ + "', NOT '" + scheme + "'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_UNAUTHORIZED, msg );
+ return;
+ }
+
+ // Always obtain either an "http" or an "https" port from request
+ port = request.getLocalPort();
+ request_port = Integer.toString( port );
+
+ // Always obtain the "http" port passed in as a parameter
+ param_http_port = config.getInitParameter( HTTP_PORT );
+ if( param_http_port == null ) {
+ msg = "The <param-name> '" + HTTP_PORT
+ + "' </param-name> " + "MUST be specified in 'web.xml'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, msg );
+ return;
+ }
+
+ // Always obtain the "https" port passed in as a parameter
+ param_https_port = config.getInitParameter( HTTPS_PORT );
+ if( param_https_port == null ) {
+ msg = "The <param-name> '" + HTTPS_PORT
+ + "' </param-name> " + "MUST be specified in 'web.xml'!";
+ CMS.debug( filterName + ": " + msg );
+ resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, msg );
+ return;
+ }
+
+ param_proxy_http_port = config.getInitParameter(PROXY_HTTP_PORT);
+ param_proxy_port = config.getInitParameter(PROXY_PORT);
+ boolean bad_port = false;
+
+ // If the scheme is "http", compare
+ // the request and param "http" ports;
+ // otherwise, if the scheme is "https", compare
+ // the request and param "https" ports
+ if( scheme.equals( HTTP_SCHEME ) ) {
+ if( ! param_http_port.equals( request_port ) ) {
+ String uri = ((HttpServletRequest) request).getRequestURI();
+ if (param_proxy_http_port != null) {
+ if (!param_proxy_http_port.equals(request_port)) {
+ msg = "Use HTTP port '" + param_http_port
+ + "' or proxy port '" + param_proxy_http_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTP_ROLE + " tasks!";
+ bad_port = true;
+ }
+ } else {
+ msg = "Use HTTP port '" + param_http_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTP_ROLE + " tasks!";
+ bad_port = true;
+ }
+ if (bad_port) {
+ CMS.debug( filterName + ": " + msg );
+ CMS.debug( filterName + ": uri is " + uri);
+ if ((param_active != null) &&(param_active.equals("false"))) {
+ CMS.debug("Filter is disabled .. continuing");
+ } else {
+ resp.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
+ return;
+ }
+ }
+ }
+ } else if( scheme.equals( HTTPS_SCHEME ) ) {
+ if( ! param_https_port.equals( request_port ) ) {
+ String uri = ((HttpServletRequest) request).getRequestURI();
+ if (param_proxy_port != null) {
+ if (!param_proxy_port.equals(request_port)) {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' or proxy port '" + param_proxy_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ } else {
+ msg = "Use HTTPS port '" + param_https_port
+ + "' instead of '" + request_port
+ + "' when performing " + HTTPS_ROLE + " tasks!";
+ bad_port = true;
+ }
+ if (bad_port) {
+ CMS.debug( filterName + ": " + msg );
+ CMS.debug( filterName + ": uri is " + uri);
+ if ((param_active != null) &&(param_active.equals("false"))) {
+ CMS.debug("Filter is disabled .. continuing");
+ } else {
+ resp.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
+ return;
+ }
+ }
+ }
+ }
+
+ }
+ // CMS.debug("Exiting the EE filter");
+
+ chain.doFilter( request, response );
+ }
+
+ public void destroy()
+ {
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java
new file mode 100644
index 000000000..1fe0e2f11
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java
@@ -0,0 +1,189 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+
+
+/**
+ * A class representing a recoverKey servlet. This servlet
+ * shows key information and presents a list of text boxes
+ * so that recovery agents can type in their identifiers
+ * and passwords.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConfirmRecoverBySerial extends CMSServlet {
+
+ private final static String INFO = "recoverBySerial";
+ private final static String TPL_FILE =
+ "confirmRecoverBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_M = "noOfRequiredAgents";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private IKeyService mRecoveryService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs ConfirmRecoverBySerial servlet.
+ */
+ public ConfirmRecoverBySerial() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mRecoveryService = (IKeyService) mAuthority;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is
+ * as follows:
+ * confirmRecoverBySerial?
+ * [serialNumber=<serialno>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ int seqNum = -1;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = Integer.parseInt(
+ req.getParameter(IN_SERIALNO));
+ }
+
+ // make sure this page, which contains password
+ // information, is not cache. Too bad, this is
+ // only good for NS browser, not IE specifically.
+ resp.setHeader("pragma", "no-cache");
+
+ process(argSet, header, seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Requests for a list of agent passwords.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, int seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addIntegerValue(OUT_SERIALNO, seq);
+ header.addIntegerValue(OUT_M,
+ mRecoveryService.getNoOfRequiredAgents());
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(new BigInteger(
+ Integer.toString(seq)));
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java
new file mode 100644
index 000000000..fc1d9e8f4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java
@@ -0,0 +1,194 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Display a specific Key Archival Request
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerial extends CMSServlet {
+
+ private final static String INFO = "displayBySerial";
+ private final static String TPL_FILE = "displayBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs displayBySerial servlet.
+ */
+ public DisplayBySerial() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "displayBySerial.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber serial number of the key archival request
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int seqNum = -1;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = Integer.parseInt(
+ req.getParameter(IN_SERIALNO));
+ }
+ process(argSet, header, seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Display information about a particular key.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, int seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(new
+ BigInteger(Integer.toString(seq)));
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
new file mode 100644
index 000000000..dcc687597
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
@@ -0,0 +1,212 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Display a Specific Key Archival Request, and initiate
+ * key recovery process
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerialForRecovery extends CMSServlet {
+
+ private final static String INFO = "displayBySerial";
+ private final static String TPL_FILE = "displayBySerialForRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private String mFormPath = null;
+ private IKeyService mService = null;
+
+ /**
+ * Constructor
+ */
+ public DisplayBySerialForRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "displayBySerialForRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber request ID of key archival request
+ * <li>http.param publicKeyData
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ int seqNum = -1;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = Integer.parseInt(
+ req.getParameter(IN_SERIALNO));
+ }
+ process(argSet, header,
+ req.getParameter("publicKeyData"),
+ seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println(e.toString());
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Display information about a particular key.
+ */
+ private synchronized void process(CMSTemplateParams argSet,
+ IArgBlock header, String publicKeyData, int seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addIntegerValue("noOfRequiredAgents",
+ mService.getNoOfRequiredAgents());
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue("keySplitting",
+ CMS.getConfigStore().getString("kra.keySplitting"));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ if (publicKeyData != null) {
+ header.addStringValue("publicKeyData",
+ publicKeyData);
+ }
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(new
+ BigInteger(Integer.toString(seq)));
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+
+ // recovery identifier
+ header.addStringValue("recoveryID", mService.getRecoveryID());
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java
new file mode 100644
index 000000000..e52bb44ed
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java
@@ -0,0 +1,135 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cms.servlet.common.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve Transport Certificate used to
+ * wrap Private key Archival requests
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayTransport extends CMSServlet {
+
+ private final static String INFO = "displayTransport";
+
+ /**
+ * Constructs displayTransport servlet.
+ */
+ public DisplayTransport() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ try {
+ IKeyRecoveryAuthority kra =
+ (IKeyRecoveryAuthority) mAuthority;
+ ITransportKeyUnit tu = kra.getTransportKeyUnit();
+ org.mozilla.jss.crypto.X509Certificate transportCert =
+ tu.getCertificate();
+
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/html");
+ String content = "";
+
+ content += "<HTML><PRE>";
+ String mime64 =
+ "-----BEGIN CERTIFICATE-----\n" +
+ CMS.BtoA(transportCert.getEncoded()) +
+ "-----END CERTIFICATE-----\n";
+
+ content += mime64;
+ content += "</PRE></HTML>";
+ resp.setContentType("text/html");
+ resp.getOutputStream().write(content.getBytes());
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java
new file mode 100644
index 000000000..4d4607ba1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java
@@ -0,0 +1,251 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * View the Key Recovery Request
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExamineRecovery extends CMSServlet {
+
+ private final static String INFO = "examineRecovery";
+ private final static String TPL_FILE = "examineRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs EA servlet.
+ */
+ public ExamineRecovery() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mService = (IKeyService) mAuthority;
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID recovery request ID
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int seq = -1;
+
+ EBaseException error = null;
+
+ try {
+ process(argSet, header,
+ req.getParameter("recoveryID"),
+ req, resp, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ } catch (Exception e) {
+ error = new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ /*
+ catch (NumberFormatException e) {
+ error = eBaseException(
+
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ locale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+
+ try {
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ ServletOutputStream out = resp.getOutputStream();
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String recoveryID,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ header.addStringValue("keySplitting",
+ CMS.getConfigStore().getString("kra.keySplitting"));
+ Hashtable params = mService.getRecoveryParams(
+ recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+ String keyID = (String)params.get("keyID");
+ header.addStringValue("serialNumber", keyID);
+ header.addStringValue("recoveryID", recoveryID);
+
+ IKeyRepository mKeyDB =
+ ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(new
+ BigInteger(keyID));
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+
+
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error e " + e);
+ throw e;
+ }
+
+ /*
+ catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ */
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java
new file mode 100644
index 000000000..36d991937
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java
@@ -0,0 +1,238 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Check to see if a Key Recovery Request has been approved
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetApprovalStatus extends CMSServlet {
+
+ private final static String INFO = "getApprovalStatus";
+ private final static String TPL_FILE = "getApprovalStatus.template";
+ private final static String TPL_FINISH = "finishRecovery.template";
+
+ private final static String IN_DELIVERY = "p12Delivery";
+
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_STATUS = "status";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs getApprovalStatus servlet.
+ */
+ public GetApprovalStatus() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template files
+ * "getApprovalStatus.template" and "finishRecovery.template"
+ * to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // mFormPath = "/"+authority.getId()+"/"+TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID request ID to check
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int seq = -1;
+ int rComplete = 0;
+
+ // get status and populate argSet
+ try {
+ String recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable params = mService.getRecoveryParams(recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+ header.addStringValue("serialNumber",
+ (String) params.get("keyID"));
+
+ int requiredNumber = mService.getNoOfRequiredAgents();
+
+ header.addIntegerValue("noOfRequiredAgents", requiredNumber);
+
+ Vector dc = ((IKeyRecoveryAuthority) mService).getAppAgents(recoveryID);
+ Enumeration agents = dc.elements();
+
+ while (agents.hasMoreElements()) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("agentName", ((Credential) agents.nextElement()).getIdentifier());
+ argSet.addRepeatRecord(rarg);
+ }
+ if (dc.size() >= requiredNumber) {
+ // got all approval, return pk12
+ byte pkcs12[] = ((IKeyRecoveryAuthority) mService).getPk12(recoveryID);
+
+ if (pkcs12 != null) {
+ rComplete = 1;
+ header.addStringValue(OUT_STATUS, "complete");
+
+ /*
+ mService.destroyRecoveryParams(recoveryID);
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ locale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+ } else if (((IKeyRecoveryAuthority) mService).getError(recoveryID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(recoveryID));
+ rComplete = 1;
+ } else {
+ // pk12 hasn't been created yet.
+ }
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ rComplete = 1;
+ }
+
+ try {
+ if (rComplete == 1) {
+ mFormPath = "/" + ((IAuthority) mService).getId() + "/" + TPL_FINISH;
+ } else {
+ mFormPath = "/" + ((IAuthority) mService).getId() + "/" + TPL_FILE;
+ }
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java
new file mode 100644
index 000000000..eb510bf59
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java
@@ -0,0 +1,241 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Get the recovered key in PKCS#12 format
+ * - for asynchronous key recovery only
+ *
+ */
+public class GetAsyncPk12 extends CMSServlet {
+
+ private final static String INFO = "getAsyncPk12";
+
+ private final static String TPL_FILE = "finishAsyncRecovery.template";
+
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_PASSWORD_AGAIN = "p12PasswordAgain";
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private final static String OUT_STATUS = "status";
+
+ private String mFormPath = null;
+
+ /**
+ * Constructs getAsyncPk12 servlet.
+ */
+ public GetAsyncPk12() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "finishAsyncRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param reqID request id for recovery
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "download");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int seq = -1;
+
+ // get status and populate argSet
+ try {
+ String reqID = req.getParameter("reqID");
+ header.addStringValue("reqID", reqID);
+
+ // only the init DRM agent can get the pkcs12
+ SessionContext sContext = SessionContext.getContext();
+ String agent = null;
+
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ if (agent == null ) {
+ CMS.debug( "GetAsyncPk12::process() - agent is null!" );
+ throw new EBaseException( "agent is null" );
+ }
+
+ String initAgent = "undefined";
+ initAgent = mService.getInitAgentAsyncKeyRecovery(reqID);
+
+ if ((initAgent.equals("undefined")) || !agent.equals(initAgent)) {
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_INVALID_AGENT_ASYNC_3",
+ reqID, initAgent));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_AGENT_ASYNC",
+ reqID, initAgent));
+ }
+
+ // The async recovery request must be in "approved" state
+ // i.e. all required # of recovery agents approved
+ if (mService.isApprovedAsyncKeyRecovery(reqID) != true) {
+ CMS.debug("GetAsyncPk12::process() - # required recovery agents not met");
+ throw new EBaseException( "# required recovery agents not met" );
+ }
+
+ String password = req.getParameter(IN_PASSWORD);
+ String passwordAgain = req.getParameter(IN_PASSWORD_AGAIN);
+
+ if (password == null || password.equals("")) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not found");
+ throw new EBaseException( "PKCS12 password not found" );
+ }
+ if (passwordAgain == null || !passwordAgain.equals(password)) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not matched");
+ throw new EBaseException( "PKCS12 password not matched" );
+ }
+
+ // got all approval, return pk12
+ byte pkcs12[] = mService.doKeyRecovery(reqID, password);
+
+ if (pkcs12 != null) {
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ } else if (((IKeyRecoveryAuthority) mService).getError(reqID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(reqID));
+ } else {
+ // pk12 hasn't been created yet. Shouldn't get here
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java
new file mode 100644
index 000000000..cd43cc8eb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java
@@ -0,0 +1,235 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Get the recovered key in PKCS#12 format
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetPk12 extends CMSServlet {
+
+ private final static String INFO = "getPk12";
+
+ private final static String TPL_FILE = "finishRecovery.template";
+
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private final static String OUT_STATUS = "status";
+
+ private String mFormPath = null;
+
+ /**
+ * Constructs getPk12 servlet.
+ */
+ public GetPk12() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "finishRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID ID of request to recover
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "download");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int seq = -1;
+
+ // get status and populate argSet
+ try {
+ String recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable params = mService.getRecoveryParams(recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+
+ // only the init DRM agent can get the pkcs12
+ SessionContext sContext = SessionContext.getContext();
+ String agent = null;
+
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ if (agent == null ) {
+ CMS.debug( "GetPk12::process() - agent is null!" );
+ throw new EBaseException( "agent is null" );
+ }
+
+ String initAgent = (String) params.get("agent");
+
+ if (!agent.equals(initAgent)) {
+ log(ILogger.LL_SECURITY,
+
+ CMS.getLogMessage("CMSGW_INVALID_AGENT_3",
+ recoveryID,
+ initAgent));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_AGENT",
+ agent, initAgent, recoveryID));
+ }
+
+ header.addStringValue("serialNumber",
+ (String) params.get("keyID"));
+
+ // got all approval, return pk12
+ byte pkcs12[] = ((IKeyRecoveryAuthority) mService).getPk12(recoveryID);
+
+ if (pkcs12 != null) {
+ mService.destroyRecoveryParams(recoveryID);
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ } else if (((IKeyRecoveryAuthority) mService).getError(recoveryID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(recoveryID));
+ } else {
+ // pk12 hasn't been created yet. Shouldn't get here
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
new file mode 100644
index 000000000..dbb5356cc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
@@ -0,0 +1,288 @@
+// --- 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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key;
+
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Approve an asynchronous key recovery request
+ *
+ */
+public class GrantAsyncRecovery extends CMSServlet {
+
+ private final static String INFO = "grantAsyncRecovery";
+ private final static String TPL_FILE = "grantAsyncRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_REQ_ID = "reqID";
+ private final static String IN_UID = "uid";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN_4";
+
+ /**
+ * Constructs EA servlet.
+ */
+ public GrantAsyncRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'grantAsyncRecovery.template' to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param reqID request ID of the request to approve
+ * <li>http.param agentID User ID of the agent approving the request
+
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ CMS.debug("GrantAsyncRecovery: process() begins");
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "recover");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ int seq = -1;
+
+ String agentID = authToken.getInString("uid");
+ CMS.debug("GrantAsyncRecovery: process() agent uid=" + agentID);
+ CMS.debug("GrantAsyncRecovery: process() request id=" + req.getParameter("reqID"));
+ try {
+ process(argSet, header,
+ req.getParameter("reqID"),
+ agentID,
+ req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Update agent approval list
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN used
+ * whenever DRM agents login as recovery agents to approve key recovery
+ * requests
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param reqID string containing the recovery request ID
+ * @param agentID string containing the agent ID
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String reqID,
+ String agentID,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequestID = reqID;
+ String auditAgentID = agentID;
+
+ // "normalize" the "reqID"
+ if (auditRequestID != null) {
+ auditRequestID = auditRequestID.trim();
+
+ if (auditRequestID.equals("")) {
+ auditRequestID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditRequestID = ILogger.UNIDENTIFIED;
+ }
+
+ // "normalize" the "auditAgentID"
+ if (auditAgentID != null) {
+ auditAgentID = auditAgentID.trim();
+
+ if (auditAgentID.equals("")) {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ // update approving agent list
+ mService.addAgentAsyncKeyRecovery(reqID, agentID);
+
+ header.addStringValue("requestID", reqID);
+ header.addStringValue("agentID", agentID);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
new file mode 100644
index 000000000..8119e4e37
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
@@ -0,0 +1,315 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Approve a key recovery request
+ *
+ * @version $Revision$, $Date$
+ */
+public class GrantRecovery extends CMSServlet {
+
+ private final static String INFO = "grantRecovery";
+ private final static String TPL_FILE = "grantRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN_4";
+
+ /**
+ * Constructs EA servlet.
+ */
+ public GrantRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'grantRecovery.template' to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID ID of the request to approve
+ * <li>http.param agentID User ID of the agent approving the request
+ * <li>http.param agentPWD Password of the agent approving the request
+
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "recover");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ int seq = -1;
+
+ String agentID = authToken.getInString("uid");
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ agentID = req.getParameter("agentID");
+ }
+ try {
+ process(argSet, header,
+ req.getParameter("recoveryID"),
+ agentID,
+ req.getParameter("agentPWD"),
+ req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN used
+ * whenever DRM agents login as recovery agents to approve key recovery
+ * requests
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param recoveryID string containing the recovery ID
+ * @param agentID string containing the agent ID
+ * @param agentPWD string containing the agent password
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String recoveryID,
+ String agentID, String agentPWD,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRecoveryID = recoveryID;
+ String auditAgentID = agentID;
+
+ // "normalize" the "auditRecoveryID"
+ if (auditRecoveryID != null) {
+ auditRecoveryID = auditRecoveryID.trim();
+
+ if (auditRecoveryID.equals("")) {
+ auditRecoveryID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditRecoveryID = ILogger.UNIDENTIFIED;
+ }
+
+ // "normalize" the "auditAgentID"
+ if (auditAgentID != null) {
+ auditAgentID = auditAgentID.trim();
+
+ if (auditAgentID.equals("")) {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ Hashtable h = mService.getRecoveryParams(recoveryID);
+
+ if (h == null) {
+ header.addStringValue(OUT_ERROR,
+ "No such token found");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ return;
+ }
+ header.addStringValue("serialNumber",
+ (String) h.get("keyID"));
+
+ mService.addDistributedCredential(recoveryID, agentID, agentPWD);
+ header.addStringValue("agentID",
+ agentID);
+ header.addStringValue("recoveryID",
+ recoveryID);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java
new file mode 100644
index 000000000..709f34337
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java
@@ -0,0 +1,102 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+
+/**
+ * Output a 'pretty print' of a Key Archival record
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordParser {
+
+ public final static String OUT_STATE = "state";
+ public final static String OUT_OWNER_NAME = "ownerName";
+ public final static String OUT_SERIALNO = "serialNumber";
+ public final static String OUT_KEY_ALGORITHM = "keyAlgorithm";
+ public final static String OUT_PUBLIC_KEY = "publicKey";
+ public final static String OUT_KEY_LEN = "keyLength";
+ public final static String OUT_ARCHIVED_BY = "archivedBy";
+ public final static String OUT_ARCHIVED_ON = "archivedOn";
+ public final static String OUT_RECOVERED_BY = "recoveredBy";
+ public final static String OUT_RECOVERED_ON = "recoveredOn";
+
+
+ /**
+ * Fills key record into argument block.
+ */
+ public static void fillRecordIntoArg(IKeyRecord rec, IArgBlock rarg)
+ throws EBaseException {
+ if (rec == null)
+ return;
+ rarg.addStringValue(OUT_STATE,
+ rec.getState().toString());
+ rarg.addStringValue(OUT_OWNER_NAME,
+ rec.getOwnerName());
+ rarg.addIntegerValue(OUT_SERIALNO,
+ rec.getSerialNumber().intValue());
+ rarg.addStringValue(OUT_KEY_ALGORITHM,
+ rec.getAlgorithm());
+ // Possible Enhancement: sun's BASE64Encode is not
+ // fast. We may may to have our native implmenetation.
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+
+ rarg.addStringValue(OUT_PUBLIC_KEY,
+ pp.toHexString(rec.getPublicKeyData(), 0, 20));
+ Integer keySize = rec.getKeySize();
+
+ if (keySize == null) {
+ rarg.addIntegerValue(OUT_KEY_LEN, 512);
+ } else {
+ rarg.addIntegerValue(OUT_KEY_LEN, keySize.intValue());
+ }
+ rarg.addStringValue(OUT_ARCHIVED_BY,
+ rec.getArchivedBy());
+ rarg.addLongValue(OUT_ARCHIVED_ON,
+ rec.getCreateTime().getTime() / 1000);
+ Date dateOfRevocation[] = rec.getDateOfRevocation();
+
+ if (dateOfRevocation != null) {
+ rarg.addStringValue(OUT_RECOVERED_BY,
+ "null");
+ rarg.addStringValue(OUT_RECOVERED_ON,
+ "null");
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
new file mode 100644
index 000000000..b1b46807a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
@@ -0,0 +1,528 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cmsutil.util.Cert;
+import netscape.security.x509.X509CertImpl;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+/**
+ * A class representing a recoverBySerial servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RecoverBySerial extends CMSServlet {
+
+ private final static String INFO = "recoverBySerial";
+ private final static String TPL_FILE = "recoverBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_PASSWORD_AGAIN = "p12PasswordAgain";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+ private final static String IN_NICKNAME = "nickname";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private final static String SCHEME = "scheme";
+ private final static String HOST = "host";
+ private final static String PORT = "port";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs EA servlet.
+ */
+ public RecoverBySerial() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is as follows:
+ * recoverBySerial?
+ * [serialNumber=<number>]
+ * [uid#=<uid>]
+ * [pwd#=<password>]
+ * [localAgents=yes|null]
+ * [recoveryID=recoveryID]
+ * [pkcs12Password=<password of pkcs12>]
+ * [pkcs12PasswordAgain=<password of pkcs12>]
+ * [pkcs12Delivery=<delivery mechanism for pkcs12>]
+ * [cert=<encryption certificate>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "recover");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // set host name and port.
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String host = httpReq.getServerName();
+ int port = httpReq.getServerPort();
+ String scheme = httpReq.getScheme();
+
+ fixed.set(HOST, host);
+ fixed.set(PORT, Integer.valueOf(port));
+ fixed.set(SCHEME, scheme);
+
+ int seq = -1;
+
+ SessionContext ctx = null;
+
+ try {
+ String localAgents = req.getParameter("localAgents");
+ String initAsyncRecovery = req.getParameter("initAsyncRecovery");
+
+ // this information is needed within the server for
+ // various signed audit log messages to report
+ ctx = SessionContext.getContext();
+
+ /*
+ When Recovery is first initiated, if it is in asynch mode,
+ no pkcs#12 password is needed.
+ The initiating agent uid will be recorded in the recovery
+ request.
+ Later, as approving agents submit their approvals, they will
+ also be listed in the request.
+ */
+ if ((initAsyncRecovery != null) &&
+ initAsyncRecovery.equalsIgnoreCase("ON")) {
+ process(form, argSet, header,
+ req.getParameter(IN_SERIALNO),
+ req.getParameter(IN_CERT),
+ req, resp, locale[0]);
+
+ int requiredNumber = mService.getNoOfRequiredAgents();
+ header.addIntegerValue("noOfRequiredAgents", requiredNumber);
+ } else {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID != null && !recoveryID.equals("")) {
+ ctx.put(SessionContext.RECOVERY_ID,
+ req.getParameter("recoveryID"));
+ }
+ byte pkcs12[] = process(form, argSet, header,
+ req.getParameter(IN_SERIALNO),
+ req.getParameter("localAgents"),
+ req.getParameter(IN_PASSWORD),
+ req.getParameter(IN_PASSWORD_AGAIN),
+ req.getParameter(IN_CERT),
+ req.getParameter(IN_DELIVERY),
+ req.getParameter(IN_NICKNAME),
+ req, resp, locale[0]);
+
+ if (pkcs12 != null) {
+ //resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("application/x-pkcs12");
+ //resp.setContentLength(pkcs12.length);
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+ return;
+ }
+ }
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } finally {
+ ctx.releaseContext();
+ }
+
+ // return status page
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Async Key Recovery - request initiation
+ */
+ private void process(CMSTemplate form, CMSTemplateParams argSet,
+ IArgBlock header, String seq, String cert,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+
+ // seq is the key id
+ if (seq == null) {
+ header.addStringValue(OUT_ERROR, "sequence number not found");
+ return;
+ }
+ X509CertImpl x509cert = null;
+
+ if (cert == null) {
+ header.addStringValue(OUT_ERROR, "certificate not found");
+ return;
+ } else {
+ try {
+ x509cert = Cert.mapCert(cert);
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ }
+ if (x509cert == null) {
+ header.addStringValue(OUT_ERROR, "invalid X.509 certificate");
+ return;
+ }
+
+ SessionContext sContext = SessionContext.getContext();
+
+ try {
+ String reqID = mService.initAsyncKeyRecovery(
+ new BigInteger(seq), x509cert,
+ (String) sContext.get(SessionContext.USER_ID));
+ header.addStringValue(OUT_SERIALNO, req.getParameter(IN_SERIALNO));
+ header.addStringValue("requestID", reqID);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to recover key for key id " +
+ seq + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(seq, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ }
+ return;
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ */
+ private byte[] process(CMSTemplate form, CMSTemplateParams argSet,
+ IArgBlock header, String seq, String localAgents,
+ String password, String passwordAgain,
+ String cert, String delivery, String nickname,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ if (seq == null) {
+ header.addStringValue(OUT_ERROR, "sequence number not found");
+ return null;
+ }
+ if (password == null || password.equals("")) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not found");
+ return null;
+ }
+ if (passwordAgain == null || !passwordAgain.equals(password)) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not matched");
+ return null;
+ }
+ X509CertImpl x509cert = null;
+
+ if (cert == null) {
+ // perform recovery
+ header.addStringValue(OUT_ERROR, "certificate not found");
+ return null;
+ } else {
+ try {
+ x509cert = Cert.mapCert(cert);
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ }
+ if (x509cert == null) {
+ header.addStringValue(OUT_ERROR, "invalid X.509 certificate");
+ return null;
+ }
+ try {
+ Credential creds[] = null;
+
+ SessionContext sContext = SessionContext.getContext();
+ String agent = null;
+
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ if (localAgents == null) {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID == null || recoveryID.equals("")) {
+ header.addStringValue(OUT_ERROR, "No recovery ID specified");
+ return null;
+ }
+ Hashtable params = mService.createRecoveryParams(recoveryID);
+
+ params.put("keyID", req.getParameter(IN_SERIALNO));
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ params.put("agent", agent);
+
+ // new thread to wait for pk12
+ Thread waitThread = new WaitApprovalThread(recoveryID,
+ seq, password, x509cert, delivery, nickname,
+ SessionContext.getContext());
+
+ waitThread.start();
+ return null;
+ } else {
+ Vector v = new Vector();
+
+ for (int i = 0; i < mService.getNoOfRequiredAgents(); i++) {
+ String uid = req.getParameter(IN_UID + i);
+ String pwd = req.getParameter(IN_PWD + i);
+
+ if (uid != null && pwd != null && !uid.equals("") &&
+ !pwd.equals("")) {
+ v.addElement(new Credential(uid, pwd));
+ } else {
+ header.addStringValue(OUT_ERROR, "Uid(s) or password(s) are not provided");
+ return null;
+ }
+ }
+ if (v.size() != mService.getNoOfRequiredAgents()) {
+ header.addStringValue(OUT_ERROR, "Uid(s) or password(s) are not provided");
+ return null;
+ }
+ creds = new Credential[v.size()];
+ v.copyInto(creds);
+ }
+
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addIntegerValue(OUT_SERIALNO,
+ Integer.parseInt(seq));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ byte pkcs12[] = mService.doKeyRecovery(
+ new BigInteger(seq),
+ creds, password, x509cert,
+ delivery, nickname, agent);
+
+ return pkcs12;
+ } else {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID == null || recoveryID.equals("")) {
+ header.addStringValue(OUT_ERROR, "No recovery ID specified");
+ return null;
+ }
+ Hashtable params = mService.createRecoveryParams(recoveryID);
+
+ params.put("keyID", req.getParameter(IN_SERIALNO));
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ params.put("agent", agent);
+
+ // new thread to wait for pk12
+ Thread waitThread = new WaitApprovalThread(recoveryID,
+ seq, password, x509cert, delivery, nickname,
+ SessionContext.getContext());
+
+ waitThread.start();
+ return null;
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ return null;
+ }
+
+ /**
+ * Wait approval thread. Wait for recovery agents' approval
+ * exit when required number of approval received
+ */
+ final class WaitApprovalThread extends Thread {
+ String theRecoveryID = null;
+ String theSeq = null;
+ String thePassword = null;
+ X509CertImpl theCert = null;
+ String theDelivery = null;
+ String theNickname = null;
+ SessionContext theSc = null;
+
+ /**
+ * Wait approval thread constructor including thread name
+ */
+ public WaitApprovalThread(String recoveryID, String seq,
+ String password, X509CertImpl cert,
+ String delivery, String nickname, SessionContext sc) {
+ super();
+ super.setName("waitApproval." + recoveryID + "-" +
+ (Thread.activeCount() + 1));
+ theRecoveryID = recoveryID;
+ theSeq = seq;
+ thePassword = password;
+ theCert = cert;
+ theDelivery = delivery;
+ theNickname = nickname;
+ theSc = sc;
+ }
+
+ public void run() {
+ SessionContext.setContext(theSc);
+ Credential creds[] = null;
+
+ try {
+ creds = mService.getDistributedCredentials(theRecoveryID);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to get required approvals for recovery id " +
+ theRecoveryID + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(theRecoveryID, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ return;
+ }
+
+ SessionContext sContext = SessionContext.getContext();
+
+ try {
+ byte pkcs12[] = mService.doKeyRecovery(
+ new BigInteger(theSeq),
+ creds, thePassword, theCert,
+ theDelivery, theNickname,
+ (String) sContext.get(SessionContext.USER_ID));
+
+ ((IKeyRecoveryAuthority) mService).createPk12(theRecoveryID, pkcs12);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to recover key for recovery id " +
+ theRecoveryID + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(theRecoveryID, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ }
+ return;
+ }
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java
new file mode 100644
index 000000000..21e61ed7d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java
@@ -0,0 +1,293 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+/**
+ * Retrieve archived keys matching search criteria
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKey extends CMSServlet {
+
+ private final static String TPL_FILE = "srchKey.template";
+ private final static String INFO = "srchKey";
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ // input parameters
+ private final static String IN_MAXCOUNT = "maxCount";
+ private final static String IN_FILTER = "queryFilter";
+ private final static String IN_SENTINEL = "querySentinel";
+
+ // output parameters
+ private final static String OUT_FILTER = IN_FILTER;
+ private final static String OUT_MAXCOUNT = IN_MAXCOUNT;
+ private final static String OUT_SENTINEL = IN_SENTINEL;
+ private final static String OUT_OP = "op";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_ARCHIVER = "archiverName";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_TOTAL_COUNT = "totalRecordCount";
+ private final static String OUT_TEMPLATE = "templateName";
+
+ private IKeyRepository mKeyDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = 100;
+ private int mTimeLimits = 30; /* in seconds */
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchKey() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "srchKey.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ /* maxReturns doesn't seem to do anything useful in this
+ servlet!!! */
+ try {
+ String tmp =
+ sc.getInitParameter(PROP_MAX_SEARCH_RETURNS);
+
+ if (tmp == null)
+ mMaxReturns = 100;
+ else
+ mMaxReturns = Integer.parseInt(tmp);
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mAuthName = ((IKeyRecoveryAuthority) mAuthority).getX500Name();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ /* Server-Side time limit */
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param maxCount maximum number of matches to show in result
+ * <li>http.param maxResults maximum number of matches to run in ldapsearch
+ * <li>http.param queryFilter ldap-style filter to search with
+ * <li>http.param querySentinel ID of first request to show
+ * <li>http.param timeLimit number of seconds to limit ldap search to
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ // process query if authentication is successful
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ int maxCount = -1;
+ int sentinel = 0;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ try {
+ if (req.getParameter(IN_MAXCOUNT) != null) {
+ maxCount = Integer.parseInt(
+ req.getParameter(IN_MAXCOUNT));
+ }
+ if (req.getParameter(IN_SENTINEL) != null) {
+ sentinel = Integer.parseInt(
+ req.getParameter(IN_SENTINEL));
+ }
+ String maxResultsStr = req.getParameter("maxResults");
+
+ if (maxResultsStr != null && maxResultsStr.length() > 0)
+ maxResults = Integer.parseInt(maxResultsStr);
+ String timeLimitStr = req.getParameter("timeLimit");
+
+ if (timeLimitStr != null && timeLimitStr.length() > 0)
+ timeLimit = Integer.parseInt(timeLimitStr);
+ process(argSet, header, ctx, maxCount, maxResults,
+ timeLimit, sentinel,
+ req.getParameter(IN_FILTER), req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, IArgBlock ctx,
+ int maxCount, int maxResults, int timeLimit, int sentinel, String filter,
+ HttpServletRequest req, HttpServletResponse resp, Locale locale) {
+
+ try {
+ // Fill header
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_ARCHIVER,
+ mAuthName.toString());
+ // STRANGE: IE does not like the following:
+ // header.addStringValue(OUT_SERVICE_URL,
+ // req.getRequestURI());
+ // XXX
+ header.addStringValue(OUT_SERVICE_URL,
+ "/kra?");
+ header.addStringValue(OUT_TEMPLATE,
+ TPL_FILE);
+ header.addStringValue(OUT_FILTER,
+ filter);
+
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... timelimit=" + timeLimit);
+ Enumeration e = mKeyDB.searchKeys(filter,
+ maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = (IKeyRecord)
+ e.nextElement();
+ // rec is null when we specify maxResults
+ // DS will return an err=4, which triggers
+ // a LDAPException.SIZE_LIMIT_ExCEEDED
+ // in DSSearchResults.java
+ if (rec != null) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ KeyRecordParser.fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ count++;
+ }
+ }
+ }
+
+ header.addIntegerValue("maxSize", mMaxReturns);
+ header.addIntegerValue(OUT_TOTAL_COUNT, count);
+ ctx.addIntegerValue(OUT_MAXCOUNT, maxCount);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java
new file mode 100644
index 000000000..bd5bca4d5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java
@@ -0,0 +1,314 @@
+// --- 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.servlet.key;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+/**
+ * Retrieve archived keys matching given public key material
+ *
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKeyForRecovery extends CMSServlet {
+
+ private final static String TPL_FILE = "srchKeyForRecovery.template";
+ private final static String INFO = "srchKey";
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ // input parameters
+ private final static String IN_MAXCOUNT = "maxCount";
+ private final static String IN_FILTER = "queryFilter";
+ private final static String IN_SENTINEL = "querySentinel";
+
+ // output parameters
+ private final static String OUT_FILTER = IN_FILTER;
+ private final static String OUT_MAXCOUNT = IN_MAXCOUNT;
+ private final static String OUT_SENTINEL = IN_SENTINEL;
+ private final static String OUT_OP = "op";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_ARCHIVER = "archiverName";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_TOTAL_COUNT = "totalRecordCount";
+ private final static String OUT_TEMPLATE = "templateName";
+
+ private IKeyRepository mKeyDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = 100;
+ private int mTimeLimits = 30; /* in seconds */
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchKeyForRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "srchKeyForRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ try {
+ String tmp =
+ sc.getInitParameter(PROP_MAX_SEARCH_RETURNS);
+
+ if (tmp == null)
+ mMaxReturns = 100;
+ else
+ mMaxReturns = Integer.parseInt(tmp);
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mAuthName = ((IKeyRecoveryAuthority) mAuthority).getX500Name();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ /* Server-Side time limit */
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param maxCount maximum number of matches to show in result
+ * <li>http.param maxResults maximum number of matches to run in ldapsearch
+ * <li>http.param publicKeyData public key data to search on
+ * <li>http.param querySentinel ID of first request to show
+ * <li>http.param timeLimit number of seconds to limit ldap search to
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ // process query if authentication is successful
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+ EBaseException error = null;
+
+ int maxCount = -1;
+ int sentinel = 0;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ try {
+ if (req.getParameter(IN_MAXCOUNT) != null) {
+ maxCount = Integer.parseInt(
+ req.getParameter(IN_MAXCOUNT));
+ }
+ if (req.getParameter(IN_SENTINEL) != null) {
+ sentinel = Integer.parseInt(
+ req.getParameter(IN_SENTINEL));
+ }
+ String maxResultsStr = req.getParameter("maxResults");
+
+ if (maxResultsStr != null && maxResultsStr.length() > 0)
+ maxResults = Integer.parseInt(maxResultsStr);
+ String timeLimitStr = req.getParameter("timeLimit");
+
+ if (timeLimitStr != null && timeLimitStr.length() > 0)
+ timeLimit = Integer.parseInt(timeLimitStr);
+ process(argSet, header, ctx, maxCount, maxResults, timeLimit, sentinel,
+ req.getParameter("publicKeyData"), req.getParameter(IN_FILTER), req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT"));
+ }
+
+ /*
+ catch (Exception e) {
+ error = new EBaseException(BaseResources.INTERNAL_ERROR_1, e);
+ }
+ */
+
+ try {
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ ServletOutputStream out = resp.getOutputStream();
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, IArgBlock ctx,
+ int maxCount, int maxResults, int timeLimit, int sentinel, String publicKeyData,
+ String filter,
+ HttpServletRequest req, HttpServletResponse resp, Locale locale)
+ throws EBaseException {
+
+ try {
+ // Fill header
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_ARCHIVER,
+ mAuthName.toString());
+ // STRANGE: IE does not like the following:
+ // header.addStringValue(OUT_SERVICE_URL,
+ // req.getRequestURI());
+ // XXX
+ header.addStringValue(OUT_SERVICE_URL,
+ "/kra?");
+ header.addStringValue(OUT_TEMPLATE,
+ TPL_FILE);
+ header.addStringValue(OUT_FILTER,
+ filter);
+ if (publicKeyData != null) {
+ header.addStringValue("publicKeyData",
+ publicKeyData);
+ }
+
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... timelimit=" + timeLimit);
+ Enumeration e = mKeyDB.searchKeys(filter, maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = (IKeyRecord)
+ e.nextElement();
+ // rec is null when we specify maxResults
+ // DS will return an err=4, which triggers
+ // a LDAPException.SIZE_LIMIT_ExCEEDED
+ // in DSSearchResults.java
+ if (rec != null) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ KeyRecordParser.fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ count++;
+ }
+ }
+ }
+
+ header.addIntegerValue("maxSize", mMaxReturns);
+ header.addIntegerValue(OUT_TOTAL_COUNT, count);
+ ctx.addIntegerValue(OUT_MAXCOUNT, maxCount);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error " + e);
+ throw e;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java
new file mode 100644
index 000000000..1e8e02379
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java
@@ -0,0 +1,322 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.math.*;
+import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.util.*;
+
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import java.security.cert.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+/**
+ * Configure the CA to respond to OCSP requests for a CA
+ *
+ * @version $Revision$ $Date$
+ */
+public class AddCAServlet extends CMSServlet {
+
+ public static final String BEGIN_HEADER =
+ "-----BEGIN CERTIFICATE-----";
+ public static final String END_HEADER =
+ "-----END CERTIFICATE-----";
+
+ public static final BigInteger BIG_ZERO = new BigInteger("0");
+ public static final Long MINUS_ONE = Long.valueOf(-1);
+
+ private final static String TPL_FILE = "addCA.template";
+ private String mFormPath = null;
+ private IOCSPAuthority mOCSPAuthority = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST =
+ "LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_3";
+ private final static String LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED_3";
+
+ public AddCAServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "addCA.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mOCSPAuthority = (IOCSPAuthority) mAuthority;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param cert ca certificate. The format is base-64, DER
+ * encoded, wrapped with -----BEGIN CERTIFICATE-----,
+ * -----END CERTIFICATE----- strings
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST used when
+ * a CA is attempted to be added to the OCSP responder
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED
+ * used when an add CA request to the OCSP Responder is processed
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditCA = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditCASubjectDN = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "add");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ if (auditSubjectID.equals(ILogger.NONROLEUSER) ||
+ auditSubjectID.equals(ILogger.UNIDENTIFIED)) {
+ String uid = authToken.getInString(IAuthToken.USER_ID);
+ if (uid != null) {
+ CMS.debug("AddCAServlet: auditSubjectID set to "+uid);
+ auditSubjectID = uid;
+ }
+ }
+ String b64 = cmsReq.getHttpReq().getParameter("cert");
+
+ if (b64 == null) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CA_CERT"));
+ }
+
+ auditCA = Cert.normalizeCertStr(Cert.stripCertBrackets(b64.trim()));
+ // record the fact that a request to add CA is made
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditCA);
+
+ audit( auditMessage );
+
+ if (b64.indexOf(BEGIN_HEADER) == -1) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CERT_HEADER"));
+ }
+ if (b64.indexOf(END_HEADER) == -1) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CERT_FOOTER"));
+ }
+
+ IDefStore defStore = mOCSPAuthority.getDefaultStore();
+
+ X509Certificate leafCert = null;
+ X509Certificate certs[] = null;
+
+ try {
+ X509Certificate cert = Cert.mapCert(b64);
+
+ if( cert == null ) {
+ CMS.debug( "AddCAServlet::process() - cert is null!" );
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+
+ throw new EBaseException( "cert is null" );
+ } else {
+ certs = new X509Certificate[1];
+ }
+
+ certs[0] = cert;
+ leafCert = cert;
+ auditCASubjectDN = leafCert.getSubjectDN().getName();
+ } catch (Exception e) {
+ }
+ if (certs == null) {
+ try {
+ // this could be a chain
+ certs = Cert.mapCertFromPKCS7(b64);
+ if (certs[0].getSubjectDN().getName().equals(certs[0].getIssuerDN().getName())) {
+ leafCert = certs[certs.length - 1];
+ } else {
+ leafCert = certs[0];
+ }
+ auditCASubjectDN = leafCert.getSubjectDN().getName();
+ } catch (Exception e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_CA_CHAIN_ERROR"));
+ }
+ }
+ if (certs != null && certs.length > 0) {
+ // (1) need to normalize (sort) the chain
+
+ // (2) store certificate (and certificate chain) into
+ // database
+ ICRLIssuingPointRecord rec = defStore.createCRLIssuingPointRecord(
+ leafCert.getSubjectDN().getName(),
+ BIG_ZERO,
+ MINUS_ONE, null, null);
+
+ try {
+ rec.set(ICRLIssuingPointRecord.ATTR_CA_CERT, leafCert.getEncoded());
+ } catch (Exception e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+
+ // error
+ }
+ defStore.addCRLIssuingPoint(leafCert.getSubjectDN().getName(), rec);
+ log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Added CA certificate " + leafCert.getSubjectDN().getName());
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_ADD_CA_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditCASubjectDN);
+
+ audit( auditMessage );
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+ String error = null;
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ // cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java
new file mode 100644
index 000000000..f967c5556
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java
@@ -0,0 +1,605 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.math.*;
+import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.*;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.util.*;
+
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import java.security.cert.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+/**
+ * Update the OCSP responder with a new CRL
+ *
+ * @version $Revision$ $Date$
+ */
+public class AddCRLServlet extends CMSServlet {
+
+ public static final String BEGIN_HEADER =
+ "-----BEGIN CERTIFICATE REVOCATION LIST-----";
+ public static final String END_HEADER =
+ "-----END CERTIFICATE REVOCATION LIST-----";
+
+ private final static String TPL_FILE = "addCRL.template";
+ private String mFormPath = null;
+ private IOCSPAuthority mOCSPAuthority = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL =
+ "LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL_3";
+ private final static String LOGGING_SIGNED_AUDIT_CRL_VALIDATION =
+ "LOGGING_SIGNED_AUDIT_CRL_VALIDATION_2";
+
+ public AddCRLServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "addCRL.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mOCSPAuthority = (IOCSPAuthority) mAuthority;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <P>
+ *
+ * <ul>
+ * <li>http.param crl certificate revocation list, base-64, DER encoded
+ * wrapped in -----BEGIN CERTIFICATE REVOCATION LIST-----,
+ * -----END CERTIFICATE REVOCATION LIST----- strings
+ * <li>http.param noui if true, use minimal hardcoded text response
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL used when CRLs are
+ * retrieved by the OCSP Responder ("agent" or "EE")
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CRL_VALIDATION used when CRL is
+ * retrieved and validation process occurs ("agent" or "EE")
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ * @exception EBaseException an error has occurred
+ */
+ protected synchronized void process(CMSRequest cmsReq)
+ throws EBaseException {
+ boolean CRLFetched = false;
+ boolean CRLValidated = false;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditCRLNum = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("add_crl", true /* main action */);
+ }
+
+ try {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "add");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ return;
+ }
+
+ if (auditSubjectID.equals(ILogger.NONROLEUSER) ||
+ auditSubjectID.equals(ILogger.UNIDENTIFIED)) {
+ String uid = authToken.getInString(IAuthToken.USER_ID);
+ if (uid != null) {
+ CMS.debug("AddCAServlet: auditSubjectID set to "+uid);
+ auditSubjectID = uid;
+ }
+ }
+ log(ILogger.LL_INFO, "AddCRLServlet");
+ String b64 = cmsReq.getHttpReq().getParameter("crl");
+ if (CMS.debugOn()) CMS.debug("AddCRLServlet: b64=" + b64);
+
+ if (b64 == null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CRL"));
+ }
+
+ String nouiParm = cmsReq.getHttpReq().getParameter("noui");
+ boolean noUI = false;
+
+ if (nouiParm != null && nouiParm.equals("true")) {
+ noUI = true;
+ CMS.debug("AddCRLServlet: noUI=true");
+ } else {
+ CMS.debug("AddCRLServlet: noUI=false");
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ if (!noUI) {
+ form = getTemplate(mFormPath, req, locale);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath,
+ e.toString()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ if (b64.indexOf(BEGIN_HEADER) == -1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CRL_HEADER"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req),
+ "CMS_GW_MISSING_CRL_HEADER"));
+ }
+ if (b64.indexOf(END_HEADER) == -1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CRL_FOOTER"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req),
+ "CMS_GW_MISSING_CRL_FOOTER"));
+ }
+
+ IDefStore defStore = mOCSPAuthority.getDefaultStore();
+
+ X509CRLImpl crl = null;
+
+ try {
+ long startTime = CMS.getCurrentDate().getTime();
+ CMS.debug("AddCRLServlet: mapCRL start startTime=" + startTime);
+ if (statsSub != null) {
+ statsSub.startTiming("decode_crl");
+ }
+ crl = mapCRL1( b64 );
+ if (statsSub != null) {
+ statsSub.endTiming("decode_crl");
+ }
+ long endTime = CMS.getCurrentDate().getTime();
+ CMS.debug("AddCRLServlet: mapCRL done endTime=" + endTime +
+ " diff=" + (endTime - startTime));
+
+ // Retrieve the actual CRL number
+ BigInteger crlNum = crl.getCRLNumber();
+ if( crlNum != null ) {
+ auditCRLNum = crlNum.toString();
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ // acknowledge that the CRL has been retrieved
+ CRLFetched = true;
+ } catch (Exception e) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODING_CRL_ERROR"));
+ }
+ log(ILogger.LL_INFO, "AddCRLServlet: CRL Issuer DN " +
+ crl.getIssuerDN().getName());
+
+ // update the CRLIssuingPoint record
+ if (crl == null) {
+ // error
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_VALIDATION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODING_CRL_ERROR"));
+ }
+
+ ICRLIssuingPointRecord pt = null;
+
+ try {
+ pt = defStore.readCRLIssuingPoint(
+ crl.getIssuerDN().getName());
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT_FOUND",
+ crl.getIssuerDN().getName()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_VALIDATION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODING_CRL_ERROR"));
+ }
+ log(ILogger.LL_INFO, "AddCRLServlet: IssuingPoint " +
+ pt.getThisUpdate());
+
+ // verify CRL
+ byte caCertData[] = pt.getCACert();
+ if (caCertData != null) {
+ try {
+ X509CertImpl caCert = new X509CertImpl(caCertData);
+ CMS.debug("AddCRLServlet: start verify");
+
+ CryptoManager cmanager = CryptoManager.getInstance();
+ org.mozilla.jss.crypto.X509Certificate jssCert = null;
+ try {
+ jssCert = cmanager.importCACertPackage(
+ caCert.getEncoded());
+ } catch (Exception e2) {
+ CMS.debug("AddCRLServlet: importCACertPackage " +
+ e2.toString());
+ throw new EBaseException( e2.toString() );
+ }
+
+ if (statsSub != null) {
+ statsSub.startTiming("verify_crl");
+ }
+ crl.verify(jssCert.getPublicKey(), "Mozilla-JSS");
+ if (statsSub != null) {
+ statsSub.endTiming("verify_crl");
+ }
+ CMS.debug("AddCRLServlet: done verify");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_VALIDATION,
+ auditSubjectID,
+ ILogger.SUCCESS );
+
+ audit( auditMessage );
+
+ // acknowledge that the CRL has been validated
+ CRLValidated = true;
+ } catch (Exception e) {
+ CMS.debug("AddCRLServlet: failed to verify CRL " + e.toString());
+ CMS.debug(e);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT_FOUND",
+ crl.getIssuerDN().getName()));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_VALIDATION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODING_CRL_ERROR"));
+ }
+ }
+
+ if ((pt.getThisUpdate() != null) &&
+ (pt.getThisUpdate().getTime() >=
+ crl.getThisUpdate().getTime())) {
+ // error, the uploaded CRL is older than the current
+ CMS.debug("AddCRLServlet: no update, CRL is older");
+ log(ILogger.LL_INFO,
+ "AddCRLServlet: no update, received CRL is older " +
+ "than current CRL");
+ if (noUI) {
+ try {
+ resp.setContentType("application/text");
+ resp.getOutputStream().write("status=1\n".getBytes());
+ resp.getOutputStream().write(
+ "error=Sent CRL is older than the current CRL\n".getBytes());
+ resp.getOutputStream().flush();
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // NOTE: The signed audit events
+ // LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL and
+ // LOGGING_SIGNED_AUDIT_CRL_VALIDATION have
+ // already been logged at this point!
+
+ return;
+ } catch (Exception e) {
+ }
+ } else {
+ CMS.debug("AddCRLServlet: CRL is older");
+
+ // NOTE: The signed audit events
+ // LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL and
+ // LOGGING_SIGNED_AUDIT_CRL_VALIDATION have
+ // already been logged at this point!
+
+ throw new ECMSGWException(CMS.getUserMessage(
+ "CMS_GW_OLD_CRL_ERROR"));
+ }
+ }
+
+ if (crl.isDeltaCRL()) {
+ CMS.debug("AddCRLServlet: no update, Delta CRLs are not supported.");
+ log(ILogger.LL_INFO, "AddCRLServlet: no update, "+
+ CMS.getUserMessage("CMS_GW_DELTA_CRL_NOT_SUPPORTED"));
+ if (noUI) {
+ try {
+ resp.setContentType("application/text");
+ resp.getOutputStream().write("status=1\n".getBytes());
+ resp.getOutputStream().write(
+ "error=Delta CRLs are not supported.\n".getBytes());
+ resp.getOutputStream().flush();
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ return;
+ } catch (Exception e) {
+ }
+ } else {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DELTA_CRL_NOT_SUPPORTED"));
+ }
+ }
+
+ CMS.debug("AddCRLServlet: strt committing CRL");
+ log(ILogger.LL_INFO, "AddCRLServlet: Start Committing CRL");
+
+ // *****************************************************
+ // The commit transaction may take long time and
+ // there may have a system crash during the transaction
+ // *****************************************************
+
+ IRepositoryRecord repRec = defStore.createRepositoryRecord();
+
+ repRec.set(IRepositoryRecord.ATTR_SERIALNO,
+ new BigInteger(Long.toString(crl.getThisUpdate().getTime())));
+ try {
+ defStore.addRepository(
+ crl.getIssuerDN().getName(),
+ Long.toString(crl.getThisUpdate().getTime()),
+ repRec);
+ log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Added CRL Updated " +
+ Long.toString(crl.getThisUpdate().getTime()));
+ } catch (Exception e) {
+ CMS.debug("AddCRLServlet: add repository e=" + e.toString());
+ }
+ log(ILogger.LL_INFO, "AddCRLServlet: Created CRL Repository " +
+ Long.toString(crl.getThisUpdate().getTime()));
+
+ if (defStore.waitOnCRLUpdate()) {
+ defStore.updateCRL(crl);
+ } else {
+ // when the CRL large, the thread is terminiated by the
+ // servlet framework before it can finish its work
+ UpdateCRLThread uct = new UpdateCRLThread(defStore, crl);
+
+ uct.start();
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (noUI) {
+ CMS.debug("AddCRLServlet: return result noUI=true");
+ resp.setContentType("application/text");
+ resp.getOutputStream().write("status=0".getBytes());
+ resp.getOutputStream().flush();
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } else {
+ CMS.debug("AddCRLServlet: return result noUI=false");
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ }
+ } catch (IOException e) {
+ CMS.debug("AddCRLServlet: return result error=" + e.toString());
+ mOCSPAuthority.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE",
+ e.toString()));
+
+ // NOTE: The signed audit events
+ // LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL and
+ // LOGGING_SIGNED_AUDIT_CRL_VALIDATION have
+ // already been logged at this point!
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ } catch( EBaseException eAudit1 ) {
+ if( !CRLFetched ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditCRLNum );
+
+ audit( auditMessage );
+ } else {
+ if( !CRLValidated ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CRL_VALIDATION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+ }
+ }
+ throw eAudit1;
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("add_crl");
+ }
+ }
+
+ public X509CRLImpl mapCRL1(String mime64)
+ throws IOException {
+ mime64 = Cert.stripCRLBrackets(mime64.trim());
+
+ byte rawPub[] = CMS.AtoB(mime64);
+ X509CRLImpl crl = null;
+
+ try {
+ crl = new X509CRLImpl(rawPub, false);
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ return crl;
+ }
+}
+
+
+class UpdateCRLThread extends Thread {
+ private IDefStore mDefStore = null;
+ private X509CRL mCRL = null;
+
+ public UpdateCRLThread(
+ IDefStore defStore, X509CRL crl) {
+ mDefStore = defStore;
+ mCRL = crl;
+ }
+
+ public void run() {
+ try {
+ if (!((X509CRLImpl)mCRL).areEntriesIncluded())
+ mCRL = new X509CRLImpl(((X509CRLImpl)mCRL).getEncoded());
+ mDefStore.updateCRL(mCRL);
+ } catch (CRLException e) {
+ } catch (X509ExtensionException e) {
+ } catch (EBaseException e) {
+ // ignore
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java
new file mode 100644
index 000000000..bfed10291
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java
@@ -0,0 +1,224 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import java.security.cert.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+/**
+ * Check the status of a specific certificate
+ *
+ * @version $Revision$ $Date$
+ */
+public class CheckCertServlet extends CMSServlet {
+
+ public static final String BEGIN_HEADER =
+ "-----BEGIN CERTIFICATE-----";
+ public static final String END_HEADER =
+ "-----END CERTIFICATE-----";
+
+ public static final String ATTR_STATUS = "status";
+ public static final String ATTR_ISSUERDN = "issuerDN";
+ public static final String ATTR_SUBJECTDN = "subjectDN";
+ public static final String ATTR_SERIALNO = "serialno";
+
+ public static final String STATUS_GOOD = "good";
+ public static final String STATUS_REVOKED = "revoked";
+ public static final String STATUS_UNKNOWN = "unknown";
+
+ private final static String TPL_FILE = "checkCert.template";
+ private String mFormPath = null;
+ private IOCSPAuthority mOCSPAuthority = null;
+
+ public CheckCertServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "checkCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mOCSPAuthority = (IOCSPAuthority) mAuthority;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param cert certificate to check. Base64, DER encoded, wrapped
+ * in -----BEGIN CERTIFICATE-----, -----END CERTIFICATE----- strings
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "validate");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IDefStore defStore = mOCSPAuthority.getDefaultStore();
+
+ String b64 = cmsReq.getHttpReq().getParameter("cert");
+
+ if (b64.indexOf(BEGIN_HEADER) == -1) {
+ // error
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CERT_HEADER"));
+
+ }
+ if (b64.indexOf(END_HEADER) == -1) {
+ // error
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CERT_FOOTER"));
+ }
+
+ X509Certificate cert = null;
+
+ try {
+ cert = Cert.mapCert(b64);
+ } catch (Exception e) {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DECODING_CERT_ERROR"));
+ }
+ if (cert == null) {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DECODING_CERT_ERROR"));
+ }
+
+ ICRLIssuingPointRecord pt = defStore.readCRLIssuingPoint(
+ cert.getIssuerDN().getName());
+
+ header.addStringValue(ATTR_ISSUERDN, cert.getIssuerDN().getName());
+ header.addStringValue(ATTR_SUBJECTDN, cert.getSubjectDN().getName());
+ header.addStringValue(ATTR_SERIALNO, "0x" + cert.getSerialNumber().toString(16));
+ try {
+ X509CRLImpl crl = null;
+
+ crl = new X509CRLImpl(pt.getCRL());
+ X509CRLEntry crlentry = crl.getRevokedCertificate(cert.getSerialNumber());
+
+ if (crlentry == null) {
+ if (defStore.isNotFoundGood()) {
+ header.addStringValue(ATTR_STATUS, STATUS_GOOD);
+ } else {
+ header.addStringValue(ATTR_STATUS, STATUS_UNKNOWN);
+ }
+ } else {
+ header.addStringValue(ATTR_STATUS, STATUS_REVOKED);
+ }
+ } catch (Exception e) {
+ header.addStringValue(ATTR_STATUS, STATUS_UNKNOWN);
+ }
+ log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Checked Certificate Status " + cert.getIssuerDN().getName() + " " + cert.getSerialNumber().toString());
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+ String error = null;
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ // cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java
new file mode 100644
index 000000000..6885eb067
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java
@@ -0,0 +1,173 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve information about the number of OCSP requests the OCSP
+ * has serviced
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetOCSPInfo extends CMSServlet {
+ private final static String TPL_FILE = "getOCSPInfo.template";
+ private String mFormPath = null;
+
+ public GetOCSPInfo() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template
+ * file "getOCSPInfo.template" to render the result page.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IOCSPService)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IOCSPService ca = (IOCSPService) mAuthority;
+
+ header.addLongValue("numReq", ca.getNumOCSPRequest());
+ header.addLongValue("totalSec", ca.getOCSPRequestTotalTime());
+ header.addLongValue("totalSignSec", ca.getOCSPTotalSignTime());
+ header.addLongValue("totalLookupSec", ca.getOCSPTotalLookupTime());
+ header.addLongValue("totalData", ca.getOCSPTotalData());
+ long secs = 0;
+ if (ca.getOCSPRequestTotalTime() != 0) {
+ secs = (ca.getNumOCSPRequest() * 1000) / ca.getOCSPRequestTotalTime();
+ }
+ header.addLongValue("ReqSec", secs);
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java
new file mode 100644
index 000000000..df52d1256
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java
@@ -0,0 +1,211 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.math.*;
+import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.cmsutil.util.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.pkcs.*;
+import netscape.security.x509.*;
+import java.security.cert.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+/**
+ * Show the list of CA's that the OCSP responder can service
+ *
+ * @version $Revision$ $Date$
+ */
+public class ListCAServlet extends CMSServlet {
+
+ public static final String BEGIN_HEADER =
+ "-----BEGIN CERTIFICATE-----";
+ public static final String END_HEADER =
+ "-----END CERTIFICATE-----";
+
+ private final static String TPL_FILE = "listCAs.template";
+ private String mFormPath = null;
+ private IOCSPAuthority mOCSPAuthority = null;
+
+ public ListCAServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "listCAs.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mOCSPAuthority = (IOCSPAuthority) mAuthority;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IDefStore defStore = mOCSPAuthority.getDefaultStore();
+ Enumeration recs = defStore.searchAllCRLIssuingPointRecord(100);
+
+ // show the current CRL number if present
+ header.addStringValue("stateCount",
+ Integer.toString(defStore.getStateCount()));
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec =
+ (ICRLIssuingPointRecord) recs.nextElement();
+ IArgBlock rarg = CMS.createArgBlock();
+ String thisId = rec.getId();
+
+ rarg.addStringValue("Id", thisId);
+ Date thisUpdate = rec.getThisUpdate();
+
+ if (thisUpdate == null) {
+ rarg.addStringValue("ThisUpdate", "UNKNOWN");
+ } else {
+ rarg.addStringValue("ThisUpdate", thisUpdate.toString());
+ }
+ Date nextUpdate = rec.getNextUpdate();
+
+ if (nextUpdate == null) {
+ rarg.addStringValue("NextUpdate", "UNKNOWN");
+ } else {
+ rarg.addStringValue("NextUpdate", nextUpdate.toString());
+ }
+ Long rc = rec.getCRLSize();
+
+ if (rc == null) {
+ rarg.addLongValue("NumRevoked", 0);
+ } else {
+ if (rc.longValue() == -1) {
+ rarg.addStringValue("NumRevoked", "UNKNOWN");
+ } else {
+ rarg.addLongValue("NumRevoked", rc.longValue());
+ }
+ }
+
+ BigInteger crlNumber = rec.getCRLNumber();
+ if (crlNumber == null || crlNumber.equals(new BigInteger("-1"))) {
+ rarg.addStringValue("CRLNumber", "UNKNOWN");
+ } else {
+ rarg.addStringValue("CRLNumber", crlNumber.toString());
+ }
+
+ rarg.addLongValue("ReqCount", defStore.getReqCount(thisId));
+ argSet.addRepeatRecord(rarg);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+ String error = null;
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ // cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java
new file mode 100644
index 000000000..1054c794e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java
@@ -0,0 +1,272 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.*;
+import java.security.*;
+import java.util.Vector;
+import java.io.*;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.BIT_STRING;
+
+import netscape.security.x509.*;
+import java.security.cert.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cmsutil.ocsp.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * Process OCSP messages, According to RFC 2560
+ * See http://www.ietf.org/rfc/rfc2560.txt
+ *
+ * @version $Revision$ $Date$
+ */
+public class OCSPServlet extends CMSServlet {
+
+ public final static String PROP_AUTHORITY = "authority";
+ public final static String PROP_CLIENTAUTH = "GetClientCert";
+ public final static String PROP_MAX_REQUEST_SIZE = "MaxRequestSize";
+ public final static String PROP_ID = "ID";
+
+ private int m_maxRequestSize=5000;
+
+ public OCSPServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ String s = sc.getInitParameter(PROP_MAX_REQUEST_SIZE);
+ if (s != null) {
+ try {
+ m_maxRequestSize = Integer.parseInt(s);
+ } catch (Exception e) {}
+ }
+
+ }
+
+ /**
+ * Process the HTTP request.
+ * This method is invoked when the OCSP service receives a OCSP
+ * request. Based on RFC 2560, the request should have the OCSP
+ * request in the HTTP body as binary blob.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("ocsp", true /* main action */);
+ }
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMS.debug("Servlet Path=" + httpReq.getServletPath());
+ CMS.debug("RequestURI=" + httpReq.getRequestURI());
+ String pathInfo = httpReq.getPathInfo();
+ java.net.URLDecoder urldecoder = new java.net.URLDecoder();
+ if (pathInfo != null && pathInfo.indexOf('%') != -1) {
+ pathInfo = urldecoder.decode(pathInfo);
+ }
+ CMS.debug("PathInfo=" + pathInfo);
+
+ OCSPRequest ocspReq = null;
+
+ try {
+ InputStream is = httpReq.getInputStream();
+ byte reqbuf[] = null;
+ String method = httpReq.getMethod();
+ CMS.debug("Method=" + method);
+ if (method != null && method.equals("POST")) {
+ int reqlen = httpReq.getContentLength();
+
+ if (reqlen == -1) {
+ throw new Exception("OCSPServlet: Content-Length not supplied");
+ }
+ if (reqlen == 0) {
+ throw new Exception("OCSPServlet: Invalid Content-Length");
+ }
+ if (reqlen > m_maxRequestSize) {
+ throw new Exception("OCSPServlet: Client sending too much OCSP request data ("+reqlen+")");
+ }
+
+ // for debugging
+ reqbuf = new byte[reqlen];
+ int bytesread = 0;
+ boolean partial = false;
+
+ while (bytesread < reqlen) {
+ int r = is.read(reqbuf, bytesread, reqlen - bytesread);
+ if (r == -1) {
+ throw new Exception("OCSPServlet: Client did not supply enough OCSP data");
+ }
+ bytesread += r;
+ if (partial == false) {
+ if (bytesread < reqlen) {
+ partial = true;
+ }
+ }
+ }
+ is = new ByteArrayInputStream(reqbuf);
+ } else {
+ // GET method
+ if ( (pathInfo == null) ||
+ (pathInfo.equals( "" ) ) ||
+ (pathInfo.substring(1) == null) ||
+ (pathInfo.substring(1).equals( "" ) ) ) {
+ throw new Exception("OCSPServlet: OCSP request not provided in GET method");
+ }
+ is = new ByteArrayInputStream(
+ com.netscape.osutil.OSUtil.AtoB(pathInfo.substring(1)));
+ }
+
+ // (1) retrieve OCSP request
+ // (2) decode request
+ OCSPResponse response = null;
+
+ try {
+ OCSPRequest.Template reqTemplate =
+ new OCSPRequest.Template();
+
+ if ( (is == null) ||
+ (is.toString().equals( "" ) ) ) {
+ throw new Exception( "OCSPServlet: OCSP request is "
+ + "empty or malformed");
+ }
+ ocspReq = (OCSPRequest) reqTemplate.decode(is);
+ if ( (ocspReq == null) ||
+ (ocspReq.toString().equals( "" ) ) ) {
+ throw new Exception( "OCSPServlet: Decoded OCSP request "
+ + "is empty or malformed");
+ }
+ response = ((IOCSPService) mAuthority).validate(ocspReq);
+ } catch (Exception e) {;
+ CMS.debug("OCSPServlet: " + e.toString());
+ }
+
+ if (response != null) {
+ ByteArrayOutputStream fos1 = new ByteArrayOutputStream();
+
+ response.encode(fos1);
+ fos1.close();
+
+ byte[] respbytes;
+
+ respbytes = fos1.toByteArray();
+
+ // print out OCSP response in debug mode so that
+ // we can validate the response
+ if (CMS.debugOn()) {
+ CMS.debug("OCSPServlet: OCSP Request:");
+ CMS.debug("OCSPServlet: " + CMS.BtoA(ASN1Util.encode(ocspReq)));
+ TBSRequest tbsReq = ocspReq.getTBSRequest();
+ for (int i = 0; i < tbsReq.getRequestCount(); i++) {
+ com.netscape.cmsutil.ocsp.Request req = tbsReq.getRequestAt(i);
+ CMS.debug("Serial Number: " + req.getCertID().getSerialNumber());
+ }
+ CMS.debug("OCSPServlet: OCSP Response Size:");
+ CMS.debug("OCSPServlet: " + Integer.toString(respbytes.length));
+ CMS.debug("OCSPServlet: OCSP Response Data:");
+ CMS.debug("OCSPServlet: " + CMS.BtoA(respbytes));
+ ResponseBytes rbytes = response.getResponseBytes();
+ if (rbytes == null) {
+ CMS.debug("Response bytes is null");
+ } else if (rbytes.getObjectIdentifier().equals(
+ ResponseBytes.OCSP_BASIC)) {
+ BasicOCSPResponse basicRes = (BasicOCSPResponse)
+ BasicOCSPResponse.getTemplate().decode(
+ new ByteArrayInputStream(rbytes.getResponse().toByteArray()));
+ if (basicRes == null) {
+ CMS.debug("Basic Res is null");
+ } else {
+ ResponseData data = basicRes.getResponseData();
+ for (int i = 0; i < data.getResponseCount(); i++) {
+ SingleResponse res = data.getResponseAt(i);
+ CMS.debug("Serial Number: " +
+ res.getCertID().getSerialNumber() +
+ " Status: " +
+ res.getCertStatus().getClass().getName());
+ }
+ }
+ }
+ }
+
+ httpResp.setContentType("application/ocsp-response");
+
+ httpResp.setContentLength(respbytes.length);
+ OutputStream ooss = httpResp.getOutputStream();
+
+ ooss.write(respbytes);
+ ooss.flush();
+ if (statsSub != null) {
+ statsSub.endTiming("ocsp");
+ }
+
+ mRenderResult = false;
+ }
+ } catch (Exception e) {
+ CMS.debug("OCSPServlet: " + e.toString());
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java b/pki/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java
new file mode 100644
index 000000000..5a1f7a432
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java
@@ -0,0 +1,225 @@
+// --- 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.servlet.ocsp;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.math.*;
+import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.cmsutil.util.*;
+
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+/**
+ * Configure the CA to no longer respond to OCSP requests for a CA
+ *
+ * @version $Revision: 1274 $ $Date: 2010-09-07 22:14:41 -0700 (Tue, 07 Sep 2010) $
+ */
+public class RemoveCAServlet extends CMSServlet {
+
+ private final static String TPL_FILE = "removeCA.template";
+ private String mFormPath = null;
+ private IOCSPAuthority mOCSPAuthority = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST =
+ "LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_3";
+ private final static String LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS_3";
+
+ private final static String LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE_3";
+
+ public RemoveCAServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "addCA.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mOCSPAuthority = (IOCSPAuthority) mAuthority;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param ca id. The format is string.
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST used when
+ * a CA is attempted to be removed from the OCSP responder
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS
+ * and LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE are used when
+ * a remove CA request to the OCSP Responder is processed successfully or not.
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditCA = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditCASubjectDN = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "add");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ if (auditSubjectID.equals(ILogger.NONROLEUSER) ||
+ auditSubjectID.equals(ILogger.UNIDENTIFIED)) {
+ String uid = authToken.getInString(IAuthToken.USER_ID);
+ if (uid != null) {
+ CMS.debug("RemoveCAServlet: auditSubjectID set to "+uid);
+ auditSubjectID = uid;
+ }
+ }
+
+ String caID = cmsReq.getHttpReq().getParameter("caID");
+
+
+ if (caID == null) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(req), "CMS_GW_MISSING_CA_ID"));
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ caID);
+
+ audit( auditMessage );
+
+ IDefStore defStore = mOCSPAuthority.getDefaultStore();
+
+ try {
+ defStore.deleteCRLIssuingPointRecord(caID);
+
+ } catch (EBaseException e) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ caID);
+ audit( auditMessage );
+
+ CMS.debug("RemoveCAServlet::process: Error deleting CRL IssuingPoint: " + caID);
+ throw new EBaseException(e.toString());
+ }
+
+ CMS.debug("RemoveCAServlet::process: CRL IssuingPoint for CA successfully removed: " + caID);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ caID);
+ audit( auditMessage );
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+ String error = null;
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ // cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java
new file mode 100644
index 000000000..0d9c1137c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java
@@ -0,0 +1,463 @@
+// --- 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.servlet.processors;
+
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Hashtable;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerValue;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import java.math.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import com.netscape.cms.servlet.processors.*;
+
+
+/**
+ * Process CMC messages according to RFC 2797
+ * See http://www.ietf.org/rfc/rfc2797.txt
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCProcessor extends PKIProcessor {
+
+ private boolean enforcePop = false;
+
+ public CMCProcessor() {
+ super();
+ }
+
+ public CMCProcessor(CMSRequest cmsReq, CMSServlet servlet, boolean doEnforcePop) {
+
+ super(cmsReq, servlet);
+ enforcePop = doEnforcePop;
+
+ }
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException {
+ }
+
+ public void fillCertInfo(
+ String protocolString, X509CertInfo certInfo,
+ IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+ }
+
+ public X509CertInfo[] fillCertInfoArray(
+ String protocolString, IAuthToken authToken, IArgBlock httpParams, IRequest req)
+ throws EBaseException {
+
+ CMS.debug("CMCProcessor: In CMCProcessor.fillCertInfoArray!");
+ String cmc = protocolString;
+
+ try {
+ byte[] cmcBlob = CMS.AtoB(cmc);
+ ByteArrayInputStream cmcBlobIn =
+ new ByteArrayInputStream(cmcBlob);
+
+ org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(cmcBlobIn);
+
+ if
+ (!cmcReq.getContentType().equals(org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) || !cmcReq.hasContent())
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_CMC_CONTENT"));
+
+ SignedData cmcFullReq = (SignedData)
+ cmcReq.getInterpretedContent();
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+
+ OBJECT_IDENTIFIER id = ci.getContentType();
+
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) || !ci.hasContent()) {
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_PKIDATA"));
+ }
+ OCTET_STRING content = ci.getContent();
+
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SEQUENCE reqSequence = pkiData.getReqSequence();
+
+ int numReqs = reqSequence.size();
+ X509CertInfo[] certInfoArray = new X509CertInfo[numReqs];
+ String[] reqIdArray = new String[numReqs];
+
+ for (int i = 0; i < numReqs; i++) {
+ // decode message.
+ TaggedRequest taggedRequest = (TaggedRequest) reqSequence.elementAt(i);
+
+ TaggedRequest.Type type = taggedRequest.getType();
+
+ if (type.equals(TaggedRequest.PKCS10)) {
+ TaggedCertificationRequest tcr = taggedRequest.getTcr();
+ int p10Id = tcr.getBodyPartID().intValue();
+
+ reqIdArray[i] = String.valueOf(p10Id);
+
+ CertificationRequest p10 =
+ tcr.getCertificationRequest();
+
+ // transfer to sun class
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ p10.encode(ostream);
+
+ PKCS10Processor pkcs10Processor = new PKCS10Processor(mRequest, mServlet);
+
+ try {
+ PKCS10 pkcs10 = new PKCS10(ostream.toByteArray());
+ //xxx do we need to do anything else?
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ pkcs10Processor.fillCertInfo(pkcs10, certInfo, authToken, httpParams);
+
+ /* fillPKCS10(pkcs10,certInfo,
+ authToken, httpParams);
+ */
+
+ certInfoArray[i] = certInfo;
+ } catch (Exception e) {
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_PKCS10_ERROR", e.toString()));
+ }
+ } else if (type.equals(TaggedRequest.CRMF)) {
+
+ CRMFProcessor crmfProc = new CRMFProcessor(mRequest, mServlet, enforcePop);
+
+ CertReqMsg crm = taggedRequest.getCrm();
+ CertRequest certReq = crm.getCertReq();
+
+ INTEGER certReqId = certReq.getCertReqId();
+ int srcId = certReqId.intValue();
+
+ reqIdArray[i] = String.valueOf(srcId);
+
+ certInfoArray[i] = crmfProc.processIndividualRequest(crm, authToken, httpParams);
+
+ } else {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_CMC_CONTENT"));
+ }
+ }
+
+ // verify the signerInfo
+ SET dais = cmcFullReq.getDigestAlgorithmIdentifiers();
+ int numDig = dais.size();
+ Hashtable digs = new Hashtable();
+
+ for (int i = 0; i < numDig; i++) {
+ AlgorithmIdentifier dai =
+ (AlgorithmIdentifier) dais.elementAt(i);
+ String name =
+ DigestAlgorithm.fromOID(dai.getOID()).toString();
+
+ MessageDigest md =
+ MessageDigest.getInstance(name);
+
+ byte[] digest = md.digest(content.toByteArray());
+
+ digs.put(name, digest);
+ }
+
+ SET sis = cmcFullReq.getSignerInfos();
+ int numSis = sis.size();
+
+ for (int i = 0; i < numSis; i++) {
+ org.mozilla.jss.pkix.cms.SignerInfo si =
+ (org.mozilla.jss.pkix.cms.SignerInfo)
+ sis.elementAt(i);
+
+ String name = si.getDigestAlgorithm().toString();
+ byte[] digest = (byte[]) digs.get(name);
+
+ if (digest == null) {
+ MessageDigest md = MessageDigest.getInstance(name);
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkiData.encode((OutputStream) ostream);
+ digest = md.digest(ostream.toByteArray());
+
+ }
+
+ SignerIdentifier sid = si.getSignerIdentifier();
+
+ if
+ (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
+ IssuerAndSerialNumber issuerAndSerialNumber = sid.getIssuerAndSerialNumber();
+ // find from the certs in the signedData
+ X509Certificate cert = null;
+
+ if (cmcFullReq.hasCertificates()) {
+ SET certs = cmcFullReq.getCertificates();
+ int numCerts = certs.size();
+
+ for (int j = 0; j < numCerts; j++) {
+ Certificate certJss =
+ (Certificate) certs.elementAt(j);
+ CertificateInfo certI =
+ certJss.getInfo();
+ Name issuer = certI.getIssuer();
+ byte[] issuerB = ASN1Util.encode(issuer);
+
+ INTEGER sn = certI.getSerialNumber();
+
+ if (
+ new String(issuerB).equals(new
+ String(ASN1Util.encode(issuerAndSerialNumber.getIssuer())))
+ && sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString())) {
+ ByteArrayOutputStream os = new
+ ByteArrayOutputStream();
+
+ certJss.encode(os);
+ cert = new X509CertImpl(os.toByteArray());
+ // xxx validate the cert length
+
+ }
+ }
+
+ }
+ // find from internaldb if it's ca. (ra does not have that.)
+ // find from internaldb usrgrp info
+
+ if (cert == null) {
+ // find from certDB
+ si.verify(digest, id);
+ } else {
+ PublicKey signKey = cert.getPublicKey();
+ PrivateKey.Type keyType = null;
+ String alg = signKey.getAlgorithm();
+
+ if (alg.equals("RSA")) {
+ keyType = PrivateKey.RSA;
+ } else if (alg.equals("DSA")) {
+ keyType = PrivateKey.DSA;
+ } else {
+ }
+ PK11PubKey pubK =
+ PK11PubKey.fromRaw(keyType,
+ ((X509Key) signKey).getKey());
+
+ si.verify(digest, id, pubK);
+ }
+
+ } else {
+ OCTET_STRING ski = sid.getSubjectKeyIdentifier();
+ // find the publicKey using ski
+ int j = 0;
+ PublicKey signKey = null;
+
+ while (signKey == null && j < numReqs) {
+ X509Key subjectKeyInfo = (X509Key) ((CertificateX509Key) certInfoArray[j].get(X509CertInfo.KEY)).get(CertificateX509Key.KEY);
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(subjectKeyInfo.getEncoded());
+ byte[] skib = md.digest();
+
+ if (new String(skib).equals(new String(ski.toByteArray()))) {
+ signKey = subjectKeyInfo;
+ }
+ j++;
+ }
+ if (signKey == null) {
+ throw new
+ ECMSGWException(CMS.getUserMessage("CMS_GW_CMC_ERROR",
+ "SubjectKeyIdentifier in SignerInfo does not match any publicKey in the request."));
+ } else {
+ PrivateKey.Type keyType = null;
+ String alg = signKey.getAlgorithm();
+
+ if (alg.equals("RSA")) {
+ keyType = PrivateKey.RSA;
+ } else if (alg.equals("DSA")) {
+ keyType = PrivateKey.DSA;
+ } else {
+ }
+ PK11PubKey pubK = PK11PubKey.fromRaw(
+ keyType,
+ ((X509Key) signKey).getKey());
+
+ si.verify(digest, id, pubK);
+ }
+ }
+ }
+ // end verify signerInfo
+
+ // Get control sequence
+ // verisign has transactionId, senderNonce, regInfo
+ // identification, identityproof
+ SEQUENCE controls = pkiData.getControlSequence();
+ int numControls = controls.size();
+
+ for (int i = 0; i < numControls; i++) {
+ TaggedAttribute control =
+ (TaggedAttribute) controls.elementAt(i);
+ OBJECT_IDENTIFIER type = control.getType();
+ SET values = control.getValues();
+ int numVals = values.size();
+
+ if (type.equals(OBJECT_IDENTIFIER.id_cmc_transactionId)) {
+ String[] vals = null;
+
+ if (numVals > 0)
+ vals = new String[numVals];
+ for (int j = 0; j < numVals; j++) {
+ ANY val = (ANY)
+ values.elementAt(j);
+ INTEGER transId = (INTEGER) ((ANY) val).decodeWith(
+ INTEGER.getTemplate());
+
+ if (transId != null) {
+ vals[j] = transId.toString();
+ }
+ }
+ if (vals != null)
+ req.setExtData(IRequest.CMC_TRANSID, vals);
+ } else if
+ (type.equals(OBJECT_IDENTIFIER.id_cmc_senderNonce)) {
+ String[] vals = null;
+
+ if (numVals > 0)
+ vals = new String[numVals];
+ for (int j = 0; j < numVals; j++) {
+ ANY val = (ANY)
+ values.elementAt(j);
+ OCTET_STRING nonce = (OCTET_STRING)
+ ((ANY) val).decodeWith(OCTET_STRING.getTemplate());
+
+ if (nonce != null) {
+ vals[j] = new String(nonce.toByteArray());
+ }
+ }
+ if (vals != null)
+ req.setExtData(IRequest.CMC_SENDERNONCE, vals);
+
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_regInfo)) {
+ // what can we do here
+ // for verisign, we just debug.print()
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_identification)) {
+ // what can we do here
+ // for verisign, we just debug.print()
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_identityProof)) {
+ // what can we do here
+ // for verisign, we just debug.print()
+ }
+ }
+
+ req.setExtData(IRequest.CMC_REQIDS, reqIdArray);
+ return certInfoArray;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CMC_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CMC_TO_CERTINFO_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CMC_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CMC_TO_CERTINFO_ERROR"));
+ } catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CMC_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CMC_TO_CERTINFO_ERROR"));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CMC_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CMC_TO_CERTINFO_ERROR"));
+ }catch (Exception e) {
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CMC_ERROR", e.toString()));
+ }
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
new file mode 100644
index 000000000..91867216b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
@@ -0,0 +1,370 @@
+// --- 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.servlet.processors;
+
+
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cms.servlet.common.*;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.ObjectIdentifier;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.pkix.crmf.*;
+
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.certsrv.request.IRequest;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.processors.PKIProcessor;
+
+
+/**
+ * Process CRMF requests, according to RFC 2511
+ * See http://www.ietf.org/rfc/rfc2511.txt
+ *
+ * @version $Revision$, $Date$
+ */
+public class CRMFProcessor extends PKIProcessor {
+
+ private CMSRequest mRequest;
+
+ private boolean enforcePop = false;
+
+ private final static String LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION =
+ "LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2";
+
+ public CRMFProcessor() {
+ super();
+ }
+
+ public CRMFProcessor(CMSRequest cmsReq, CMSServlet servlet, boolean doEnforcePop) {
+ super(cmsReq, servlet);
+
+ enforcePop = doEnforcePop;
+ mRequest = cmsReq;
+ }
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException {
+ }
+
+ /**
+ * Verify Proof of Possession (POP)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION used when proof
+ * of possession is checked during certificate enrollment
+ * </ul>
+ * @param certReqMsg the certificate request message
+ * @exception EBaseException an error has occurred
+ */
+ private void verifyPOP(CertReqMsg certReqMsg)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ try {
+ CMS.debug("CRMFProcessor: verifyPOP");
+
+ if (certReqMsg.hasPop()) {
+ ProofOfPossession pop = certReqMsg.getPop();
+
+ ProofOfPossession.Type popType = pop.getType();
+
+ if (popType == ProofOfPossession.SIGNATURE) {
+ CMS.debug("CRMFProcessor: Request has pop.");
+ try {
+ certReqMsg.verify();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.SUCCESS );
+
+ audit( auditMessage );
+ } catch (Exception e) {
+ CMS.debug("CRMFProcessor: Failed POP verify!");
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_POP_VERIFY"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_POP_VERIFY"));
+ }
+ }
+ } else {
+ if (enforcePop == true) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_NO_POP"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_NO_POP"));
+ }
+ }
+ } catch( EBaseException eAudit1 ) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION,
+ auditSubjectID,
+ ILogger.FAILURE );
+
+ audit( auditMessage );
+ }
+ }
+
+ public X509CertInfo processIndividualRequest(CertReqMsg certReqMsg, IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+ CMS.debug("CRMFProcessor::processIndividualRequest!");
+
+ try {
+
+ verifyPOP(certReqMsg);
+
+ CertRequest certReq = certReqMsg.getCertReq();
+ INTEGER certReqId = certReq.getCertReqId();
+
+ CertTemplate certTemplate = certReq.getCertTemplate();
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ // get key
+ SubjectPublicKeyInfo spki = certTemplate.getPublicKey();
+ ByteArrayOutputStream keyout = new ByteArrayOutputStream();
+
+ spki.encode(keyout);
+ byte[] keybytes = keyout.toByteArray();
+ X509Key key = new X509Key();
+
+ key.decode(keybytes);
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+
+ // field suggested notBefore and notAfter in CRMF
+ // Tech Support #383184
+ if (certTemplate.getNotBefore() != null || certTemplate.getNotAfter() != null) {
+ CertificateValidity certValidity = new CertificateValidity(certTemplate.getNotBefore(), certTemplate.getNotAfter());
+
+ certInfo.set(X509CertInfo.VALIDITY, certValidity);
+ }
+
+ if (certTemplate.hasSubject()) {
+ Name subjectdn = certTemplate.getSubject();
+ ByteArrayOutputStream subjectEncStream =
+ new ByteArrayOutputStream();
+
+ subjectdn.encode(subjectEncStream);
+ byte[] subjectEnc = subjectEncStream.toByteArray();
+ X500Name subject = new X500Name(subjectEnc);
+
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+ } else if (authToken == null ||
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) == null) {
+ // No subject name - error!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ }
+
+ // get extensions
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (CertificateException e) {
+ extensions = null;
+ } catch (IOException e) {
+ extensions = null;
+ }
+ if (certTemplate.hasExtensions()) {
+ // put each extension from CRMF into CertInfo.
+ // index by extension name, consistent with
+ // CertificateExtensions.parseExtension() method.
+ if (extensions == null)
+ extensions = new CertificateExtensions();
+ int numexts = certTemplate.numExtensions();
+
+ for (int j = 0; j < numexts; j++) {
+ org.mozilla.jss.pkix.cert.Extension jssext =
+ certTemplate.extensionAt(j);
+ boolean isCritical = jssext.getCritical();
+ org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssoid =
+ jssext.getExtnId();
+ long[] numbers = jssoid.getNumbers();
+ int[] oidNumbers = new int[numbers.length];
+
+ for (int k = numbers.length - 1; k >= 0; k--) {
+ oidNumbers[k] = (int) numbers[k];
+ }
+ ObjectIdentifier oid =
+ new ObjectIdentifier(oidNumbers);
+ org.mozilla.jss.asn1.OCTET_STRING jssvalue =
+ jssext.getExtnValue();
+ ByteArrayOutputStream jssvalueout =
+ new ByteArrayOutputStream();
+
+ jssvalue.encode(jssvalueout);
+ byte[] extValue = jssvalueout.toByteArray();
+
+ Extension ext =
+ new Extension(oid, isCritical, extValue);
+
+ extensions.parseExtension(ext);
+ }
+
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ }
+
+ // Added a new configuration parameter
+ // eeGateway.Enrollment.authTokenOverride=[true|false]
+ // By default, it is set to true. In most
+ // of the case, administrator would want
+ // to have the control of the subject name
+ // formulation.
+ // -- CRMFfillCert
+ if (authToken != null &&
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) != null) {
+ // if authenticated override subect name, validity and
+ // extensions if any from authtoken.
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ }
+
+ // SPECIAL CASE:
+ // if it is adminEnroll servlet, get the validity
+ // from the http parameters.
+ if (mServletId.equals(PKIProcessor.ADMIN_ENROLL_SERVLET_ID)) {
+ fillValidityFromForm(certInfo, httpParams);
+ }
+
+ return certInfo;
+
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } /* catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1",e.toString()));
+ throw new ECMSGWException(
+ CMSGWResources.ERROR_CRMF_TO_CERTINFO);
+ } */ catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ }
+
+ }
+
+ public X509CertInfo[] fillCertInfoArray(
+ String protocolString, IAuthToken authToken, IArgBlock httpParams, IRequest req)
+ throws EBaseException {
+
+ CMS.debug("CRMFProcessor.fillCertInfoArray!");
+
+ String crmf = protocolString;
+
+ try {
+ byte[] crmfBlob = CMS.AtoB(crmf);
+ ByteArrayInputStream crmfBlobIn =
+ new ByteArrayInputStream(crmfBlob);
+
+ SEQUENCE crmfMsgs = (SEQUENCE)
+ new SEQUENCE.OF_Template(new CertReqMsg.Template()).decode(crmfBlobIn);
+
+ int nummsgs = crmfMsgs.size();
+ X509CertInfo[] certInfoArray = new X509CertInfo[nummsgs];
+
+ for (int i = 0; i < nummsgs; i++) {
+ // decode message.
+ CertReqMsg certReqMsg = (CertReqMsg) crmfMsgs.elementAt(i);
+
+ CertRequest certReq = certReqMsg.getCertReq();
+ INTEGER certReqId = certReq.getCertReqId();
+ int srcId = certReqId.intValue();
+
+ req.setExtData(IRequest.CRMF_REQID, String.valueOf(srcId));
+
+ certInfoArray[i] = processIndividualRequest(certReqMsg, authToken, httpParams);
+
+ }
+
+ //do_testbed_hack(nummsgs, certInfoArray, httpParams);
+
+ return certInfoArray;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java
new file mode 100644
index 000000000..d74dbcd95
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java
@@ -0,0 +1,105 @@
+// --- 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.servlet.processors;
+
+
+import com.netscape.cms.servlet.common.*;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Hashtable;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerValue;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import java.math.*;
+
+
+/**
+ * This represents the request parser.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPKIProcessor {
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException;
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java
new file mode 100644
index 000000000..c8db3e3d0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java
@@ -0,0 +1,185 @@
+// --- 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.servlet.processors;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Hashtable;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerValue;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import java.math.*;
+
+import com.netscape.cms.servlet.processors.IPKIProcessor;
+import com.netscape.cms.servlet.processors.PKIProcessor;
+
+
+/**
+ * KeyGenProcess parses Certificate request matching the
+ * KEYGEN tag format used by Netscape Communicator 4.x
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyGenProcessor extends PKIProcessor {
+
+ public KeyGenProcessor() {
+ super();
+ }
+
+ public KeyGenProcessor(CMSRequest cmsReq, CMSServlet servlet) {
+ super(cmsReq, servlet);
+
+ }
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException {
+ }
+
+ public void fillCertInfo(
+ String protocolString, X509CertInfo certInfo,
+ IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+
+ CMS.debug("KeyGenProcessor: fillCertInfo");
+
+ if (mServlet == null) {
+ return;
+ }
+
+ KeyGenInfo keyGenInfo = httpParams.getValueAsKeyGenInfo(
+ PKIProcessor.SUBJECT_KEYGEN_INFO, null);
+
+ // fill key
+ X509Key key = null;
+
+ key = keyGenInfo.getSPKI();
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_MISSING_KEY_IN_KEYGENINFO"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_KEY_IN_KEYGENINFO"));
+ }
+ try {
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ "Could not set key into certInfo from keygen. Error " + e);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_KEYGEN_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_KEYGEN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_KEYGEN_FAILED", e.toString()));
+ }
+
+ String authMgr = mServlet.getAuthMgr();
+
+ // if not authenticated, fill subject name, validity & extensions
+ // from authtoken.
+ if (authToken == null) {
+ fillCertInfoFromForm(certInfo, httpParams);
+ } else {
+ if (authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) == null) {
+ // allow special case for agent gateway in admin enroll
+ // and bulk issuance.
+ if (!authMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID) &&
+ !authMgr.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ }
+ fillCertInfoFromForm(certInfo, httpParams);
+ } else {
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java
new file mode 100644
index 000000000..bcbe839c1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java
@@ -0,0 +1,342 @@
+// --- 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.servlet.processors;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Hashtable;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerValue;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import java.math.*;
+
+import com.netscape.cms.servlet.processors.IPKIProcessor;
+import com.netscape.cms.servlet.processors.PKIProcessor;
+
+
+/**
+ * PKCS10Processor process Certificate Requests in
+ * PKCS10 format, as defined here:
+ * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-10/index.html
+ *
+ * @version $Revision$, $Date$
+ */
+public class PKCS10Processor extends PKIProcessor {
+
+ private PKCS10 mPkcs10 = null;
+
+ private final String USE_INTERNAL_PKCS10 = "internal";
+
+ public PKCS10Processor() {
+
+ super();
+ }
+
+ public PKCS10Processor(CMSRequest cmsReq, CMSServlet servlet) {
+ super(cmsReq, servlet);
+
+ }
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException {
+ }
+
+ public void fillCertInfo(
+ PKCS10 pkcs10, X509CertInfo certInfo,
+ IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+
+ mPkcs10 = pkcs10;
+
+ fillCertInfo(USE_INTERNAL_PKCS10, certInfo, authToken, httpParams);
+
+ }
+
+ public void fillCertInfo(
+ String protocolString, X509CertInfo certInfo,
+ IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+
+ PKCS10 p10 = null;
+
+ CMS.debug("PKCS10Processor:fillCertInfo");
+
+ if (protocolString == null) {
+ p10 = getPKCS10(httpParams);
+ } else if (protocolString.equals(USE_INTERNAL_PKCS10)) {
+ p10 = mPkcs10;
+ } else {
+ CMS.debug( "PKCS10Processor::fillCertInfo() - p10 is null!" );
+ throw new EBaseException( "p10 is null" );
+ }
+
+ if (mServlet == null) {
+ EBaseException ex = new ECMSGWException("Servlet property of PKCS10Processor is null.");
+
+ throw ex;
+
+ }
+
+ // fill key
+ X509Key key = p10.getSubjectPublicKeyInfo();
+
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_MISSING_KEY_IN_P10"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_MISSING_KEY_IN_P10"));
+ }
+ CertificateX509Key certKey = new CertificateX509Key(key);
+
+ try {
+ certInfo.set(X509CertInfo.KEY, certKey);
+ } catch (CertificateException e) {
+ EBaseException ex = new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_P10_FAILED", e.toString()));
+
+ log(ILogger.LL_FAILURE, ex.toString());
+ throw ex;
+ } catch (IOException e) {
+ EBaseException ex = new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_P10_FAILED", e.toString()));
+
+ log(ILogger.LL_FAILURE, ex.toString());
+ throw ex;
+ }
+
+ X500Name subject = p10.getSubjectName();
+
+ if (subject != null) {
+ try {
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+ log(ILogger.LL_INFO,
+ "Setting subject name " + subject + " from p10.");
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_SUBJECT_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_FROM_P10_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_SUBJECT_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_FROM_P10_FAILED", e.toString()));
+ } catch (Exception e) {
+ // if anything bad happens in X500 name parsing,
+ // this will catch it.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_SUBJECT_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_FROM_P10_FAILED", e.toString()));
+ }
+ } else if (authToken == null ||
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SUBJECT_IN_P10"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_IN_P10"));
+ }
+
+ // fill extensions from pkcs 10 attributes if any.
+ // other pkcs10 attributes are not recognized.
+ // ExtensionReq ::= SEQUENCE OF Extension
+ // ExtensionReq {pkcs-9 14}.
+ try {
+ PKCS10Attributes p10Attrs = p10.getAttributes();
+
+ if (p10Attrs != null) {
+ PKCS10Attribute p10Attr = (PKCS10Attribute)
+ (p10Attrs.getAttribute(CertificateExtensions.NAME));
+
+ if (p10Attr != null && p10Attr.getAttributeId().equals(
+ PKCS9Attribute.EXTENSION_REQUEST_OID)) {
+ Extensions exts0 = (Extensions)
+ (p10Attr.getAttributeValue());
+ DerOutputStream extOut = new DerOutputStream();
+
+ exts0.encode(extOut);
+ byte[] extB = extOut.toByteArray();
+ DerInputStream extIn = new DerInputStream(extB);
+ CertificateExtensions exts = new CertificateExtensions(extIn);
+
+ if (exts != null) {
+ certInfo.set(X509CertInfo.EXTENSIONS, exts);
+ }
+ }
+ }
+ CMS.debug(
+ "PKCS10Processor: Seted cert extensions from pkcs10. ");
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_EXTENSIONS_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_P10_FAILED", e.toString()));
+
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_EXTENSIONS_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_P10_FAILED", e.toString()));
+ } catch (Exception e) {
+ // if anything bad happens in extensions parsing,
+ // this will catch it.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_EXTENSIONS_FROM_P10", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_P10_FAILED", e.toString()));
+ }
+
+ // override pkcs10 attributes with authtoken attributes
+ // like subject name, validity and extensions if any.
+ // adminEnroll is an exception
+ String authMgr = mServlet.getAuthMgr();
+
+ if (authToken != null &&
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) != null &&
+ !(authMgr.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID))) {
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ }
+
+ // SPECIAL CASE:
+ // if it is adminEnroll servlet, get the validity
+ // from the http parameters.
+ if (mServletId.equals(PKIProcessor.ADMIN_ENROLL_SERVLET_ID)) {
+ fillValidityFromForm(certInfo, httpParams);
+ }
+
+ }
+
+ private PKCS10 getPKCS10(IArgBlock httpParams)
+ throws EBaseException {
+
+ PKCS10 pkcs10 = null;
+
+ String certType = null;
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(PKIProcessor.OLD_CERT_TYPE, null);
+ if (certType == null) {
+ certType = httpParams.getValueAsString(PKIProcessor.CERT_TYPE, "client");
+ } else {
+ // some policies may rely on the fact that
+ // CERT_TYPE is set. So for 3.5.1 or eariler
+ // we need to set CERT_TYPE but not here.
+ }
+ if (certType.equals("client")) {
+ // coming from MSIE
+ String p10b64 = httpParams.getValueAsString(PKIProcessor.PKCS10_REQUEST, null);
+
+ if (p10b64 != null) {
+ try {
+ byte[] bytes = CMS.AtoB(p10b64);
+
+ pkcs10 = new PKCS10(bytes);
+ } catch (Exception e) {
+ // ok, if the above fails, it could
+ // be a PKCS10 with header
+ pkcs10 = httpParams.getValueAsPKCS10(PKIProcessor.PKCS10_REQUEST, false, null);
+ // e.printStackTrace();
+ }
+ }
+
+ //pkcs10 = httpParams.getValuePKCS10(PKCS10_REQUEST, null);
+
+ } else {
+ try {
+ // coming from server cut & paste blob.
+ pkcs10 = httpParams.getValueAsPKCS10(PKIProcessor.PKCS10_REQUEST, false, null);
+ }catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ return pkcs10;
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java b/pki/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java
new file mode 100644
index 000000000..e1aea796b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java
@@ -0,0 +1,417 @@
+// --- 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.servlet.processors;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Hashtable;
+
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerValue;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.ChallengeResponseException;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.pkcs11.*;
+
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.RequestId;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.cms.servlet.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import java.math.*;
+
+import com.netscape.cms.servlet.processors.IPKIProcessor;
+
+
+/**
+ * Process Certificate Requests
+ *
+ * @version $Revision$, $Date$
+ */
+public class PKIProcessor implements IPKIProcessor {
+
+ public final static String ADMIN_ENROLL_SERVLET_ID = "caadminEnroll";
+ public static final String SUBJECT_NAME = "subject";
+ public static final String OLD_CERT_TYPE = "csrCertType";
+ public static final String CERT_TYPE = "certType";
+ public static final String PKCS10_REQUEST = "pkcs10Request";
+ public static final String SUBJECT_KEYGEN_INFO = "subjectKeyGenInfo";
+
+ protected CMSRequest mRequest = null;
+
+ protected HttpServletRequest httpReq = null;
+ protected String mServletId = null;
+ protected CMSServlet mServlet = null;
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ public PKIProcessor() {
+ }
+
+ public PKIProcessor(CMSRequest cmsReq, CMSServlet servlet) {
+ mRequest = cmsReq;
+
+ mServlet = servlet;
+
+ if (mServlet == null || mRequest == null) {
+ return;
+ }
+
+ mServletId = servlet.getId();
+
+ HttpServletRequest httpReq = mRequest.getHttpReq();
+
+ }
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException {
+ }
+
+ protected void fillCertInfo(
+ String protocolString, X509CertInfo certInfo,
+ IAuthToken authToken, IArgBlock httpParams)
+ throws EBaseException {
+ }
+
+ protected X509CertInfo[] fillCertInfoArray(
+ String protocolString, IAuthToken authToken, IArgBlock httpParams, IRequest req)
+ throws EBaseException {
+ return null;
+ }
+
+ /**
+ * fill subject name, validity, extensions from authoken if any,
+ * overriding what was in pkcs10.
+ * fill subject name, extensions from http input if not authenticated.
+ * requests not authenticated will need to be approved by an agent.
+ */
+ public static void fillCertInfoFromAuthToken(
+ X509CertInfo certInfo, IAuthToken authToken)
+ throws EBaseException {
+ // override subject, validity and extensions from auth token
+ // CA determines algorithm, version and issuer.
+ // take key from keygen, cmc, pkcs10 or crmf.
+
+ CMS.debug("PKIProcessor: fillCertInfoFromAuthToken");
+ // subject name.
+ try {
+ String subjectname =
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT);
+
+ if (subjectname != null) {
+ CertificateSubjectName certSubject = (CertificateSubjectName)
+ new CertificateSubjectName(new X500Name(subjectname));
+
+ certInfo.set(X509CertInfo.SUBJECT, certSubject);
+ log(ILogger.LL_INFO,
+ "cert subject set to " + certSubject + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ }
+
+ // validity
+ try {
+ CertificateValidity validity = null;
+ Date notBefore =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTBEFORE);
+ Date notAfter =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTAFTER);
+
+ if (notBefore != null && notAfter != null) {
+ validity = new CertificateValidity(notBefore, notAfter);
+ certInfo.set(X509CertInfo.VALIDITY, validity);
+ log(ILogger.LL_INFO,
+ "cert validity set to " + validity + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ }
+
+ // extensions
+ try {
+ CertificateExtensions extensions =
+ authToken.getInCertExts(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ log(ILogger.LL_INFO, "cert extensions set from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ }
+ }
+
+ /**
+ * fill subject name, extension from form.
+ * this is done for unauthenticated requests.
+ * unauthenticated requests must be approved by agents so these will
+ * all be seen by and agent.
+ */
+ public static void fillCertInfoFromForm(
+ X509CertInfo certInfo, IArgBlock httpParams)
+ throws EBaseException {
+
+ CMS.debug("PKIProcessor: fillCertInfoFromForm");
+ // subject name.
+ try {
+ String subject = httpParams.getValueAsString(PKIProcessor.SUBJECT_NAME, null);
+
+ if (subject == null) {
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_FROM_FORM"));
+ }
+
+ X500Name x500name = new X500Name(subject);
+
+ certInfo.set(
+ X509CertInfo.SUBJECT, new CertificateSubjectName(x500name));
+
+ fillValidityFromForm(certInfo, httpParams);
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IllegalArgumentException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQ_ILLEGAL_CHARACTERS"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CONVERT_DN_TO_X500NAME_ERROR"));
+ }
+
+ // requested extensions.
+ // let polcies form extensions from http input.
+ }
+
+ public static void fillValidityFromForm(
+ X509CertInfo certInfo, IArgBlock httpParams)
+ throws EBaseException {
+ CMS.debug("PKIProcessor: fillValidityFromForm!");
+ try {
+ String notValidBeforeStr = httpParams.getValueAsString("notValidBefore", null);
+ String notValidAfterStr = httpParams.getValueAsString("notValidAfter", null);
+
+ if (notValidBeforeStr != null && notValidAfterStr != null) {
+ long notValidBefore = 0;
+ long notValidAfter = 0;
+
+ try {
+ notValidBefore = Long.parseLong(notValidBeforeStr);
+ } catch (NumberFormatException e) {
+ }
+ try {
+ notValidAfter = Long.parseLong(notValidAfterStr);
+ } catch (NumberFormatException e) {
+ }
+
+ if (notValidBefore > 0 && notValidAfter > 0) {
+ CertificateValidity validity = null;
+ Date notBefore = new Date(notValidBefore);
+ Date notAfter = new Date(notValidAfter);
+
+ if (notBefore != null && notAfter != null) {
+ validity = new CertificateValidity(notBefore, notAfter);
+ certInfo.set(X509CertInfo.VALIDITY, validity);
+ log(ILogger.LL_INFO,
+ "cert validity set to " + validity + " from authtoken");
+ }
+ }
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ }
+ }
+
+ /**
+ * log according to authority category.
+ */
+ public static void log(int event, int level, String msg) {
+ CMS.getLogger().log(event, ILogger.S_OTHER, level,
+ "PKIProcessor " + ": " + msg);
+ }
+
+ public static void log(int level, String msg) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level,
+ "PKIProcessor " + ": " + msg);
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java
new file mode 100644
index 000000000..8f3a0f688
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java
@@ -0,0 +1,519 @@
+// --- 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.servlet.profile;
+
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cms.servlet.common.*;
+
+
+/**
+ * Toggle the approval state of a profile
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileApproveServlet extends ProfileServlet {
+
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+ private String mAuthorityId = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL =
+ "LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL_4";
+ private final static String OP_APPROVE = "approve";
+ private final static String OP_DISAPPROVE = "disapprove";
+
+ public ProfileApproveServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+ }
+
+ /**
+ * Process the HTTP request.
+ * <P>
+ *
+ * <ul>
+ * <li>http.param profileId the id of the profile to change
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL used when an
+ * agent approves/disapproves a cert profile set by the administrator for
+ * automatic approval
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ * @exception EBaseException an error has occurred
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditProfileID = auditProfileID(request);
+ String auditProfileOp = auditProfileOp(request);
+
+ String userid = null;
+ IAuthToken authToken = null;
+ ArgSet args = new ArgSet();
+
+ Locale locale = getLocale(request);
+
+ IProfile profile = null;
+
+ String profileId = null;
+
+ IProfileSubsystem ps = null;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ try {
+ authToken = authenticate(cmsReq);
+ CMS.debug("uid=" + authToken.getInString("userid"));
+ userid = authToken.getInString("userid");
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE",
+ e.toString()));
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_ERROR"));
+ outputTemplate(request, response, args);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "approve");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE",
+ e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE",
+ e.toString()));
+ }
+
+ if (authzToken == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ CMS.debug("ProfileApproveServlet: start serving");
+ // (1) Read request from the database
+
+ // (2) Get profile id from the request
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileApproveServlet: SubId=" + mProfileSubId);
+ ps = (IProfileSubsystem) CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileApproveServlet: ProfileSubsystem not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ // retrieve request
+ IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority == null) {
+ CMS.debug("ProfileApproveServlet: 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);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+ IRequestQueue queue = authority.getRequestQueue();
+
+ if (queue == null) {
+ CMS.debug("ProfileApproveServlet: 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);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ profileId = request.getParameter("profileId");
+
+ CMS.debug("ProfileApproveServlet: profileId=" + profileId);
+
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ try {
+ if (ps.isProfileEnable(profileId)) {
+ if (ps.checkOwner()) {
+ if (ps.getProfileEnableBy(profileId).equals(userid)) {
+ ps.disableProfile(profileId);
+ } else {
+ // only enableBy can disable profile
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_OWNER"));
+ outputTemplate(request, response, args);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+ } else {
+ ps.disableProfile(profileId);
+ }
+ } else {
+ ps.enableProfile(profileId, userid);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+ } catch (EProfileException e) {
+ // profile not enabled
+ CMS.debug("ProfileApproveServlet: profile not error " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ return;
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditProfileID,
+ auditProfileOp);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ // } catch( ServletException eAudit2 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditProfileID,
+ // auditProfileOp );
+ //
+ // audit( auditMessage );
+ //
+ // // rethrow the specific exception to be handled later
+ // throw eAudit2;
+ }
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ // profile not found
+ CMS.debug("ProfileApproveServlet: profile not found " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, e.toString());
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ return;
+ }
+ if (profile == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ Enumeration policySetIds = profile.getProfilePolicySetIds();
+
+ ArgList setlist = new ArgList();
+
+ while (policySetIds.hasMoreElements()) {
+ String setId = (String) policySetIds.nextElement();
+
+ Enumeration policyIds = profile.getProfilePolicyIds(setId);
+ ArgList list = new ArgList();
+
+ while (policyIds.hasMoreElements()) {
+ String id = (String) policyIds.nextElement();
+ IProfilePolicy policy = (IProfilePolicy)
+ profile.getProfilePolicy(setId, id);
+
+ // (3) query all the profile policies
+ // (4) default plugins convert request parameters
+ // into string http parameters
+ handlePolicy(list, response, locale,
+ id, policy);
+ }
+ ArgSet setArg = new ArgSet();
+
+ setArg.set(ARG_POLICY_SET_ID, setId);
+ setArg.set(ARG_POLICY, list);
+ setlist.add(setArg);
+ }
+ args.set(ARG_POLICY_SET_LIST, setlist);
+
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_PROFILE_IS_ENABLED,
+ Boolean.toString(ps.isProfileEnable(profileId)));
+ args.set(ARG_PROFILE_ENABLED_BY, ps.getProfileEnableBy(profileId));
+ args.set(ARG_PROFILE_NAME, profile.getName(locale));
+ args.set(ARG_PROFILE_DESC, profile.getDescription(locale));
+
+ // (5) return info as template
+ outputTemplate(request, response, args);
+ }
+
+ private void handlePolicy(ArgList list, ServletResponse response,
+ Locale locale, String id, IProfilePolicy policy) {
+ ArgSet set = new ArgSet();
+
+ set.set(ARG_POLICY_ID, id);
+
+ // handle default policy
+ IPolicyDefault def = policy.getDefault();
+ String dDesc = def.getText(locale);
+
+ set.set(ARG_DEF_DESC, dDesc);
+
+ ArgList deflist = new ArgList();
+ Enumeration defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = (String) defNames.nextElement();
+ IDescriptor defDesc = def.getValueDescriptor(locale, defName);
+ if (defDesc == null) {
+ CMS.debug("defName=" + defName);
+ } else {
+ String defSyntax = defDesc.getSyntax();
+ String defConstraint = defDesc.getConstraint();
+ String defValueName = defDesc.getDescription(locale);
+ String defValue = null;
+
+ defset.set(ARG_DEF_ID, defName);
+ defset.set(ARG_DEF_SYNTAX, defSyntax);
+ defset.set(ARG_DEF_CONSTRAINT, defConstraint);
+ defset.set(ARG_DEF_NAME, defValueName);
+ defset.set(ARG_DEF_VAL, defValue);
+ deflist.add(defset);
+ }
+ }
+ }
+ set.set(ARG_DEF_LIST, deflist);
+
+ // handle constraint policy
+ IPolicyConstraint con = policy.getConstraint();
+ String conDesc = con.getText(locale);
+
+ set.set(ARG_CON_DESC, conDesc);
+
+ list.add(set);
+ }
+
+ /**
+ * Signed Audit Log Profile ID
+ *
+ * This method is called to obtain the "ProfileID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return id string containing the signed audit log message ProfileID
+ */
+ private String auditProfileID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String profileID = null;
+
+ // Obtain the profileID
+ profileID = req.getParameter("profileId");
+
+ if (profileID != null) {
+ profileID = profileID.trim();
+ } else {
+ profileID = ILogger.UNIDENTIFIED;
+ }
+
+ return profileID;
+ }
+
+ /**
+ * Signed Audit Log Profile Operation
+ *
+ * This method is called to obtain the "Profile Operation" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param req HTTP request
+ * @return operation string containing either OP_APPROVE, OP_DISAPPROVE,
+ * or SIGNED_AUDIT_EMPTY_VALUE
+ */
+ private String auditProfileOp(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (mProfileSubId == null ||
+ mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String profileID = auditProfileID(req);
+
+ if (profileID == ILogger.UNIDENTIFIED) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ if (ps.isProfileEnable(profileID)) {
+ return OP_DISAPPROVE;
+ } else {
+ return OP_APPROVE;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java
new file mode 100644
index 000000000..0090e6fdc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java
@@ -0,0 +1,169 @@
+// --- 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.servlet.profile;
+
+
+import java.util.Enumeration;
+import java.util.Locale;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+
+/**
+ * List all enabled profiles.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileListServlet extends ProfileServlet {
+
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+
+ private String mAuthorityId = null;
+
+ public ProfileListServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ CMS.debug("ProfileListServlet: start serving");
+
+ Locale locale = getLocale(request);
+
+ ArgSet args = new ArgSet();
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ // (1) Read request from the database
+
+ // (2) Get profile id from the request
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileListServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileListServlet: ProfileSubsystem " +
+ mProfileSubId + " not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ ArgList list = new ArgList();
+ Enumeration e = ps.getProfileIds();
+
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ String id = (String) e.nextElement();
+ IProfile profile = null;
+
+ try {
+ profile = ps.getProfile(id);
+ } catch (EBaseException e1) {
+ // skip bad profile
+ CMS.debug("ProfileListServlet: profile " + id +
+ " not found (skipped) " + e1.toString());
+ continue;
+ }
+ if (profile == null) {
+ CMS.debug("ProfileListServlet: profile " + id +
+ " not found (skipped)");
+ continue;
+ }
+
+ String name = profile.getName(locale);
+ String desc = profile.getDescription(locale);
+
+ ArgSet profileArgs = new ArgSet();
+
+ profileArgs.set(ARG_PROFILE_IS_ENABLED,
+ Boolean.toString(ps.isProfileEnable(id)));
+ profileArgs.set(ARG_PROFILE_ENABLED_BY,
+ ps.getProfileEnableBy(id));
+ profileArgs.set(ARG_PROFILE_ID, id);
+ profileArgs.set(ARG_PROFILE_IS_VISIBLE,
+ Boolean.toString(profile.isVisible()));
+ profileArgs.set(ARG_PROFILE_NAME, name);
+ profileArgs.set(ARG_PROFILE_DESC, desc);
+ list.add(profileArgs);
+
+ }
+ }
+ args.set(ARG_RECORD, list);
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ // (5) return info as template
+ outputTemplate(request, response, args);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
new file mode 100644
index 000000000..92cfa9bff
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
@@ -0,0 +1,936 @@
+// --- 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.servlet.profile;
+
+
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cms.servlet.common.*;
+
+import java.security.cert.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This servlet approves profile-based request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileProcessServlet extends ProfileServlet {
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+ private String mAuthorityId = null;
+ private Nonces mNonces = null;
+
+ private final static String SIGNED_AUDIT_CERT_REQUEST_REASON =
+ "requestNotes";
+ private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ public ProfileProcessServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+
+ ICertificateAuthority authority = null;
+ if (mAuthorityId != null)
+ authority = (ICertificateAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority != null && authority.noncesEnabled()) {
+ mNonces = authority.getNonces();
+ }
+ }
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("approval", true /* main action */);
+ }
+
+ IAuthToken authToken = null;
+ ArgSet args = new ArgSet();
+
+ Locale locale = getLocale(request);
+
+ if (mAuthMgr != null) {
+ try {
+ authToken = authenticate(cmsReq);
+ } catch (EBaseException e) {
+ CMS.debug("ProfileProcessServlet: " + e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_ERROR"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "approve");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ if (mNonces != null) {
+ String requestNonce = request.getParameter(ARG_REQUEST_NONCE);
+ boolean nonceVerified = false;
+ if (requestNonce != null) {
+ long nonce = Long.parseLong(requestNonce.trim());
+ X509Certificate cert1 = mNonces.getCertificate(nonce);
+ X509Certificate cert2 = getSSLClientCertificate(request);
+ if (cert1 == null) {
+ CMS.debug("ProfileProcessServlet: Unknown nonce");
+ } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) {
+ nonceVerified = true;
+ mNonces.removeNonce(nonce);
+ }
+ } else {
+ CMS.debug("ProfileProcessServlet: Missing nonce");
+ }
+ CMS.debug("ProfileProcessServlet: nonceVerified="+nonceVerified);
+ if (!nonceVerified) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ }
+
+ CMS.debug("ProfileProcessServlet: start serving");
+
+ // (1) Read request from the database
+
+ // (2) Get profile id from the request
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileProcessServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileProcessServlet: ProfileSubsystem not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ // retrieve request
+ IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority == null) {
+ CMS.debug("ProfileProcessServlet: 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);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ IRequestQueue queue = authority.getRequestQueue();
+
+ if (queue == null) {
+ CMS.debug("ProfileProcessServlet: 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);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ String requestId = request.getParameter("requestId");
+
+ if (requestId == null || requestId.equals("")) {
+ CMS.debug("ProfileProcessServlet: Request Id not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_REQUEST_ID_NOT_FOUND"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ IRequest req = null;
+
+ CMS.debug("ProfileProcessServlet: requestId=" + requestId);
+ try {
+ req = queue.findRequest(new RequestId(requestId));
+ } catch (EBaseException e) {
+ // request not found
+ CMS.debug("ProfileProcessServlet: request not found requestId=" +
+ requestId + " " + e.toString());
+ }
+ if (req == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_REQUEST_NOT_FOUND", requestId));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ // check if the request is in one of the terminal states
+ if (!req.getRequestStatus().equals(RequestStatus.PENDING)) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_REQUEST_NOT_PENDING", requestId));
+ args.set(ARG_REQUEST_ID, requestId);
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ String profileId = req.getExtDataInString("profileId");
+
+ CMS.debug("ProfileProcessServlet: profileId=" + profileId);
+ if (profileId == null || profileId.equals("")) {
+ CMS.debug("ProfileProcessServlet: Profile Id not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_ID_NOT_FOUND"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ String op = request.getParameter("op");
+ if (op == null) {
+ CMS.debug("ProfileProcessServlet: No op found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_OP_NOT_FOUND"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+
+ IProfile profile = null;
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ // profile not found
+ CMS.debug("ProfileProcessServlet: profile not found " +
+ " " + " profileId=" + profileId + " " + e.toString());
+ }
+ if (profile == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+ // if profile is currently disabled, dont do anything
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("ProfileProcessServlet: Profile Id not enabled");
+ args.set(ARG_OP, op);
+ args.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ args.set(ARG_REQUEST_STATUS, req.getRequestStatus().toString());
+ args.set(ARG_REQUEST_TYPE, req.getRequestType());
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_ID_NOT_ENABLED"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+
+
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ try {
+ if (op.equals("assign")) {
+ String owner = req.getRequestOwner();
+
+ // assigned owner
+ if (owner != null && owner.length() > 0) {
+ if (!grantPermission(req, authToken)) {
+ CMS.debug("ProfileProcessServlet: Permission not granted to assign request.");
+ args.set(ARG_OP, op);
+ args.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ args.set(ARG_REQUEST_STATUS, req.getRequestStatus().toString());
+ args.set(ARG_REQUEST_TYPE, req.getRequestType());
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ }
+ assignRequest(request, args, req, queue, profile, locale);
+ } else {
+ if (grantPermission(req, authToken)) {
+ if (op.equals("approve")) {
+ checkProfileVersion(profile, req, locale);
+ updateValues(request, req, queue, profile, locale);
+ updateNotes(request, req);
+ approveRequest(request, args, req, queue, profile, locale);
+ } else if (op.equals("reject")) {
+ updateNotes(request, req);
+ rejectRequest(request, args, req, queue, profile, locale);
+ } else if (op.equals("cancel")) {
+ updateNotes(request, req);
+ cancelRequest(request, args, req, queue, profile, locale);
+ } else if (op.equals("update")) {
+ checkProfileVersion(profile, req, locale);
+ updateValues(request, req, queue, profile, locale);
+ updateNotes(request, req);
+ } else if (op.equals("validate")) {
+ updateValues(request, req, queue, profile, locale);
+ } else if (op.equals("unassign")) {
+ unassignRequest(request, args, req, queue, profile, locale);
+ }
+ } else {
+ CMS.debug("ProfileProcessServlet: Permission not granted to approve/reject/cancel/update/validate/unassign request.");
+ args.set(ARG_OP, op);
+ args.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ args.set(ARG_REQUEST_STATUS, req.getRequestStatus().toString());
+ args.set(ARG_REQUEST_TYPE, req.getRequestType());
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ }
+
+ // commit request to the storage
+ if (!op.equals("validate")) {
+ try {
+ if (op.equals("approve")) {
+ queue.markAsServiced(req);
+ } else {
+ queue.updateRequest(req);
+ }
+ } catch (EBaseException e) {
+ CMS.debug("ProfileProcessServlet: Request commit error " +
+ e.toString());
+ // save request to disk
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ return;
+ }
+ }
+ } catch (ERejectException e) {
+ CMS.debug("ProfileProcessServlet: execution rejected " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_REJECTED", e.toString()));
+ } catch (EDeferException e) {
+ CMS.debug("ProfileProcessServlet: execution defered " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEFERRED", e.toString()));
+ } catch (EPropertyException e) {
+ CMS.debug("ProfileProcessServlet: execution error " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_PROPERTY_ERROR", e.toString()));
+ } catch (EProfileException e) {
+ CMS.debug("ProfileProcessServlet: execution error " +
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ }
+
+ args.set(ARG_OP, op);
+ args.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ args.set(ARG_REQUEST_STATUS, req.getRequestStatus().toString());
+ args.set(ARG_REQUEST_TYPE, req.getRequestType());
+ args.set(ARG_PROFILE_ID, profileId);
+ outputTemplate(request, response, args);
+ if (statsSub != null) {
+ statsSub.endTiming("approval");
+ }
+ }
+
+ public boolean grantPermission(IRequest req, IAuthToken token) {
+
+ try {
+ boolean enable = CMS.getConfigStore().getBoolean("request.assignee.enable",
+ false);
+ if (!enable)
+ return true;
+ String owner = req.getRequestOwner();
+
+ // unassigned owner
+ if (owner == null || owner.length() == 0)
+ return true;
+ String uid = token.getInString(IAuthToken.USER_ID);
+ if (uid.equals(owner))
+ return true;
+ } catch (Exception e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if the request creation time is older than the profile
+ * lastModified attribute.
+ */
+ protected void checkProfileVersion(IProfile profile, IRequest req,
+ Locale locale) throws EProfileException {
+ IConfigStore profileConfig = profile.getConfigStore();
+ if (profileConfig != null) {
+ String lastModified = null;
+ try {
+ lastModified = profileConfig.getString("lastModified","");
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ throw new EProfileException( e.toString() );
+ }
+ if (!lastModified.equals("")) {
+ Date profileModifiedAt = new Date(Long.parseLong(lastModified));
+ CMS.debug("ProfileProcessServlet: Profile Last Modified=" +
+ profileModifiedAt);
+ Date reqCreatedAt = req.getCreationTime();
+ CMS.debug("ProfileProcessServlet: Request Created At=" +
+ reqCreatedAt);
+ if (profileModifiedAt.after(reqCreatedAt)) {
+ CMS.debug("Profile Newer Than Request");
+ throw new ERejectException("Profile Newer Than Request");
+ }
+ }
+ }
+ }
+
+ protected void assignRequest(ServletRequest request, ArgSet args,
+ IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws EProfileException {
+
+ String id = auditSubjectID();
+ req.setRequestOwner(id);
+ }
+
+ protected void unassignRequest(ServletRequest request, ArgSet args,
+ IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws EProfileException {
+
+ req.setRequestOwner("");
+ }
+
+ /**
+ * Cancel request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert
+ * cancellation)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param request the servlet request
+ * @param args argument set
+ * @param req the certificate request
+ * @param queue the certificate request queue
+ * @param profile this profile
+ * @param locale the system locale
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ protected void cancelRequest(ServletRequest request, ArgSet args,
+ IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditInfoValue = auditInfoValue(req);
+
+ // try {
+ req.setRequestStatus(RequestStatus.CANCELED);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_CANCELLATION,
+ auditInfoValue);
+
+ audit(auditMessage);
+ // } catch( EProfileException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditRequesterID,
+ // ILogger.SIGNED_AUDIT_CANCELLATION,
+ // auditInfoValue );
+ //
+ // audit( auditMessage );
+ // }
+ }
+
+ /**
+ * Reject request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert
+ * rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param request the servlet request
+ * @param args argument set
+ * @param req the certificate request
+ * @param queue the certificate request queue
+ * @param profile this profile
+ * @param locale the system locale
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ protected void rejectRequest(ServletRequest request, ArgSet args,
+ IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditInfoValue = auditInfoValue(req);
+
+ // try {
+ req.setRequestStatus(RequestStatus.REJECTED);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ auditInfoValue);
+
+ audit(auditMessage);
+ // } catch( EProfileException eAudit1 ) {
+ // // store a message in the signed audit log file
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditRequesterID,
+ // ILogger.SIGNED_AUDIT_REJECTION,
+ // auditInfoValue );
+ //
+ // audit( auditMessage );
+ // }
+ }
+
+ /**
+ * Approve request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert
+ * acceptance)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param request the servlet request
+ * @param args argument set
+ * @param req the certificate request
+ * @param queue the certificate request queue
+ * @param profile this profile
+ * @param locale the system locale
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ protected void approveRequest(ServletRequest request, ArgSet args,
+ IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+
+ try {
+ profile.execute(req);
+ req.setRequestStatus(RequestStatus.COMPLETE);
+
+ ArgList outputlist = new ArgList();
+ Enumeration outputIds = profile.getProfileOutputIds();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = (String) outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(
+ outputId);
+
+ Enumeration outputNames = profileOutput.getValueNames();
+
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ ArgSet outputset = new ArgSet();
+ String outputName = (String)
+ outputNames.nextElement();
+ IDescriptor outputDesc =
+ profileOutput.getValueDescriptor(locale,
+ outputName);
+
+ if (outputDesc == null)
+ continue;
+ String outputSyntax = outputDesc.getSyntax();
+ String outputConstraint =
+ outputDesc.getConstraint();
+ String outputValueName =
+ outputDesc.getDescription(locale);
+ String outputValue = null;
+
+ try {
+ outputValue = profileOutput.getValue(
+ outputName,
+ locale, req);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitServlet: " +
+ e.toString());
+ }
+
+ outputset.set(ARG_OUTPUT_ID, outputName);
+ outputset.set(ARG_OUTPUT_SYNTAX, outputSyntax);
+ outputset.set(ARG_OUTPUT_CONSTRAINT,
+ outputConstraint);
+ outputset.set(ARG_OUTPUT_NAME, outputValueName);
+ outputset.set(ARG_OUTPUT_VAL, outputValue);
+ outputlist.add(outputset);
+ }
+ }
+ }
+ }
+ args.set(ARG_OUTPUT_LIST, outputlist);
+
+ // retrieve the certificate
+ X509CertImpl theCert = req.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(theCert));
+
+ audit(auditMessage);
+
+ } catch (EProfileException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+
+ CMS.debug("ProfileProcessServlet: about to throw EProfileException because of bad profile execute.");
+ throw new EProfileException(eAudit1.toString());
+
+
+ }
+ }
+
+ protected void updateValues(ServletRequest request, IRequest req,
+ IRequestQueue queue, IProfile profile, Locale locale)
+ throws ERejectException, EDeferException, EPropertyException {
+ String profileSetId = req.getExtDataInString("profileSetId");
+
+ Enumeration policies = profile.getProfilePolicies(profileSetId);
+ int count = 0;
+
+ while (policies.hasMoreElements()) {
+ IProfilePolicy policy = (IProfilePolicy) policies.nextElement();
+
+ setValue(locale, count, policy, req, request);
+ count++;
+ }
+
+ policies = profile.getProfilePolicies(profileSetId);
+ count = 0;
+ while (policies.hasMoreElements()) {
+ IProfilePolicy policy = (IProfilePolicy) policies.nextElement();
+
+ validate(locale, count, policy, req, request);
+ count++;
+ }
+
+ }
+
+ protected void updateNotes(ServletRequest request, IRequest req) {
+ String notes = request.getParameter(ARG_REQUEST_NOTES);
+
+ if (notes != null) {
+ req.setExtData("requestNotes", notes);
+ }
+ }
+
+ protected void validate(Locale locale, int count,
+ IProfilePolicy policy, IRequest req, ServletRequest request)
+ throws ERejectException, EDeferException {
+ IPolicyConstraint con = policy.getConstraint();
+
+ con.validate(req);
+ }
+
+ protected void setValue(Locale locale, int count,
+ IProfilePolicy policy, IRequest req, ServletRequest request)
+ throws EPropertyException {
+ // handle default policy
+ IPolicyDefault def = policy.getDefault();
+ Enumeration defNames = def.getValueNames();
+
+ while (defNames.hasMoreElements()) {
+ String defName = (String) defNames.nextElement();
+ String defValue = request.getParameter(defName);
+
+ def.setValue(defName, locale, req, defValue);
+ }
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = ILogger.UNIDENTIFIED;
+
+ if (request != null) {
+ // overwrite "requesterID" if and only if "id" != null
+ String id = request.getRequestId().toString();
+
+ if (id != null) {
+ requesterID = id.trim();
+ }
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Info Value
+ *
+ * This method is called to obtain the "reason" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return reason string containing the signed audit log message reason
+ */
+ private String auditInfoValue(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String reason = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ if (request != null) {
+ // overwrite "reason" if and only if "info" != null
+ String info =
+ request.getExtDataInString(SIGNED_AUDIT_CERT_REQUEST_REASON);
+
+ if (info != null) {
+ reason = info.trim();
+
+ // overwrite "reason" if and only if "reason" is empty
+ if (reason.equals("")) {
+ reason = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+ }
+
+ return reason;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param x509cert an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(X509CertImpl x509cert) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (!Character.isWhitespace(base64Data.charAt(i))) {
+ sb.append(base64Data.charAt(i));
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java
new file mode 100644
index 000000000..1591d5fdf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java
@@ -0,0 +1,436 @@
+// --- 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.servlet.profile;
+
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cms.servlet.common.*;
+
+
+/**
+ * This servlet allows reviewing of profile-based request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileReviewServlet extends ProfileServlet {
+
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+
+ private String mAuthorityId = null;
+ private Random mRandom = null;
+ private Nonces mNonces = null;
+
+ public ProfileReviewServlet() {
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+
+ ICertificateAuthority authority = null;
+ if (mAuthorityId != null)
+ authority = (ICertificateAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority != null && authority.noncesEnabled()) {
+ mNonces = authority.getNonces();
+ mRandom = new Random();
+ }
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param requestId the ID of the profile to review
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ CMS.debug("ProfileReviewServlet: start serving");
+
+ Locale locale = getLocale(request);
+ ArgSet args = new ArgSet();
+ IAuthToken authToken = null;
+
+ if (mAuthMgr != null) {
+ try {
+ authToken = authenticate(request);
+ } catch (EBaseException e) {
+ CMS.debug("ReviewReqServlet: " + e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ // (1) Read request from the database
+
+ // (2) Get profile id from the request
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileReviewServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileReviewServlet: ProfileSubsystem not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ // retrieve request
+ IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority == null) {
+ CMS.debug("ProfileReviewServlet: 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("ProfileReviewServlet: 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 requestId = request.getParameter("requestId");
+ IRequest req = null;
+
+ CMS.debug("ProfileReviewServlet: requestId=" + requestId);
+ try {
+ req = queue.findRequest(new RequestId(requestId));
+ } catch (EBaseException e) {
+ // request not found
+ CMS.debug("ProfileReviewServlet: request not found requestId=" +
+ requestId + " " + e.toString());
+ }
+ if (req == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_REQUEST_NOT_FOUND", requestId));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ String profileId = req.getExtDataInString("profileId");
+
+ CMS.debug("ProfileReviewServlet: requestId=" +
+ requestId + " profileId=" + profileId);
+ IProfile profile = null;
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ // profile not found
+ CMS.debug("ProfileReviewServlet: profile not found requestId=" +
+ requestId + " profileId=" + profileId + " " + e.toString());
+ }
+ if (profile == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ String profileSetId = req.getExtDataInString("profileSetId");
+
+ CMS.debug("ProfileReviewServlet: profileSetId=" + profileSetId);
+ Enumeration policyIds = (profileSetId != null && profileSetId.length() > 0)?
+ profile.getProfilePolicyIds(profileSetId): null;
+ int count = 0;
+ ArgList list = new ArgList();
+
+ if (policyIds != null) {
+ while (policyIds.hasMoreElements()) {
+ String id = (String) policyIds.nextElement();
+ IProfilePolicy policy = (IProfilePolicy)
+ profile.getProfilePolicy(req.getExtDataInString("profileSetId"),
+ id);
+
+ // (3) query all the profile policies
+ // (4) default plugins convert request parameters into string
+ // http parameters
+ handlePolicy(list, response, locale,
+ id, policy, req);
+ count++;
+ }
+ }
+
+ if (mNonces != null) {
+ long n = mRandom.nextLong();
+ long m = mNonces.addNonce(n, getSSLClientCertificate(request));
+ if ((n + m) != 0) {
+ args.set(ARG_REQUEST_NONCE, Long.toString(m));
+ }
+ }
+
+ args.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ args.set(ARG_REQUEST_TYPE, req.getRequestType());
+ args.set(ARG_REQUEST_STATUS, req.getRequestStatus().toString());
+ if (req.getRequestOwner() == null) {
+ args.set(ARG_REQUEST_OWNER, "");
+ } else {
+ args.set(ARG_REQUEST_OWNER, req.getRequestOwner());
+ }
+ args.set(ARG_REQUEST_CREATION_TIME, req.getCreationTime().toString());
+ args.set(ARG_REQUEST_MODIFICATION_TIME,
+ req.getModificationTime().toString());
+
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_PROFILE_APPROVED_BY,
+ req.getExtDataInString("profileApprovedBy"));
+ args.set(ARG_PROFILE_SET_ID, req.getExtDataInString("profileSetId"));
+ if (profile.isVisible()) {
+ args.set(ARG_PROFILE_IS_VISIBLE, "true");
+ } else {
+ args.set(ARG_PROFILE_IS_VISIBLE, "false");
+ }
+ args.set(ARG_PROFILE_NAME, profile.getName(locale));
+ args.set(ARG_PROFILE_DESC, profile.getDescription(locale));
+ args.set(ARG_PROFILE_REMOTE_HOST,
+ req.getExtDataInString("profileRemoteHost"));
+ args.set(ARG_PROFILE_REMOTE_ADDR,
+ req.getExtDataInString("profileRemoteAddr"));
+ if (req.getExtDataInString("requestNotes") == null) {
+ args.set(ARG_REQUEST_NOTES, "");
+ } else {
+ args.set(ARG_REQUEST_NOTES,
+ req.getExtDataInString("requestNotes"));
+ }
+
+ args.set(ARG_RECORD, list);
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ ArgList inputlist = new ArgList();
+
+ // populate authentication parameters
+
+ // populate input parameters
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+
+ Enumeration inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ ArgSet inputset = new ArgSet();
+ String inputName = (String) inputNames.nextElement();
+
+ IDescriptor inputDesc = profileInput.getValueDescriptor(locale, inputName);
+
+ if (inputDesc == null)
+ continue;
+ String inputSyntax = inputDesc.getSyntax();
+ String inputConstraint = inputDesc.getConstraint();
+ String inputValueName = inputDesc.getDescription(locale);
+ String inputValue = null;
+
+ try {
+ inputValue = profileInput.getValue(inputName, locale, req);
+ } catch (EBaseException e) {
+ CMS.debug("ProfileReviewServlet: " + e.toString());
+ }
+
+ inputset.set(ARG_INPUT_ID, inputName);
+ inputset.set(ARG_INPUT_SYNTAX, inputSyntax);
+ inputset.set(ARG_INPUT_CONSTRAINT, inputConstraint);
+ inputset.set(ARG_INPUT_NAME, inputValueName);
+ inputset.set(ARG_INPUT_VAL, inputValue);
+ inputlist.add(inputset);
+ }
+ }
+ }
+ }
+ args.set(ARG_INPUT_LIST, inputlist);
+
+ // if request in complete state
+
+ ArgList outputlist = new ArgList();
+ Enumeration outputIds = profile.getProfileOutputIds();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = (String) outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId
+ );
+
+ Enumeration outputNames = profileOutput.getValueNames();
+
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ ArgSet outputset = new ArgSet();
+ String outputName = (String) outputNames.nextElement
+ ();
+ IDescriptor outputDesc =
+ profileOutput.getValueDescriptor(locale, outputName);
+
+ if (outputDesc == null)
+ continue;
+ String outputSyntax = outputDesc.getSyntax();
+ String outputConstraint = outputDesc.getConstraint();
+ String outputValueName = outputDesc.getDescription(locale);
+ String outputValue = null;
+
+ try {
+ outputValue = profileOutput.getValue(outputName,
+ locale, req);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitServlet: " + e.toString(
+ ));
+ }
+
+ outputset.set(ARG_OUTPUT_ID, outputName);
+ outputset.set(ARG_OUTPUT_SYNTAX, outputSyntax);
+ outputset.set(ARG_OUTPUT_CONSTRAINT, outputConstraint);
+ outputset.set(ARG_OUTPUT_NAME, outputValueName);
+ outputset.set(ARG_OUTPUT_VAL, outputValue);
+ outputlist.add(outputset);
+ }
+ }
+ }
+ }
+ args.set(ARG_OUTPUT_LIST, outputlist);
+
+ // (5) return info as template
+ outputTemplate(request, response, args);
+ }
+
+ private void handlePolicy(ArgList list, ServletResponse response,
+ Locale locale, String id, IProfilePolicy policy,
+ IRequest req) {
+ ArgSet set = new ArgSet();
+
+ set.set(ARG_POLICY_ID, id);
+
+ // handle default policy
+ IPolicyDefault def = policy.getDefault();
+ String dDesc = def.getText(locale);
+
+ set.set(ARG_DEF_DESC, dDesc);
+ ArgList deflist = new ArgList();
+ Enumeration defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = (String) defNames.nextElement();
+ IDescriptor defDesc = def.getValueDescriptor(locale, defName);
+
+ if (defDesc == null)
+ continue;
+ String defSyntax = defDesc.getSyntax();
+ String defConstraint = defDesc.getConstraint();
+ String defValueName = defDesc.getDescription(locale);
+ String defValue = null;
+
+ try {
+ defValue = def.getValue(defName, locale, req);
+ } catch (EPropertyException ee) {
+ CMS.debug("ProfileReviewServlet: " + ee.toString());
+ }
+
+ defset.set(ARG_DEF_ID, defName);
+ defset.set(ARG_DEF_SYNTAX, defSyntax);
+ defset.set(ARG_DEF_CONSTRAINT, defConstraint);
+ defset.set(ARG_DEF_NAME, defValueName);
+ defset.set(ARG_DEF_VAL, defValue);
+ deflist.add(defset);
+ }
+ }
+ set.set(ARG_DEF_LIST, deflist);
+
+ // handle constraint policy
+ IPolicyConstraint con = policy.getConstraint();
+
+ if (con != null) {
+ String conDesc = con.getText(locale);
+
+ set.set(ARG_CON_DESC, conDesc);
+ }
+
+ list.add(set);
+ }
+}
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
new file mode 100644
index 000000000..7d0edbbc0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
@@ -0,0 +1,401 @@
+// --- 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.servlet.profile;
+
+
+import com.netscape.cms.servlet.common.*;
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cms.servlet.common.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * Retrieve detailed information of a particular profile.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileSelectServlet extends ProfileServlet {
+
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+ private String mAuthorityId = null;
+
+ public ProfileSelectServlet() {
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param profileId the id of the profile to select
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ CMS.debug("ProfileSelectServlet: start serving");
+
+ Locale locale = getLocale(request);
+
+ IAuthToken authToken = null;
+ ArgSet args = new ArgSet();
+
+ if (mAuthMgr != null) {
+ try {
+ authToken = authenticate(request);
+ } catch (EBaseException e) {
+ CMS.debug("ProcessReqServlet: " + e.toString());
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ // (1) Read request from the database
+
+ // (2) Get profile id from the request
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileSelectServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileSelectServlet: ProfileSubsystem not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ // retrieve request
+ IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId);
+
+ if (authority == null) {
+ CMS.debug("ProfileSelectServlet: 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("ProfileSelectServlet: 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;
+ }
+
+ IProfile profile = null;
+
+ String profileId = request.getParameter("profileId");
+
+ CMS.debug("ProfileSelectServlet: profileId=" + profileId);
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ // profile not found
+ CMS.debug("ProfileSelectServlet: profile not found profileId=" +
+ profileId + " " + e.toString());
+ }
+ if (profile == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ ArgList setlist = new ArgList();
+ Enumeration policySetIds = profile.getProfilePolicySetIds();
+
+ if (policySetIds != null) {
+ while (policySetIds.hasMoreElements()) {
+ String setId = (String) policySetIds.nextElement();
+
+ ArgList list = new ArgList();
+ Enumeration policyIds = profile.getProfilePolicyIds(setId);
+
+ if (policyIds != null) {
+ while (policyIds.hasMoreElements()) {
+ String id = (String) policyIds.nextElement();
+ IProfilePolicy policy = (IProfilePolicy)
+ profile.getProfilePolicy(setId, id);
+
+ // (3) query all the profile policies
+ // (4) default plugins convert request parameters into string
+ // http parameters
+ handlePolicy(list, response, locale,
+ id, policy);
+ }
+ }
+ ArgSet setArg = new ArgSet();
+
+ setArg.set(ARG_POLICY_SET_ID, setId);
+ setArg.set(ARG_POLICY, list);
+ setlist.add(setArg);
+ }
+ }
+ args.set(ARG_POLICY_SET_LIST, setlist);
+
+ args.set(ARG_PROFILE_ID, profileId);
+ args.set(ARG_PROFILE_IS_ENABLED,
+ Boolean.toString(ps.isProfileEnable(profileId)));
+ args.set(ARG_PROFILE_ENABLED_BY, ps.getProfileEnableBy(profileId));
+ args.set(ARG_PROFILE_NAME, profile.getName(locale));
+ args.set(ARG_PROFILE_DESC, profile.getDescription(locale));
+ args.set(ARG_PROFILE_IS_VISIBLE,
+ Boolean.toString(profile.isVisible()));
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ try {
+ boolean keyArchivalEnabled = CMS.getConfigStore().getBoolean("ca.connector.KRA.enable", false);
+ if (keyArchivalEnabled == true) {
+ CMS.debug("ProfileSelectServlet: keyArchivalEnabled is true");
+
+ // output transport certificate if present
+ args.set("transportCert",
+ CMS.getConfigStore().getString("ca.connector.KRA.transportCert", ""));
+ } else {
+ CMS.debug("ProfileSelectServlet: keyArchivalEnabled is false");
+ args.set("transportCert", "");
+ }
+ } catch (EBaseException e) {
+ CMS.debug("ProfileSelectServlet: exception caught:"+e.toString());
+ }
+
+ // build authentication
+ ArgList authlist = new ArgList();
+ IProfileAuthenticator authenticator = null;
+
+ try {
+ authenticator = profile.getAuthenticator();
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_MANAGER_NOT_FOUND",
+ profile.getAuthenticatorId()));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ if (authenticator != null) {
+ Enumeration authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ ArgSet authset = new ArgSet();
+ String authName = (String) authNames.nextElement();
+ IDescriptor authDesc =
+ authenticator.getValueDescriptor(locale, authName);
+
+ if (authDesc == null)
+ continue;
+ String authSyntax = authDesc.getSyntax();
+ String authConstraint = authDesc.getConstraint();
+ String authValueName = authDesc.getDescription(locale);
+
+ authset.set(ARG_AUTH_ID, authName);
+ authset.set(ARG_AUTH_SYNTAX, authSyntax);
+ authset.set(ARG_AUTH_CONSTRAINT, authConstraint);
+ authset.set(ARG_AUTH_NAME, authValueName);
+ authlist.add(authset);
+ }
+ }
+ args.set(ARG_AUTH_LIST, authlist);
+ args.set(ARG_AUTH_NAME, authenticator.getName(locale));
+ args.set(ARG_AUTH_DESC, authenticator.getText(locale));
+ args.set(ARG_AUTH_IS_SSL,
+ Boolean.toString(authenticator.isSSLClientRequired()));
+ }
+
+ // build input list
+ ArgList inputlist = new ArgList();
+ ArgList inputPluginlist = new ArgList();
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+
+ if (profileInput != null) {
+
+ ArgSet inputpluginset = new ArgSet();
+ inputpluginset.set(ARG_INPUT_PLUGIN_ID, inputId);
+ inputpluginset.set(ARG_INPUT_PLUGIN_NAME,
+ profileInput.getName(locale));
+ inputpluginset.set(ARG_INPUT_PLUGIN_DESC,
+ profileInput.getText(locale));
+ inputPluginlist.add(inputpluginset);
+
+ Enumeration inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ ArgSet inputset = new ArgSet();
+ String inputName = (String) inputNames.nextElement();
+ IDescriptor inputDesc = profileInput.getValueDescriptor(
+ locale, inputName);
+
+ if (inputDesc == null)
+ continue;
+ String inputSyntax = inputDesc.getSyntax();
+ String inputConstraint = inputDesc.getConstraint();
+ String inputValueName = inputDesc.getDescription(locale);
+ String inputValue = null;
+
+ inputset.set(ARG_INPUT_PLUGIN_ID, inputId);
+ inputset.set(ARG_INPUT_ID, inputName);
+ inputset.set(ARG_INPUT_SYNTAX, inputSyntax);
+ inputset.set(ARG_INPUT_CONSTRAINT, inputConstraint);
+ inputset.set(ARG_INPUT_NAME, inputValueName);
+ inputset.set(ARG_INPUT_VAL, inputValue);
+ inputlist.add(inputset);
+ }
+ }
+ }
+ }
+ }
+ args.set(ARG_INPUT_LIST, inputlist);
+ args.set(ARG_INPUT_PLUGIN_LIST, inputPluginlist);
+ args.set(ARG_IS_RENEWAL, profile.isRenewal());
+ args.set(ARG_XML_OUTPUT, profile.isXmlOutput());
+
+ // (5) return info as template
+ outputTemplate(request, response, args);
+ }
+
+ private void handlePolicy(ArgList list, ServletResponse response,
+ Locale locale, String id, IProfilePolicy policy) {
+ ArgSet set = new ArgSet();
+
+ set.set(ARG_POLICY_ID, id);
+
+ // handle default policy
+ IPolicyDefault def = policy.getDefault();
+ String dDesc = def.getText(locale);
+
+ set.set(ARG_DEF_DESC, dDesc);
+ ArgList deflist = new ArgList();
+ Enumeration defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = (String) defNames.nextElement();
+ IDescriptor defDesc = def.getValueDescriptor(locale, defName);
+
+ if (defDesc == null)
+ continue;
+ String defSyntax = defDesc.getSyntax();
+ String defConstraint = defDesc.getConstraint();
+ String defValueName = defDesc.getDescription(locale);
+ String defValue = null;
+
+ defset.set(ARG_DEF_ID, defName);
+ defset.set(ARG_DEF_SYNTAX, defSyntax);
+ defset.set(ARG_DEF_CONSTRAINT, defConstraint);
+ defset.set(ARG_DEF_NAME, defValueName);
+ defset.set(ARG_DEF_VAL, defValue);
+ deflist.add(defset);
+ }
+ }
+ set.set(ARG_DEF_LIST, deflist);
+
+ // handle constraint policy
+ IPolicyConstraint con = policy.getConstraint();
+ String conDesc = con.getText(locale);
+
+ set.set(ARG_CON_DESC, conDesc);
+ ArgList conlist = new ArgList();
+ Enumeration conNames = con.getConfigNames();
+ if (conNames != null) {
+ while (conNames.hasMoreElements()) {
+ ArgSet conset = new ArgSet();
+ String conName = (String) conNames.nextElement();
+ conset.set(ARG_CON_NAME, conName);
+ conset.set(ARG_CON_VALUE, con.getConfig(conName));
+ conlist.add(conset);
+ }
+ }
+ set.set(ARG_CON_LIST, conlist);
+
+ list.add(set);
+ }
+
+}
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
new file mode 100644
index 000000000..40132290a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
@@ -0,0 +1,499 @@
+// --- 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.servlet.profile;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authentication.AuthCredentials;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This servlet is the base class of all profile servlets.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileServlet extends CMSServlet {
+
+ public final static String ARG_ERROR_CODE = "errorCode";
+ public final static String ARG_ERROR_REASON = "errorReason";
+ public final static String ARG_RECORD = "record";
+ public final static String ARG_OP = "op";
+
+ public final static String ARG_REQUEST_LIST = "requestList";
+ public final static String ARG_REQUEST_ID = "requestId";
+ public final static String ARG_REQUEST_TYPE = "requestType";
+ public final static String ARG_REQUEST_STATUS = "requestStatus";
+ public final static String ARG_REQUEST_OWNER =
+ "requestOwner";
+ public final static String ARG_REQUEST_CREATION_TIME =
+ "requestCreationTime";
+ public final static String ARG_REQUEST_MODIFICATION_TIME =
+ "requestModificationTime";
+ public final static String ARG_REQUEST_NONCE = "nonce";
+
+ public final static String ARG_AUTH_ID = "authId";
+ public final static String ARG_AUTH_SYNTAX = "authSyntax";
+ public final static String ARG_AUTH_CONSTRAINT = "authConstraint";
+ public final static String ARG_AUTH_NAME = "authName";
+ public final static String ARG_AUTH_LIST = "authList";
+ public final static String ARG_AUTH_DESC = "authDesc";
+ public final static String ARG_AUTH_IS_SSL = "authIsSSLClientRequired";
+ 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";
+ public final static String ARG_PROFILE_APPROVED_BY = "profileApprovedBy";
+ public final static String ARG_PROFILE_NAME = "profileName";
+ public final static String ARG_PROFILE_DESC = "profileDesc";
+ public final static String ARG_PROFILE_REMOTE_HOST = "profileRemoteHost";
+ public final static String ARG_PROFILE_REMOTE_ADDR = "profileRemoteAddr";
+ public final static String ARG_DEF_ID = "defId";
+ public final static String ARG_DEF_SYNTAX = "defSyntax";
+ public final static String ARG_DEF_CONSTRAINT = "defConstraint";
+ public final static String ARG_DEF_NAME = "defName";
+ public final static String ARG_DEF_VAL = "defVal";
+ public final static String ARG_DEF_DESC = "defDesc";
+ public final static String ARG_DEF_LIST = "defList";
+ public final static String ARG_CON_DESC = "conDesc";
+ public final static String ARG_CON_LIST = "constraint";
+ public final static String ARG_CON_NAME = "name";
+ public final static String ARG_CON_VALUE = "value";
+ public final static String ARG_PROFILE_SET_ID = "profileSetId";
+ public final static String ARG_POLICY_SET_ID = "setId";
+ public final static String ARG_POLICY = "policy";
+ public final static String ARG_POLICY_ID = "policyId";
+ public final static String ARG_POLICY_SET_LIST = "policySetList";
+ public final static String ARG_INPUT_PLUGIN_LIST = "inputPluginList";
+ public final static String ARG_INPUT_PLUGIN_ID = "inputPluginId";
+ public final static String ARG_INPUT_PLUGIN_NAME = "inputPluginName";
+ public final static String ARG_INPUT_PLUGIN_DESC = "inputPluginDesc";
+ public final static String ARG_INPUT_LIST = "inputList";
+ public final static String ARG_INPUT_ID = "inputId";
+ public final static String ARG_INPUT_SYNTAX = "inputSyntax";
+ 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_XML_OUTPUT = "xmlOutput";
+ public final static String ARG_OUTPUT_LIST = "outputList";
+ public final static String ARG_OUTPUT_ID = "outputId";
+ public final static String ARG_OUTPUT_SYNTAX = "outputSyntax";
+ public final static String ARG_OUTPUT_CONSTRAINT = "outputConstraint";
+ public final static String ARG_OUTPUT_NAME = "outputName";
+ public final static String ARG_OUTPUT_VAL = "outputVal";
+
+ private static final String PROP_TEMPLATE = "templatePath";
+ private static final String PROP_AUTH_MGR_ID = "authMgrId";
+ private final static String PROP_AUTHMGR = "AuthMgr";
+ private final static String PROP_CLIENTAUTH = "GetClientCert";
+ private static final String PROP_PROFILE_SUB_ID = "profileSubId";
+ private static final String PROP_ID = "ID";
+ public final static String PROP_RESOURCEID = "resourceID";
+ public final static String AUTHZ_SRC_LDAP = "ldap";
+ public final static String AUTHZ_SRC_TYPE = "sourceType";
+ public final static String AUTHZ_CONFIG_STORE = "authz";
+ public final static String AUTHZ_SRC_XML = "web.xml";
+ public final static String PROP_AUTHZ_MGR = "AuthzMgr";
+ public final static String PROP_ACL = "ACLinfo";
+ public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz";
+ public final static String AUTHZ_MGR_LDAP = "DirAclAuthz";
+
+ private final static String HDR_LANG = "accept-language";
+
+ private String mTemplate = null;
+ private String mAuthMgrId = null;
+
+ protected String mId = null;
+ protected String mGetClientCert = "false";
+ protected String mAuthMgr = null;
+ protected IAuthzSubsystem mAuthz = null;
+ protected String mAclMethod = null;
+ protected String mAuthzResourceName = null;
+ protected ILogger mLogger = CMS.getLogger();
+ protected int mLogCategory = ILogger.S_OTHER;
+ protected String mProfileSubId = null;
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ public ProfileServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. Servlets implementing this method
+ * must specify the template to use as a parameter called
+ * "templatePath" in the servletConfig
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplate = sc.getServletContext().getRealPath(
+ sc.getInitParameter(PROP_TEMPLATE));
+ mGetClientCert = sc.getInitParameter(PROP_CLIENTAUTH);
+ mAuthMgr = sc.getInitParameter(PROP_AUTHMGR);
+ mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ mAuthzResourceName = sc.getInitParameter(PROP_RESOURCEID);
+ mProfileSubId = sc.getInitParameter(PROP_PROFILE_SUB_ID);
+ mId = sc.getInitParameter(PROP_ID);
+
+ try {
+ mAclMethod = Utils.initializeAuthz(sc, mAuthz, mId);
+ } catch (ServletException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ throw e;
+ }
+ }
+
+ protected String escapeXML(String v)
+ {
+ if (v == null) {
+ return "";
+ }
+ v = v.replaceAll("&", "&amp;");
+ return v;
+ }
+
+ protected void outputArgValueAsXML(PrintStream ps, String name, IArgValue v)
+ {
+ ps.println("<" + name + ">");
+ if (v != null) {
+ if (v instanceof ArgList) {
+ ArgList list = (ArgList)v;
+ ps.println("<list>");
+ for (int i = 0; i < list.size(); i++) {
+ outputArgValueAsXML(ps, name, list.get(i));
+ }
+ ps.println("</list>");
+ } else if (v instanceof ArgString) {
+ ArgString str = (ArgString)v;
+ ps.println(escapeXML(str.getValue()));
+ } else if (v instanceof ArgSet) {
+ ArgSet set = (ArgSet)v;
+ ps.println("<set>");
+ Enumeration names = set.getNames();
+ while (names.hasMoreElements()) {
+ String n = (String)names.nextElement();
+ outputArgValueAsXML(ps, n, set.get(n));
+ }
+ ps.println("</set>");
+ } else {
+ ps.println(v);
+ }
+ }
+ ps.println("</" + name + ">");
+ }
+
+ protected void outputThisAsXML(ByteArrayOutputStream bos, ArgSet args)
+ {
+ PrintStream ps = new PrintStream(bos);
+ ps.println("<xml>");
+ outputArgValueAsXML(ps, "output", args);
+ ps.println("</xml>");
+ ps.flush();
+ }
+
+ public void outputTemplate(HttpServletRequest request,
+ HttpServletResponse response, ArgSet args)
+ throws EBaseException {
+
+ String xmlOutput = request.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ response.setContentType("text/xml");
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ outputThisAsXML(bos, args);
+ try {
+ response.setContentLength(bos.size());
+ bos.writeTo(response.getOutputStream());
+ } catch (Exception e) {
+ CMS.debug("outputTemplate error " + e);
+ }
+ return;
+ }
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("output_template");
+ }
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(
+ new FileReader(mTemplate));
+
+ response.setContentType("text/html; charset=UTF-8");
+
+ PrintWriter writer = response.getWriter();
+
+
+ // output template
+ String line = null;
+
+ do {
+ line = reader.readLine();
+ if (line != null) {
+ if (line.indexOf("<CMS_TEMPLATE>") == -1) {
+ writer.println(line);
+ } else {
+ // output javascript parameters
+ writer.println("<script type=\"text/javascript\">");
+ outputData(writer, args);
+ writer.println("</script>");
+ }
+ }
+ }
+ while (line != null);
+ reader.close();
+ } catch (IOException e) {
+ CMS.debug(e);
+ throw new EBaseException(e.toString());
+ } finally {
+ if (statsSub != null) {
+ statsSub.endTiming("output_template");
+ }
+ }
+ }
+
+ protected void outputArgList(PrintWriter writer, String name, ArgList list)
+ throws IOException {
+
+ String h_name = null;
+
+ if (name.indexOf('.') == -1) {
+ h_name = name;
+ } else {
+ h_name = name.substring(name.indexOf('.') + 1);
+ }
+ writer.println(name + "Set = new Array;");
+ // writer.println(h_name + "Count = 0;");
+
+ for (int i = 0; i < list.size(); i++) {
+ writer.println(h_name + " = new Object;");
+ IArgValue val = list.get(i);
+
+ if (val instanceof ArgString) {
+ ArgString str = (ArgString) val;
+
+ outputArgString(writer, name, str);
+ } else if (val instanceof ArgSet) {
+ ArgSet set = (ArgSet) val;
+
+ outputArgSet(writer, h_name, set);
+ writer.println(name + "Set[" + i + "] = " + h_name + ";");
+ }
+ }
+ }
+
+ protected String escapeJavaScriptString(String v) {
+ int l = v.length();
+ char in[] = new char[l];
+ char out[] = new char[l * 4];
+ int j = 0;
+
+ v.getChars(0, l, in, 0);
+
+ for (int i = 0; i < l; i++) {
+ char c = in[i];
+
+ /* presumably this gives better performance */
+ if ((c > 0x23) && (c != 0x5c)) {
+ out[j++] = c;
+ continue;
+ }
+
+ /* some inputs are coming in as '\' and 'n' */
+ /* see BZ 500736 for details */
+ if ((c == 0x5c) && ((i+1)<l) && (in[i+1] == 'n' ||
+ in[i+1] == 'n' || in[i+1] == 'f' || in[i+1] == 't')) {
+ out[j++] = '\\';
+ out[j++] = in[i+1];
+ i++;
+ continue;
+ }
+
+ switch (c) {
+ case '\n':
+ out[j++] = '\\';
+ out[j++] = 'n';
+ break;
+
+ case '\\':
+ out[j++] = '\\';
+ out[j++] = '\\';
+ break;
+
+ case '\"':
+ out[j++] = '\\';
+ out[j++] = '\"';
+ break;
+
+ case '\r':
+ out[j++] = '\\';
+ out[j++] = 'r';
+ break;
+
+ case '\f':
+ out[j++] = '\\';
+ out[j++] = 'f';
+ break;
+
+ case '\t':
+ out[j++] = '\\';
+ out[j++] = 't';
+ break;
+
+ case '<':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'c';
+ break;
+
+ case '>':
+ out[j++] = '\\';
+ out[j++] = 'x';
+ out[j++] = '3';
+ out[j++] = 'e';
+ break;
+
+ default:
+ out[j++] = c;
+ }
+ }
+ return new String(out, 0, j);
+ }
+
+ protected void outputArgString(PrintWriter writer, String name, ArgString str)
+ throws IOException {
+ String s = str.getValue();
+
+ // sub \n with "\n"
+ if (s != null) {
+ s = escapeJavaScriptString(s);
+ }
+ writer.println(name + "=\"" + s + "\";");
+ }
+
+ protected void outputArgSet(PrintWriter writer, String name, ArgSet set)
+ throws IOException {
+ Enumeration e = set.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ IArgValue val = set.get(n);
+
+ if (val instanceof ArgSet) {
+ ArgSet set1 = (ArgSet) val;
+
+ outputArgSet(writer, name + "." + n, set1);
+ } else if (val instanceof ArgList) {
+ ArgList list = (ArgList) val;
+
+ outputArgList(writer, name + "." + n, list);
+ } else if (val instanceof ArgString) {
+ ArgString str = (ArgString) val;
+
+ outputArgString(writer, name + "." + n, str);
+ }
+ }
+ }
+
+ protected void outputData(PrintWriter writer, ArgSet set)
+ throws IOException {
+ if (set == null)
+ return;
+ Enumeration e = set.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ IArgValue val = set.get(n);
+
+ if (val instanceof ArgSet) {
+ ArgSet set1 = (ArgSet) val;
+
+ outputArgSet(writer, n, set1);
+ } else if (val instanceof ArgList) {
+ ArgList list = (ArgList) val;
+
+ outputArgList(writer, n, list);
+ } else if (val instanceof ArgString) {
+ ArgString str = (ArgString) val;
+
+ outputArgString(writer, n, str);
+ }
+ }
+ }
+
+ /**
+ * log according to authority category.
+ */
+ protected void log(int event, int level, String msg) {
+ mLogger.log(event, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader(HDR_LANG);
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected void renderResult(CMSRequest cmsReq)
+ throws IOException {
+ // do nothing
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
new file mode 100644
index 000000000..27280d4e5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
@@ -0,0 +1,877 @@
+// --- 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.servlet.profile;
+
+
+import java.util.*;
+import java.security.cert.*;
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.template.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.cmc.*;
+
+import netscape.security.x509.*;
+
+
+/**
+ * This servlet submits end-user request into the profile framework.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileSubmitCMCServlet extends ProfileServlet {
+
+ private static final String ARG_AUTH_TOKEN = "auth_token";
+ private static final String PROP_PROFILE_ID = "profileId";
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+
+ private String mOutputTemplateClassName = null;
+ private String mProfileId = null;
+ private String mProfileSubId = null;
+ private String mReqType = null;
+ private String mAuthorityId = null;
+ private String requestBinary = null;
+ private String requestB64 = null;
+
+ private final static String[]
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON = new String[] {
+
+ /* 0 */ "automated profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException"
+ };
+ private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ public ProfileSubmitCMCServlet() {
+ }
+
+ /**
+ * initialize the servlet. And instance of this servlet can
+ * be set up to always issue certificates against a certain profile
+ * by setting the 'profileId' configuration in the servletConfig
+ * If not, the user must specify the profileID when submitting the request
+ *
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+ mProfileId = sc.getInitParameter(PROP_PROFILE_ID);
+ mOutputTemplateClassName = sc.getInitParameter("outputTemplateClass");
+ mRenderResult = false;
+ }
+
+ private void setInputsIntoContext(HttpServletRequest request, IProfile profile, IProfileContext ctx) {
+
+ // 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();
+
+ if (request.getParameter(inputName) != null) {
+ ctx.set(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+
+ }
+
+ private void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator, IProfileContext ctx) {
+ Enumeration authIds = authenticator.getValueNames();
+
+ if (authIds != null) {
+ while (authIds.hasMoreElements()) {
+ String authName = (String) authIds.nextElement();
+
+ if (request.getParameter(authName) != null) {
+ ctx.set(authName, request.getParameter(authName));
+ }
+ }
+ }
+ }
+
+ public IAuthToken authenticate(IProfileAuthenticator authenticator,
+ HttpServletRequest request) throws EBaseException {
+ AuthCredentials credentials = new AuthCredentials();
+
+ // build credential
+ Enumeration authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = (String) authNames.nextElement();
+
+ if (authName.equals("cert_request"))
+ credentials.set(authName, requestB64);
+ else
+ credentials.set(authName, request.getParameter(authName));
+ }
+ }
+ IAuthToken authToken = authenticator.authenticate(credentials);
+
+ SessionContext sc = SessionContext.getContext();
+ if (sc != null) {
+ sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName());
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+ if (userid != null) {
+ sc.put(SessionContext.USER_ID, userid);
+ }
+ }
+
+ return authToken;
+ }
+
+ private void setInputsIntoRequest(HttpServletRequest request, IProfile
+profile, IRequest req) {
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ String inputName = (String) inputNames.nextElement();
+
+ if (request.getParameter(inputName) != null) {
+ req.setExtData(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the HTTP request
+ * <P>
+ *
+ * (Certificate Request Processed - either an automated "EE" profile based
+ * cert acceptance, or an automated "EE" profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>http.param profileId ID of profile to use to process request
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ * @exception EBaseException an error has occurred
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+
+ Locale locale = getLocale(request);
+ ArgSet args = new ArgSet();
+ String cert_request_type =
+ mServletConfig.getInitParameter("cert_request_type");
+ String outputFormat = mServletConfig.getInitParameter("outputFormat");
+
+ int reqlen = request.getContentLength();
+ InputStream is = null;
+ try {
+ is = request.getInputStream();
+ } catch (Exception ee) {
+ }
+ byte reqbuf[] = new byte[reqlen];
+ int bytesread = 0;
+ boolean partial = false;
+
+ while (bytesread < reqlen) {
+ try {
+ bytesread += is.read(reqbuf, bytesread, reqlen - bytesread);
+ } catch (Exception ee) {
+ }
+
+ if (partial == false) {
+ if (bytesread < reqlen)
+ partial = true;
+ }
+ }
+
+ requestB64 = com.netscape.osutil.OSUtil.BtoA(reqbuf);
+
+ if (CMS.debugOn()) {
+ CMS.debug("Start of ProfileSubmitCMCServlet Input Parameters");
+ Enumeration paramNames = request.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String paramName = (String) paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( paramName.startsWith("__") ||
+ paramName.endsWith("password") ||
+ paramName.endsWith("passwd") ||
+ paramName.endsWith("pwd") ||
+ paramName.equalsIgnoreCase("admin_password_again") ||
+ paramName.equalsIgnoreCase("directoryManagerPwd") ||
+ paramName.equalsIgnoreCase("bindpassword") ||
+ paramName.equalsIgnoreCase("bindpwd") ||
+ paramName.equalsIgnoreCase("passwd") ||
+ paramName.equalsIgnoreCase("password") ||
+ paramName.equalsIgnoreCase("pin") ||
+ paramName.equalsIgnoreCase("pwd") ||
+ paramName.equalsIgnoreCase("pwdagain") ||
+ paramName.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("ProfileSubmitCMCServlet Input Parameter " +
+ paramName + "='(sensitive)'");
+ } else {
+ CMS.debug("ProfileSubmitCMCServlet Input Parameter " +
+ paramName + "='" +
+ request.getParameter(paramName) + "'");
+ }
+ }
+ CMS.debug("End of ProfileSubmitCMCServlet Input Parameters");
+ }
+
+ CMS.debug("ProfileSubmitCMCServlet: start serving");
+
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileSubmitCMCServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileSubmitCMCServlet: ProfileSubsystem not found");
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+
+ // if we did not configure profileId in xml file,
+ // then accept the user-provided one
+ String profileId = null;
+
+ if (mProfileId == null) {
+ profileId = request.getParameter("profileId");
+ } else {
+ profileId = mProfileId;
+ }
+
+ IProfile profile = null;
+
+ try {
+ CMS.debug("ProfileSubmitCMCServlet: profileId " + profileId);
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitCMCServlet: profile not found profileId " +
+ profileId + " " + e.toString());
+ }
+ if (profile == null) {
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("ProfileSubmitCMCServlet: Profile " + profileId +
+ " not enabled");
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+
+ IProfileContext ctx = profile.createContext();
+ if (requestB64 != null) {
+ ctx.set("cert_request_type", cert_request_type);
+ ctx.set("cert_request", requestB64);
+ }
+ // passing auths into context
+ IProfileAuthenticator authenticator = null;
+
+ try {
+ authenticator = profile.getAuthenticator();
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ }
+ if (authenticator == null) {
+ CMS.debug("ProfileSubmitCMCServlet: authenticator not found");
+ } else {
+ CMS.debug("ProfileSubmitCMCServlet: authenticator " +
+ authenticator.getName() + " found");
+ setCredentialsIntoContext(request, authenticator, ctx);
+ }
+
+ setInputsIntoContext(request, profile, ctx);
+ CMS.debug("ProfileSubmistServlet: set Inputs into Context");
+
+ // before creating the request, authenticate the request
+
+ IAuthToken authToken = null;
+
+ // for ssl authentication; pass in servlet for retrieving
+ // ssl client certificates
+ SessionContext context = SessionContext.getContext();
+
+ // insert profile context so that input parameter can be retrieved
+ context.put("profileContext", ctx);
+ context.put("sslClientCertProvider",
+ new SSLClientCertProvider(request));
+ CMS.debug("ProfileSubmitCMCServlet: set sslClientCertProvider");
+ if (authenticator != null) {
+ try {
+ authToken = authenticate(authenticator, request);
+ // authentication success
+ } catch (EBaseException e) {
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(e.toString());
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.BAD_REQUEST, s);
+ CMS.debug("ProfileSubmitCMCServlet: authentication error " +
+ e.toString());
+ return;
+ }
+
+ //authorization only makes sense when request is authenticated
+ AuthzToken authzToken = null;
+ if (authToken != null) {
+ CMS.debug("ProfileSubmitCMCServlet authToken not null");
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitCMCServlet authorization failure: "+e.toString());
+ }
+ }
+
+ if (authzToken == null) {
+ CMS.debug("ProfileSubmitCMCServlet authorization failure: authzToken is null");
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String("ProfileSubmitCMCServlet authorization failure");
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.BAD_REQUEST, s);
+ return;
+ }
+ }
+
+ IRequest reqs[] = null;
+
+ ///////////////////////////////////////////////
+ // create request
+ ///////////////////////////////////////////////
+ try {
+ reqs = profile.createRequests(ctx, locale);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitCMCServlet: createRequests " + e.toString());
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(e.toString());
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ } catch (Throwable e) {
+ CMS.debug("ProfileSubmitCMCServlet: createRequests " + e.toString());
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+
+ TaggedAttribute attr =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness));
+ if (attr != null) {
+ boolean verifyAllow = true;
+ try {
+ verifyAllow = CMS.getConfigStore().getBoolean(
+ "cmc.lraPopWitness.verify.allow", true);
+ } catch (EBaseException ee) {
+ }
+
+ if (!verifyAllow) {
+ LraPopWitness lraPop = null;
+ SET vals = attr.getValues();
+ if (vals.size() > 0) {
+ try {
+ lraPop = (LraPopWitness)(ASN1Util.decode(LraPopWitness.getTemplate(),
+ ASN1Util.encode(vals.elementAt(0))));
+ } catch (InvalidBERException e) {
+ CMS.debug(
+ CMS.getUserMessage(locale, "CMS_PROFILE_ENCODING_ERROR"));
+ }
+
+ SEQUENCE bodyIds = lraPop.getBodyIds();
+
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ template.createFullResponseWithFailedStatus(response, bodyIds,
+ OtherInfo.POP_FAILED, null);
+ return;
+ }
+ }
+ }
+
+ // for CMC, requests may be zero. Then check if controls exist.
+ if (reqs == null) {
+ Integer nums = (Integer)(context.get("numOfControls"));
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ // if there is only one control GetCert, then simple response
+ // must be returned.
+ if (nums != null && nums.intValue() == 1) {
+ TaggedAttribute attr1 = (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
+ if (attr1 != null) {
+ template.createSimpleResponse(response, reqs);
+ } else
+ template.createFullResponse(response, reqs,
+ cert_request_type, null);
+ } else
+ template.createFullResponse(response, reqs,
+ cert_request_type, null);
+ return;
+ }
+
+ String errorCode = null;
+ String errorReason = null;
+
+ ///////////////////////////////////////////////
+ // populate request
+ ///////////////////////////////////////////////
+ for (int k = 0; k < reqs.length; k++) {
+ // adding parameters to request
+ setInputsIntoRequest(request, profile, reqs[k]);
+
+ // serial auth token into request
+ if (authToken != null) {
+ Enumeration tokenNames = authToken.getElements();
+ while (tokenNames.hasMoreElements()) {
+ String tokenName = (String)tokenNames.nextElement();
+ String[] vals = authToken.getInStringArray(tokenName);
+ if (vals != null) {
+ for (int i = 0; i < vals.length; i++) {
+ reqs[k].setExtData(ARG_AUTH_TOKEN + "." +
+ tokenName + "[" + i + "]", vals[i]);
+ }
+ } else {
+ String val = authToken.getInString(tokenName);
+ if (val != null) {
+ reqs[k].setExtData(ARG_AUTH_TOKEN + "." + tokenName,
+ val);
+ }
+ }
+ }
+ }
+
+ // put profile framework parameters into the request
+ reqs[k].setExtData(ARG_PROFILE, "true");
+ reqs[k].setExtData(ARG_PROFILE_ID, profileId);
+ reqs[k].setExtData(ARG_PROFILE_APPROVED_BY, profile.getApprovedBy());
+ String setId = profile.getPolicySetId(reqs[k]);
+
+ if (setId == null) {
+ // no profile set found
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(CMS.getUserMessage("CMS_PROFILE_NO_POLICY_SET_FOUND"));
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+
+ CMS.debug("ProfileSubmitCMCServlet profileSetid=" + setId);
+ reqs[k].setExtData(ARG_PROFILE_SET_ID, setId);
+ reqs[k].setExtData(ARG_PROFILE_REMOTE_HOST, request.getRemoteHost());
+ reqs[k].setExtData(ARG_PROFILE_REMOTE_ADDR, request.getRemoteAddr());
+
+ CMS.debug("ProfileSubmitCMCServlet: request " +
+ reqs[k].getRequestId().toString());
+
+ try {
+ CMS.debug("ProfileSubmitCMCServlet: populating request inputs");
+ // give authenticator a chance to populate the request
+ if (authenticator != null) {
+ authenticator.populate(authToken, reqs[k]);
+ }
+ profile.populateInput(ctx, reqs[k]);
+ profile.populate(reqs[k]);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitCMCServlet: populate " + e.toString());
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(e.toString());
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.BAD_REQUEST, s);
+ return;
+ } catch (Throwable e) {
+ CMS.debug("ProfileSubmitCMCServlet: populate " + e.toString());
+ // throw new IOException("Profile " + profileId +
+ // " cannot populate");
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(new INTEGER(0));
+ UTF8String s = null;
+ try {
+ s = new UTF8String(e.toString());
+ } catch (Exception ee) {
+ }
+ template.createFullResponseWithFailedStatus(response, seq,
+ OtherInfo.INTERNAL_CA_ERROR, s);
+ return;
+ }
+ }
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ int responseType = 0;
+ try {
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ int error_codes[] = null;
+ if (reqs != null && reqs.length > 0)
+ error_codes = new int[reqs.length];
+ for (int k = 0; k < reqs.length; k++) {
+ try {
+ // reset the "auditRequesterID"
+ auditRequesterID = auditRequesterID(reqs[k]);
+
+
+ // print request debug
+ if (reqs[k] != null) {
+ Enumeration reqKeys = reqs[k].getExtDataKeys();
+ while (reqKeys.hasMoreElements()) {
+ String reqKey = (String)reqKeys.nextElement();
+ String reqVal = reqs[k].getExtDataInString(reqKey);
+ if (reqVal != null) {
+ CMS.debug("ProfileSubmitCMCServlet: key=$request." + reqKey + "$ value=" + reqVal);
+ }
+ }
+ }
+
+ profile.submit(authToken, reqs[k]);
+ reqs[k].setRequestStatus(RequestStatus.COMPLETE);
+
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue(reqs[k]);
+
+ if (auditInfoCertValue != null) {
+ if (!(auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue);
+
+ audit(auditMessage);
+ }
+ }
+ } catch (EDeferException e) {
+ // return defer message to the user
+ reqs[k].setRequestStatus(RequestStatus.PENDING);
+ // need to notify
+ INotify notify = profile.getRequestQueue().getPendingNotify();
+ if (notify != null) {
+ notify.notify(reqs[k]);
+ }
+
+ CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString());
+ errorCode = "2";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEFERRED",
+ e.toString());
+ } catch (ERejectException e) {
+ // return error to the user
+ reqs[k].setRequestStatus(RequestStatus.REJECTED);
+ CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString());
+ errorCode = "3";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_PROFILE_REJECTED",
+ e.toString());
+ } catch (Throwable e) {
+ // return error to the user
+ CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString());
+ errorCode = "1";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR");
+ }
+
+ try {
+ if (errorCode == null) {
+ profile.getRequestQueue().markAsServiced(reqs[k]);
+ } else {
+ profile.getRequestQueue().updateRequest(reqs[k]);
+ }
+ } catch (EBaseException e) {
+ CMS.debug("ProfileSubmitCMCServlet: updateRequest " +
+ e.toString());
+ }
+
+ if (errorCode != null) {
+ if (errorCode.equals("1")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ } else if (errorCode.equals("2")) {
+ // do NOT store a message in the signed audit log file
+ // as this errorCode indicates that a process has been
+ // deferred for manual acceptance/cancellation/rejection
+ } else if (errorCode.equals("3")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ }
+ error_codes[k] = Integer.parseInt(errorCode);
+ } else
+ error_codes[k] = 0;
+ }
+
+ if (errorCode != null) {
+ // create the CMC full enrollment response
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ template.createFullResponse(response, reqs, cert_request_type, error_codes);
+
+ return;
+ }
+
+ ///////////////////////////////////////////////
+ // output output list
+ ///////////////////////////////////////////////
+
+ CMS.debug("ProfileSubmitCMCServlet: done serving");
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ if (cert_request_type.equals("pkcs10") || cert_request_type.equals("crmf")) {
+
+ if (outputFormat != null &&outputFormat.equals("pkcs7")) {
+ byte[] pkcs7 = CMS.getPKCS7(locale, reqs[0]);
+ response.setContentType("application/pkcs7-mime");
+ response.setContentLength(pkcs7.length);
+ try {
+ OutputStream os = response.getOutputStream();
+ os.write(pkcs7);
+ os.flush();
+ } catch (Exception ee) {
+ }
+ return;
+ }
+ template.createSimpleResponse(response, reqs);
+ } else if (cert_request_type.equals("cmc")) {
+ Integer nums = (Integer)(context.get("numOfControls"));
+ if (nums != null && nums.intValue() == 1) {
+ TaggedAttribute attr1 =
+ (TaggedAttribute)(context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
+ if (attr1 != null) {
+ template.createSimpleResponse(response, reqs);
+ return;
+ }
+ }
+ template.createFullResponse(response, reqs, cert_request_type,
+ error_codes);
+ }
+ } finally {
+ context.releaseContext();
+ }
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = ILogger.UNIDENTIFIED;
+
+ if (request != null) {
+ // overwrite "requesterID" if and only if "id" != null
+ String id = request.getRequestId().toString();
+
+ if (id != null) {
+ requesterID = id.trim();
+ }
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param request request containing an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ X509CertImpl x509cert = request.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (!Character.isWhitespace(base64Data.charAt(i))) {
+ sb.append(base64Data.charAt(i));
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
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
new file mode 100644
index 000000000..389267678
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
@@ -0,0 +1,1530 @@
+// --- 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.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.*;
+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;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.cmsutil.util.*;
+import org.w3c.dom.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This servlet submits end-user request into the profile framework.
+ *
+ * @author Christina Fu (renewal support)
+ * @version $Revision$, $Date$
+ */
+public class ProfileSubmitServlet extends ProfileServlet {
+
+ private static final String ARG_AUTH_TOKEN = "auth_token";
+ private static final String ARG_REQUEST_OWNER = "requestOwner";
+ private static final String PROP_PROFILE_ID = "profileId";
+ private static final String PROP_AUTHORITY_ID = "authorityId";
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ private String mProfileId = null;
+ private String mProfileSubId = null;
+ private String mReqType = null;
+ private String mAuthorityId = null;
+
+ private final static String[]
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON = new String[] {
+
+ /* 0 */ "automated profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException"
+ };
+ private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ public ProfileSubmitServlet() {
+ }
+
+ /**
+ * initialize the servlet. And instance of this servlet can
+ * be set up to always issue certificates against a certain profile
+ * by setting the 'profileId' configuration in the servletConfig
+ * If not, the user must specify the profileID when submitting the request
+ *
+ * "ImportCert.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID);
+ mProfileId = sc.getInitParameter(PROP_PROFILE_ID);
+ }
+
+ private void setInputsIntoContext(HttpServletRequest request, IProfile profile, IProfileContext ctx) {
+ // 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();
+ if (request.getParameter(inputName) != null) {
+ // all subject name parameters start with sn_, no other input parameters do
+ if (inputName.matches("^sn_.*")) {
+ ctx.set(inputName, escapeValueRfc1779(request.getParameter(inputName), false).toString());
+ } else {
+ ctx.set(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /*
+ * 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,
+ HttpServletRequest request) throws EBaseException {
+ AuthCredentials credentials = new AuthCredentials();
+
+ // build credential
+ Enumeration authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = (String) authNames.nextElement();
+
+ credentials.set(authName, request.getParameter(authName));
+ }
+ }
+
+ credentials.set("clientHost", request.getRemoteHost());
+ IAuthToken authToken = authenticator.authenticate(credentials);
+
+ SessionContext sc = SessionContext.getContext();
+ if (sc != null) {
+ sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName());
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+ if (userid != null) {
+ sc.put(SessionContext.USER_ID, userid);
+ }
+ }
+
+ return authToken;
+ }
+
+ private void setInputsIntoRequest(HttpServletRequest request, IProfile profile, IRequest req) {
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ String inputName = (String) inputNames.nextElement();
+
+ if (request.getParameter(inputName) != null) {
+ // special characters in subject names parameters must be escaped
+ if (inputName.matches("^sn_.*")) {
+ req.setExtData(inputName, escapeValueRfc1779(request.getParameter(inputName), false).toString());
+ } else {
+ req.setExtData(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * 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();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = (String) outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId);
+
+ Enumeration outputNames = profileOutput.getValueNames();
+
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ ArgSet outputset = new ArgSet();
+ String outputName = (String) outputNames.nextElement();
+ IDescriptor outputDesc =
+ profileOutput.getValueDescriptor(locale, outputName);
+
+ if (outputDesc == null)
+ continue;
+ String outputSyntax = outputDesc.getSyntax();
+ String outputConstraint = outputDesc.getConstraint();
+ String outputValueName = outputDesc.getDescription(locale);
+ String outputValue = null;
+
+ try {
+ outputValue = profileOutput.getValue(outputName,
+ locale, req);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitServlet: " + e.toString());
+ }
+
+ outputset.set(ARG_OUTPUT_ID, outputName);
+ outputset.set(ARG_OUTPUT_SYNTAX, outputSyntax);
+ outputset.set(ARG_OUTPUT_CONSTRAINT, outputConstraint);
+ outputset.set(ARG_OUTPUT_NAME, outputValueName);
+ outputset.set(ARG_OUTPUT_VAL, outputValue);
+ outputlist.add(outputset);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the HTTP request
+ * <P>
+ *
+ * (Certificate Request Processed - either an automated "EE" profile based
+ * cert acceptance, or an automated "EE" profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>http.param profileId ID of profile to use to process request
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ * @exception EBaseException an error has occurred
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest request = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+ boolean xmlOutput = false;
+
+ String v = request.getParameter("xml");
+ if ((v != null) && (v.equalsIgnoreCase("true"))) {
+ xmlOutput = true;
+ }
+ v = request.getParameter("xmlOutput");
+ if ((v != null) && (v.equalsIgnoreCase("true"))) {
+ xmlOutput = true;
+ }
+ if (xmlOutput) {
+ CMS.debug("xmlOutput true");
+ } else {
+ CMS.debug("xmlOutput false");
+ }
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("enrollment", true /* main action */);
+ }
+
+ long startTime = CMS.getCurrentDate().getTime();
+ Locale locale = getLocale(request);
+ ArgSet args = new ArgSet();
+
+ if (CMS.debugOn()) {
+ CMS.debug("Start of ProfileSubmitServlet Input Parameters");
+ Enumeration paramNames = request.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String paramName = (String) paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( paramName.startsWith("__") ||
+ paramName.endsWith("password") ||
+ paramName.endsWith("passwd") ||
+ paramName.endsWith("pwd") ||
+ paramName.equalsIgnoreCase("admin_password_again") ||
+ paramName.equalsIgnoreCase("directoryManagerPwd") ||
+ paramName.equalsIgnoreCase("bindpassword") ||
+ paramName.equalsIgnoreCase("bindpwd") ||
+ paramName.equalsIgnoreCase("passwd") ||
+ paramName.equalsIgnoreCase("password") ||
+ paramName.equalsIgnoreCase("pin") ||
+ paramName.equalsIgnoreCase("pwd") ||
+ paramName.equalsIgnoreCase("pwdagain") ||
+ paramName.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("ProfileSubmitServlet Input Parameter " +
+ paramName + "='(sensitive)'");
+ } else {
+ CMS.debug("ProfileSubmitServlet Input Parameter " +
+ paramName + "='" +
+ request.getParameter(paramName) + "'");
+ }
+ }
+ CMS.debug("End of ProfileSubmitServlet Input Parameters");
+ }
+
+ CMS.debug("ProfileSubmitServlet: start serving");
+
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileSubmitServlet: SubId=" + mProfileSubId);
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(mProfileSubId);
+
+ if (ps == null) {
+ CMS.debug("ProfileSubmitServlet: ProfileSubsystem not found");
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ 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;
+ Integer origSeqNum = 0;
+
+ // if we did not configure profileId in xml file,
+ // then accept the user-provided one
+ String profileId = null;
+
+ if (mProfileId == null) {
+ profileId = request.getParameter("profileId");
+ } else {
+ 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 or revoked_expired
+ if ((rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) || (rec.getStatus().equals(ICertRecord.STATUS_REVOKED_EXPIRED))) {
+ 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;
+ }
+ origSeqNum = origReq.getExtDataInInteger(IEnrollProfile.REQUEST_SEQ_NUM);
+
+ } 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 {
+ 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) {
+ 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) {
+ outputError(response, CMS.getUserMessage(locale,"CMS_PROFILE_NOT_FOUND", profileId));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ }
+ 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 +
+ " not enabled");
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", profileId));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ 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 {
+ 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");
+ } else {
+ CMS.debug("ProfileSubmitServlet: authenticator " +
+ authenticator.getName() + " found");
+ setCredentialsIntoContext(request, authenticator, ctx);
+ }
+
+ // 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(IEnrollProfile.CTX_RENEWAL, "true");
+ ctx.set("renewProfileId", renewProfileId);
+ ctx.set(IEnrollProfile.CTX_RENEWAL_SEQ_NUM, origSeqNum.toString());
+ } else {
+ setInputsIntoContext(request, profile, ctx);
+ }
+
+ // before creating the request, authenticate the request
+
+ IAuthToken authToken = null;
+
+ // for ssl authentication; pass in servlet for retrieving
+ // ssl client certificates
+ SessionContext context = SessionContext.getContext();
+
+ // insert profile context so that input parameter can be retrieved
+ context.put("profileContext", ctx);
+ 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 {
+ 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());
+ // authentication error
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR"));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHENTICATION_ERROR"));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("authentication");
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ }
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("profile_authentication");
+ }
+
+ // authentication success
+ if (authToken != null) {
+ CMS.debug("ProfileSubmitServlet authToken not null");
+ // do profile authorization
+ 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);
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet authorize: "+e.toString());
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_AUTHORIZATION_ERROR"));
+ outputTemplate(request, response, args);
+ }
+
+ return;
+ }
+ }
+ }
+
+ IRequest reqs[] = null;
+
+ if (statsSub != null) {
+ statsSub.startTiming("request_population");
+ }
+ ///////////////////////////////////////////////
+ // create request
+ ///////////////////////////////////////////////
+ try {
+ reqs = profile.createRequests(ctx, locale);
+ } catch (EProfileException e) {
+ CMS.debug(e);
+ CMS.debug("ProfileSubmitServlet: createRequests " + e.toString());
+ if (xmlOutput) {
+ outputError(response, e.toString());
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, e.toString());
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ } catch (Throwable e) {
+ CMS.debug(e);
+ CMS.debug("ProfileSubmitServlet: createRequests " + e.toString());
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ }
+
+ String errorCode = null;
+ String errorReason = null;
+
+ ///////////////////////////////////////////////
+ // populate request
+ ///////////////////////////////////////////////
+ for (int k = 0; k < reqs.length; k++) {
+ boolean fromRA = false;
+ String uid = "";
+
+ // adding parameters to request
+ 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].setRequestType("renewal");
+ } else
+ setInputsIntoRequest(request, profile, reqs[k]);
+
+ // serial auth token into request
+ if (authToken != null) {
+ Enumeration tokenNames = authToken.getElements();
+ while (tokenNames.hasMoreElements()) {
+ String tokenName = (String) tokenNames.nextElement();
+ String[] tokenVals = authToken.getInStringArray(tokenName);
+ if (tokenVals != null) {
+ for (int i = 0; i < tokenVals.length; i++) {
+ reqs[k].setExtData(ARG_AUTH_TOKEN + "." +
+ tokenName + "[" + i + "]", tokenVals[i]);
+ }
+ } else {
+ String tokenVal = authToken.getInString(tokenName);
+ if (tokenVal != null) {
+ reqs[k].setExtData(ARG_AUTH_TOKEN + "." + tokenName,
+ tokenVal);
+ // if RA agent, auto assign the request
+ if (tokenName.equals("uid"))
+ uid = tokenVal;
+ if (tokenName.equals("group") &&
+ tokenVal.equals("Registration Manager Agents")) {
+ fromRA = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (fromRA) {
+ CMS.debug("ProfileSubmitServlet: request from RA: "+ uid);
+ reqs[k].setExtData(ARG_REQUEST_OWNER, uid);
+ }
+
+ // 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]);
+
+ if (setId == null) {
+ // no profile set found
+ CMS.debug("ProfileSubmitServlet: no profile policy set found");
+ if (xmlOutput) {
+ outputError(response, FAILED, CMS.getUserMessage("CMS_PROFILE_NO_POLICY_SET_FOUND"), reqs[k].getRequestId().toString());
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON,
+ CMS.getUserMessage("CMS_PROFILE_NO_POLICY_SET_FOUND"));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ }
+
+ CMS.debug("ProfileSubmitServlet profileSetid=" + setId);
+ reqs[k].setExtData(ARG_PROFILE_SET_ID, setId);
+ reqs[k].setExtData(ARG_PROFILE_REMOTE_HOST, request.getRemoteHost());
+ reqs[k].setExtData(ARG_PROFILE_REMOTE_ADDR, request.getRemoteAddr());
+
+ CMS.debug("ProfileSubmitServlet: request " +
+ reqs[k].getRequestId().toString());
+
+ try {
+ CMS.debug("ProfileSubmitServlet: populating request inputs");
+ // give authenticator a chance to populate the request
+ if (authenticator != null) {
+ authenticator.populate(authToken, reqs[k]);
+ }
+ profile.populateInput(ctx, reqs[k]);
+ profile.populate(reqs[k]);
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitServlet: populate " + e.toString());
+ if (xmlOutput) {
+ outputError(response, FAILED, e.toString(), reqs[k].getRequestId().toString());
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, e.toString());
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ } catch (Throwable e) {
+ CMS.debug("ProfileSubmitServlet: populate " + e.toString());
+ // throw new IOException("Profile " + profileId +
+ // " cannot populate");
+ if (xmlOutput) {
+ outputError(response, FAILED, CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"), reqs[k].getRequestId().toString());
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ }
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("request_population");
+ }
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ try {
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ String requestIds = ""; // deliminated with double space
+ for (int k = 0; k < reqs.length; k++) {
+ try {
+ // reset the "auditRequesterID"
+ auditRequesterID = auditRequesterID(reqs[k]);
+
+ // print request debug
+ if (reqs[k] != null) {
+ requestIds += " "+reqs[k].getRequestId().toString();
+ Enumeration reqKeys = reqs[k].getExtDataKeys();
+ while (reqKeys.hasMoreElements()) {
+ String reqKey = (String)reqKeys.nextElement();
+ String reqVal = reqs[k].getExtDataInString(reqKey);
+ if (reqVal != null) {
+ CMS.debug("ProfileSubmitServlet: key=$request." + reqKey + "$ value=" + reqVal);
+ }
+ }
+ }
+
+ profile.submit(authToken, reqs[k]);
+ reqs[k].setRequestStatus(RequestStatus.COMPLETE);
+
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue(reqs[k]);
+
+ if (auditInfoCertValue != null) {
+ if (!(auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue);
+
+ audit(auditMessage);
+ }
+ }
+ } catch (EDeferException e) {
+ // return defer message to the user
+ reqs[k].setRequestStatus(RequestStatus.PENDING);
+ // need to notify
+ INotify notify = profile.getRequestQueue().getPendingNotify();
+ if (notify != null) {
+ notify.notify(reqs[k]);
+ }
+
+ CMS.debug("ProfileSubmitServlet: submit " + e.toString());
+ errorCode = "2";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_PROFILE_DEFERRED",
+ e.toString());
+ } catch (ERejectException e) {
+ // return error to the user
+ reqs[k].setRequestStatus(RequestStatus.REJECTED);
+ CMS.debug("ProfileSubmitServlet: submit " + e.toString());
+ errorCode = "3";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_PROFILE_REJECTED",
+ e.toString());
+ } catch (Throwable e) {
+ // return error to the user
+ CMS.debug("ProfileSubmitServlet: submit " + e.toString());
+ errorCode = "1";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR");
+ }
+
+ try {
+ if (errorCode == null) {
+ profile.getRequestQueue().markAsServiced(reqs[k]);
+ } else {
+ profile.getRequestQueue().updateRequest(reqs[k]);
+ }
+ } catch (EBaseException e) {
+ CMS.debug("ProfileSubmitServlet: updateRequest " +
+ e.toString());
+ }
+
+ if (errorCode != null) {
+ if (errorCode.equals("1")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ } else if (errorCode.equals("2")) {
+ // do NOT store a message in the signed audit log file
+ // as this errorCode indicates that a process has been
+ // deferred for manual acceptance/cancellation/rejection
+ } else if (errorCode.equals("3")) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ }
+ }
+ }
+
+ if (errorCode != null) {
+ if (xmlOutput) {
+ // when errorCode is not null, requestIds should have >=1
+ outputError(response, errorCode, errorReason, requestIds);
+ } else {
+ ArgList requestlist = new ArgList();
+
+ for (int k = 0; k < reqs.length; k++) {
+ ArgSet requestset = new ArgSet();
+
+ requestset.set(ARG_REQUEST_ID,
+ reqs[k].getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, errorCode);
+ args.set(ARG_ERROR_REASON, errorReason);
+ outputTemplate(request, response, args);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ return;
+ }
+
+ ///////////////////////////////////////////////
+ // output output list
+ ///////////////////////////////////////////////
+ if (xmlOutput) {
+ xmlOutput(response, profile, locale, reqs);
+ } else {
+ ArgList outputlist = new ArgList();
+ for (int k = 0; k < reqs.length; k++) {
+
+ setOutputIntoArgs(profile, outputlist, locale, reqs[k]);
+ args.set(ARG_OUTPUT_LIST, outputlist);
+ }
+
+ CMS.debug("ProfileSubmitServlet: done serving");
+
+ ArgList requestlist = new ArgList();
+
+ for (int k = 0; k < reqs.length; k++) {
+ ArgSet requestset = new ArgSet();
+
+ requestset.set(ARG_REQUEST_ID,
+ reqs[k].getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ outputTemplate(request, response, args);
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ // (automated cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[0]);
+
+ audit(auditMessage);
+
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ throw eAudit1;
+ } finally {
+ context.releaseContext();
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("enrollment");
+ }
+ }
+
+ private void xmlOutput(HttpServletResponse httpResp, IProfile profile, Locale locale, IRequest[] reqs) {
+ try {
+ XMLObject xmlObj = null;
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("XMLResponse");
+ xmlObj.addItemToContainer(root, "Status", SUCCESS);
+ Node n = xmlObj.createContainer(root, "Requests");
+ CMS.debug("ProfileSubmitServlet xmlOutput: req len = " +reqs.length);
+
+ for (int i=0; i<reqs.length; i++) {
+ Node subnode = xmlObj.createContainer(n, "Request");
+ xmlObj.addItemToContainer(subnode, "Id", reqs[i].getRequestId().toString());
+ X509CertInfo certInfo =
+ reqs[i].getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+ if (certInfo != null) {
+ String subject = "";
+ subject = (String) certInfo.get(X509CertInfo.SUBJECT).toString();
+ xmlObj.addItemToContainer(subnode, "SubjectDN", subject);
+ } else {
+ CMS.debug("ProfileSubmitServlet xmlOutput: no certInfo found in request");
+ }
+ Enumeration outputIds = profile.getProfileOutputIds();
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = (String) outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId);
+ Enumeration outputNames = profileOutput.getValueNames();
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ String outputName = (String) outputNames.nextElement();
+ if (!outputName.equals("b64_cert") && !outputName.equals("pkcs7"))
+ continue;
+ try {
+ String outputValue = profileOutput.getValue(outputName, locale, reqs[i]);
+ if (outputName.equals("b64_cert")) {
+ String ss = Cert.normalizeCertStrAndReq(outputValue);
+ outputValue = Cert.stripBrackets(ss);
+ byte[] bcode = CMS.AtoB(outputValue);
+ X509CertImpl impl = new X509CertImpl(bcode);
+ xmlObj.addItemToContainer(subnode,
+ "serialno", impl.getSerialNumber().toString(16));
+ xmlObj.addItemToContainer(subnode, "b64", outputValue);
+ }// if b64_cert
+ else if (outputName.equals("pkcs7")) {
+ String ss = Cert.normalizeCertStrAndReq(outputValue);
+ xmlObj.addItemToContainer(subnode, "pkcs7", ss);
+ }
+
+ } catch (EProfileException e) {
+ CMS.debug("ProfileSubmitServlet xmlOutput: "+e.toString());
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet xmlOutput: "+e.toString());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ byte[] cb = xmlObj.toByteArray();
+ outputResult(httpResp, "application/xml", cb);
+ } catch (Exception e) {
+ CMS.debug("Failed to send the XML output");
+ }
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = ILogger.UNIDENTIFIED;
+
+ if (request != null) {
+ // overwrite "requesterID" if and only if "id" != null
+ String id = request.getRequestId().toString();
+
+ if (id != null) {
+ requesterID = id.trim();
+ }
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param request request containing an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(IRequest request) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ X509CertImpl x509cert = request.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (!Character.isWhitespace(base64Data.charAt(i))) {
+ sb.append(base64Data.charAt(i));
+
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java b/pki/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java
new file mode 100644
index 000000000..c548d0db9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java
@@ -0,0 +1,40 @@
+// --- 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.servlet.profile;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import java.security.cert.*;
+import com.netscape.certsrv.authentication.*;
+
+public class SSLClientCertProvider implements ISSLClientCertProvider {
+ private HttpServletRequest mRequest = null;
+
+ public SSLClientCertProvider(HttpServletRequest request) {
+ mRequest = request;
+ }
+
+ public X509Certificate[] getClientCertificateChain() {
+ X509Certificate[] allCerts = (X509Certificate[])
+ mRequest.getAttribute("javax.servlet.request.X509Certificate");
+
+ return allCerts;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java b/pki/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java
new file mode 100644
index 000000000..da79324cd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java
@@ -0,0 +1,893 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.lang.reflect.Array;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * Output a 'pretty print' of a certificate request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CertReqParser extends ReqParser {
+
+ public static final CertReqParser
+ DETAIL_PARSER = new CertReqParser(true);
+ public static final CertReqParser
+ NODETAIL_PARSER = new CertReqParser(false);
+
+ private boolean mDetails = true;
+ private IPrettyPrintFormat pp = null;
+
+ /**
+ * Constructs a certificate request parser.
+ */
+ public CertReqParser() {
+ pp = CMS.getPrettyPrintFormat(":");
+ }
+
+ /**
+ * Constructs a certificate request parser.
+ *
+ * @param details return detailed information (this can be time consuming)
+ */
+ public CertReqParser(boolean details) {
+ mDetails = details;
+ pp = CMS.getPrettyPrintFormat(":");
+ }
+
+ private static final String EXT_PRETTYPRINT = "ext_prettyprint";
+
+ private static final String DOT = ".";
+ private static final String LB = "[";
+ private static final String RB = "]";
+ private static final String EQ = " = ";
+
+ private static final String
+ HTTP_PARAMS_COUNTER = IRequest.HTTP_PARAMS + LB + "httpParamsCount++" + RB;
+ private static final String
+ HTTP_HEADERS_COUNTER = IRequest.HTTP_HEADERS + LB + "httpHeadersCount++" + RB;
+ private static final String
+ AUTH_TOKEN_COUNTER = IRequest.AUTH_TOKEN + LB + "authTokenCount++" + RB;
+ private static final String
+ SERVER_ATTRS_COUNTER = IRequest.SERVER_ATTRS + LB + "serverAttrsCount++" + RB;
+
+ /**
+ * Fills in certificate specific request attributes.
+ */
+ public void fillRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException {
+ if (req.getExtDataInCertInfoArray(IRequest.CERT_INFO) != null) {
+ fillX509RequestIntoArg(l, req, argSet, arg);
+ } else if (req.getExtDataInRevokedCertArray(IRequest.CERT_INFO) != null) {
+ fillRevokeRequestIntoArg(l, req, argSet, arg);
+ } else {
+ //o = req.get(IRequest.OLD_CERTS);
+ //if (o != null)
+ fillRevokeRequestIntoArg(l, req, argSet, arg);
+ }
+ }
+
+ private void fillX509RequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException {
+
+ // fill in the standard attributes
+ super.fillRequestIntoArg(l, req, argSet, arg);
+
+ arg.addStringValue("certExtsEnabled", "yes");
+
+ int saCounter = 0;
+ Enumeration enum1 = req.getExtDataKeys();
+
+ // gross hack
+ String prefix = "record.";
+
+ if (argSet.getHeader() == arg)
+ prefix = "header.";
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (mDetails) {
+ // show all http parameters stored in request.
+ if (name.equals(IRequest.HTTP_PARAMS)) {
+ Hashtable http_params = req.getExtDataInHashtable(name);
+ // show certType specially
+ String certType = (String) http_params.get(IRequest.CERT_TYPE);
+
+ if (certType != null) {
+ arg.addStringValue(IRequest.CERT_TYPE, certType);
+ }
+ String presenceServerExt = (String) http_params.get("PresenceServerExtension");
+
+ if (presenceServerExt != null) {
+ arg.addStringValue("PresenceServerExtension", presenceServerExt);
+ }
+ // show all http parameters in request
+ int counter = 0;
+ Enumeration elms = http_params.keys();
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_PARAMS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n\r" +
+ prefix + parami + ".value=\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(
+ http_params.get(n).toString()) + "\"";
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // show all http headers stored in request.
+ else if (name.equals(IRequest.HTTP_HEADERS)) {
+ Hashtable http_hdrs = req.getExtDataInHashtable(name);
+ Enumeration elms = http_hdrs.keys();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_HEADERS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n\r" +
+ prefix + parami + ".value=\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(
+ http_hdrs.get(n).toString()) + "\"";
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // show all auth token stored in request.
+ else if (name.equals(IRequest.AUTH_TOKEN)) {
+ IAuthToken auth_token = req.getExtDataInAuthToken(name);
+ Enumeration elms = auth_token.getElements();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.AUTH_TOKEN + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ Object authTokenValue = auth_token.getInStringArray(n);
+ if (authTokenValue == null) {
+ authTokenValue = auth_token.getInString(n);
+ }
+ String v = expandValue(prefix + parami + ".value",
+ authTokenValue);
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n" + v;
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // all others are request attrs from policy or internal modules.
+ else {
+ Object val;
+ if (req.isSimpleExtDataValue(name)) {
+ val = req.getExtDataInString(name);
+ } else {
+ val = req.getExtDataInStringArray(name);
+ if (val == null) {
+ val = req.getExtDataInHashtable(name);
+ }
+ }
+ String valstr = "";
+ // hack
+ String parami =
+ IRequest.SERVER_ATTRS + LB + String.valueOf(saCounter++) + RB;
+
+ valstr = expandValue(prefix + parami + ".value", val);
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(name) + "\";\n" +
+ valstr; // java string already escaped in expandValue.
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ }
+
+ if (name.equals(IRequest.REQUESTOR_PHONE)
+ || name.equals(IRequest.REQUESTOR_EMAIL)
+ || name.equals(IRequest.REQUESTOR_COMMENTS)
+ || name.equals(IRequest.RESULT)
+ || name.equals(IRequest.REQUEST_TRUSTEDMGR_PRIVILEGE)
+ ) {
+ arg.addStringValue(name, req.getExtDataInString(name));
+ }
+
+ if (name.equals(IRequest.REQUESTOR_NAME)) {
+ String requestorName = req.getExtDataInString(name);
+
+ requestorName = requestorName.trim();
+ if (requestorName.length() > 0) {
+ arg.addStringValue(name, requestorName);
+ }
+ }
+
+ if (name.equals(IRequest.ERRORS)) {
+ Vector errorStrings = req.getExtDataInStringVector(name);
+ if (errorStrings != null) {
+ StringBuffer errInfo = new StringBuffer();
+
+ for (int i = 0; i < errorStrings.size(); i++) {
+ errInfo.append(errorStrings.elementAt(i));
+ errInfo.append("\n");
+ }
+ arg.addStringValue(IRequest.ERRORS, errInfo.toString());
+ }
+ }
+ if (name.equals(IRequest.ERROR)) {
+ arg.addStringValue(IRequest.ERRORS, req.getExtDataInString(name));
+ }
+
+ if (name.equals(IRequest.CERT_INFO)) {
+ // Get the certificate info from the request
+ X509CertInfo[] certInfo =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (certInfo != null && certInfo[0] != null) {
+ // Get the subject name if any set.
+ CertificateSubjectName subjectName = null;
+ String signatureAlgorithm = null;
+ String signatureAlgorithmName = null;
+
+ try {
+ subjectName = (CertificateSubjectName) certInfo[0].get(X509CertInfo.SUBJECT);
+ } catch (IOException e) {
+ // XXX raise exception
+ } catch (CertificateException e) {
+ // XXX raise exception
+ }
+ if (subjectName != null) {
+ String sn;
+
+ try {
+ sn = subjectName.toString();
+ } catch (java.lang.IllegalArgumentException e) {
+ sn = "* * Malformed Subject Name * *";
+ }
+ String subjectnamevalue = sn;
+
+ arg.addStringValue("subject", subjectnamevalue);
+ }
+
+ if (mDetails) {
+ try {
+ CertificateAlgorithmId certAlgId = (CertificateAlgorithmId)
+ certInfo[0].get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId algId = (AlgorithmId)
+ certAlgId.get(CertificateAlgorithmId.ALGORITHM);
+
+ signatureAlgorithm = (algId.getOID()).toString();
+ signatureAlgorithmName = algId.getName();
+ } catch (Exception e) {
+ // XXX raise exception
+ }
+ if (signatureAlgorithm != null) {
+ arg.addStringValue("signatureAlgorithm", signatureAlgorithm);
+ }
+ if (signatureAlgorithmName != null) {
+ arg.addStringValue("signatureAlgorithmName", signatureAlgorithmName);
+ }
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions) certInfo[0].get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ }
+ if (extensions != null) {
+ Enumeration exts = extensions.getElements();
+
+ while (exts.hasMoreElements()) {
+ Extension ext = (Extension) exts.nextElement();
+
+ // only know about ns cert type
+ if (ext instanceof NSCertTypeExtension) {
+ NSCertTypeExtension nsExtensions =
+ (NSCertTypeExtension) ext;
+
+ try {
+ arg.addStringValue("ext_" + NSCertTypeExtension.SSL_SERVER,
+ nsExtensions.get(NSCertTypeExtension.SSL_SERVER).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.SSL_CLIENT,
+ nsExtensions.get(NSCertTypeExtension.SSL_CLIENT).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.EMAIL,
+ nsExtensions.get(NSCertTypeExtension.EMAIL).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.OBJECT_SIGNING,
+ nsExtensions.get(NSCertTypeExtension.OBJECT_SIGNING).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.SSL_CA,
+ nsExtensions.get(NSCertTypeExtension.SSL_CA).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.EMAIL_CA,
+ nsExtensions.get(NSCertTypeExtension.EMAIL_CA).toString());
+
+ arg.addStringValue("ext_" + NSCertTypeExtension.OBJECT_SIGNING_CA,
+ nsExtensions.get(NSCertTypeExtension.OBJECT_SIGNING_CA).toString());
+
+ } catch (Exception e) {
+ }
+ } else if (ext instanceof BasicConstraintsExtension) {
+ BasicConstraintsExtension bcExt =
+ (BasicConstraintsExtension) ext;
+ Integer pathLength = null;
+ Boolean isCA = null;
+
+ try {
+ pathLength = (Integer) bcExt.get(BasicConstraintsExtension.PATH_LEN);
+ isCA = (Boolean) bcExt.get(BasicConstraintsExtension.IS_CA);
+ } catch (IOException e) {
+ }
+ if (pathLength != null)
+ arg.addIntegerValue("pathLenBasicConstraints", pathLength.intValue());
+ if (isCA != null)
+ arg.addBooleanValue("isCABasicConstraints", isCA.booleanValue());
+ } // pretty print all others.
+ else {
+ if (argSet != null) {
+ IArgBlock rr = CMS.createArgBlock();
+
+ rr.addStringValue(
+ EXT_PRETTYPRINT,
+ CMS.getExtPrettyPrint(ext, 0).toString());
+ argSet.addRepeatRecord(rr);
+ }
+ }
+ }
+
+ }
+
+ // Get the public key
+ CertificateX509Key certKey = null;
+
+ try {
+ certKey = (CertificateX509Key) certInfo[0].get(X509CertInfo.KEY);
+ } catch (IOException e) {
+ // XXX raise exception
+ } catch (CertificateException e) {
+ // XXX raise exception
+ }
+
+ X509Key key = null;
+
+ try {
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ } catch (IOException e) {
+ // XXX raise exception
+ }
+
+ if (key != null) {
+ arg.addStringValue("subjectPublicKeyInfo",
+ key.getAlgorithm() + " - " + key.getAlgorithmId().getOID().toString());
+ arg.addStringValue("subjectPublicKey",
+ pp.toHexString(key.getKey(), 0, 16));
+ }
+
+ // Get the validity period
+ CertificateValidity validity = null;
+
+ try {
+ validity =
+ (CertificateValidity)
+ certInfo[0].get(X509CertInfo.VALIDITY);
+ if (validity != null) {
+ long validityLength = (((Date) validity.get(CertificateValidity.NOT_AFTER)).getTime() - ((Date) validity.get(CertificateValidity.NOT_BEFORE)).getTime()) / 1000;
+
+ arg.addLongValue("validityLength", validityLength);
+ }
+ } catch (IOException e) {
+ // XXX raise exception
+ } catch (CertificateException e) {
+ // XXX raise exception
+ }
+ }
+ }
+ }
+
+ if (name.equals(IRequest.OLD_SERIALS) && mDetails) {
+ BigInteger oldSerialNo[] = req.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+
+ if (oldSerialNo != null) {
+ if (argSet != null) {
+ for (int i = 0; i < oldSerialNo.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ oldSerialNo[i], 16);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ }
+
+ if (name.equals(IRequest.ISSUED_CERTS) && mDetails &&
+ (req.getRequestStatus().toString().equals(RequestStatus.COMPLETE_STRING) ||
+ req.getRequestType().equals(IRequest.GETREVOCATIONINFO_REQUEST))) {
+ X509CertImpl issuedCert[] =
+ req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ arg.addBigIntegerValue("serialNumber", issuedCert[0].getSerialNumber(), 16);
+ // Set Serial No for 2nd certificate
+ if (issuedCert.length == 2)
+ arg.addBigIntegerValue("serialNumber2", issuedCert[1].getSerialNumber(), 16);
+ }
+ if (name.equals(IRequest.OLD_CERTS) && mDetails) {
+ X509CertImpl oldCert[] =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCert != null && oldCert.length > 0) {
+ arg.addBigIntegerValue("serialNumber", oldCert[0].getSerialNumber(), 16);
+ arg.addStringValue("subject", oldCert[0].getSubjectDN().toString());
+ if (req.getRequestType().equals(IRequest.GETCERTS_REQUEST)) {
+ for (int i = 0; i < oldCert.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ oldCert[i].getSerialNumber(), 16);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ }
+
+ if (name.equals(IRequest.CACERTCHAIN) && mDetails) {
+ byte[] certChainData = req.getExtDataInByteArray(
+ IRequest.CACERTCHAIN);
+ if (certChainData != null) {
+ CertificateChain certChain = new CertificateChain();
+ try {
+ certChain.decode(new ByteArrayInputStream(certChainData));
+
+ X509Certificate cert[] = certChain.getChain();
+
+ for (int i = 0; i < cert.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert[i].getSerialNumber(), 16);
+ argSet.addRepeatRecord(rarg);
+ }
+ } catch (IOException e) {
+ // XXX
+ }
+ }
+ }
+ if (name.equals(IRequest.FINGERPRINTS) && mDetails) {
+ Hashtable fingerprints =
+ req.getExtDataInHashtable(IRequest.FINGERPRINTS);
+
+ if (fingerprints != null) {
+ String namesAndHashes = null;
+ Enumeration enumFingerprints = fingerprints.keys();
+
+ while (enumFingerprints.hasMoreElements()) {
+ String hashname = (String) enumFingerprints.nextElement();
+ String hashvalue = (String) fingerprints.get(hashname);
+ byte[] fingerprint = CMS.AtoB(hashvalue);
+ String ppFingerprint = pp.toHexString(fingerprint, 0);
+
+ if (hashname != null && ppFingerprint != null) {
+ if (namesAndHashes != null) {
+ namesAndHashes += "+" + hashname + "+" + ppFingerprint;
+ } else {
+ namesAndHashes = hashname + "+" + ppFingerprint;
+ }
+ }
+ }
+ if (namesAndHashes != null) {
+ arg.addStringValue("fingerprints", namesAndHashes);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * print value out nicely in request attributes.
+ */
+ protected String expandValue(String valuename, Object v) {
+ try {
+ String valstr = "";
+
+ // if it's a vector
+ if (v instanceof Vector) {
+ valstr = valuename + "= new Array";
+ int j = 0;
+
+ StringBuffer sb = new StringBuffer();
+ for (Enumeration n = ((Vector) v).elements(); n.hasMoreElements(); j++) {
+ sb.append(";\n");
+ sb.append(valuename);
+ sb.append(LB);
+ sb.append(j);
+ sb.append(RB);
+ sb.append(EQ);
+ sb.append("\"");
+ sb.append(
+ CMSTemplate.escapeJavaScriptStringHTML(
+ n.nextElement().toString()));
+ sb.append( "\";\n");
+ }
+ sb.append("\n");
+ valstr = sb.toString();
+ return valstr;
+ }
+
+ // if an array.
+ int len = -1;
+
+ try {
+ len = Array.getLength(v);
+ } catch (IllegalArgumentException e) {
+ }
+ if (len >= 0) { // is an array; access each object in array.
+ valstr = valuename + "= new Array";
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (Array.get(v, i) != null)
+ valstr += ";\n" + valuename + LB + i + RB + EQ + "\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(
+ Array.get(v, i).toString()) + "\";\n";
+ }
+ return valstr;
+ }
+ } catch (Throwable e) {
+ }
+
+ // if string or unrecognized type, just call its toString method.
+ return valuename + "=\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(v.toString()) + "\"";
+ }
+
+ public String getRequestorDN(IRequest request) {
+ try {
+ X509CertInfo info = (X509CertInfo)
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+ // retrieve the subject name
+ CertificateSubjectName sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+
+ return sn.toString();
+ } catch (Exception e) {
+ CMS.debug("CertReqParser: getRequestorDN " + e.toString());
+ }
+ return null;
+ }
+
+ public String getKeyID(IRequest request) {
+ try {
+ String kid = null;
+
+ String cid = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
+ if (cid == null) {
+ cid = "";
+ }
+ String uid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
+ if (uid == null) {
+ uid = "";
+ }
+ kid = cid+":"+uid;
+ if (kid.equals(":")) {
+ kid = "";
+ }
+
+ return kid;
+ } catch (Exception e) {
+ CMS.debug("CertReqParser: getKeyID " + e.toString());
+ }
+ return null;
+ }
+
+ private void fillRevokeRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException {
+ // fill in the standard attributes
+ super.fillRequestIntoArg(l, req, argSet, arg);
+
+ arg.addStringValue("certExtsEnabled", "yes");
+ String profile = req.getExtDataInString("profile");
+
+ //CMS.debug("CertReqParser: profile=" + profile);
+ if (profile != null) {
+ arg.addStringValue("profile", profile);
+ String requestorDN = getRequestorDN(req);
+
+ if (requestorDN != null) {
+ arg.addStringValue("subject", requestorDN);
+ }
+ } else {
+ arg.addStringValue("profile", "false");
+ String keyID = getKeyID(req);
+
+ if (keyID != null) {
+ arg.addStringValue("subject", keyID);
+ }
+ }
+
+ int saCounter = 0;
+ Enumeration enum1 = req.getExtDataKeys();
+
+ // gross hack
+ String prefix = "record.";
+
+ if (argSet.getHeader() == arg)
+ prefix = "header.";
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (mDetails) {
+ // show all http parameters stored in request.
+ if (name.equals(IRequest.HTTP_PARAMS)) {
+ Hashtable http_params = req.getExtDataInHashtable(name);
+ // show certType specially
+ String certType = (String) http_params.get(IRequest.CERT_TYPE);
+
+ if (certType != null) {
+ arg.addStringValue(IRequest.CERT_TYPE, certType);
+ }
+ // show all http parameters in request
+ int counter = 0;
+ Enumeration elms = http_params.keys();
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_PARAMS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n\r" +
+ prefix + parami + ".value=\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(
+ http_params.get(n).toString()) + "\"";
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // show all http headers stored in request.
+ else if (name.equals(IRequest.HTTP_HEADERS)) {
+ Hashtable http_hdrs = req.getExtDataInHashtable(name);
+ Enumeration elms = http_hdrs.keys();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_HEADERS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n\r" +
+ prefix + parami + ".value=\"" +
+ CMSTemplate.escapeJavaScriptStringHTML(
+ http_hdrs.get(n).toString()) + "\"";
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // show all auth token stored in request.
+ else if (name.equals(IRequest.AUTH_TOKEN)) {
+ IAuthToken auth_token = req.getExtDataInAuthToken(name);
+ Enumeration elms = auth_token.getElements();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.AUTH_TOKEN + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = (String) elms.nextElement();
+ String v =
+ expandValue(prefix + parami + ".value",
+ auth_token.getInString(n));
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(n) + "\";\n" + v;
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ } // all others are request attrs from policy or internal modules.
+ else {
+ Object val;
+ if (req.isSimpleExtDataValue(name)) {
+ val = req.getExtDataInString(name);
+ } else {
+ val = req.getExtDataInStringArray(name);
+ if (val == null) {
+ val = req.getExtDataInHashtable(name);
+ }
+ }
+ String valstr = "";
+ // hack
+ String parami =
+ IRequest.SERVER_ATTRS + LB + String.valueOf(saCounter++) + RB;
+
+ valstr = expandValue(prefix + parami + ".value", val);
+ String rawJS = "new Object;\n\r" +
+ prefix + parami + ".name=\"" +
+ CMSTemplate.escapeJavaScriptString(name) + "\";\n" +
+ valstr; // java string already escaped in expandValue.
+
+ arg.set(parami, new RawJS(rawJS));
+ }
+ }
+
+ if (name.equals(IRequest.REQUESTOR_PHONE)
+ || name.equals(IRequest.REQUESTOR_EMAIL)
+ || name.equals(IRequest.REQUESTOR_COMMENTS)
+ || name.equals(IRequest.RESULT)
+ || name.equals(IRequest.REQUEST_TRUSTEDMGR_PRIVILEGE)
+ ) {
+ arg.addStringValue(name, req.getExtDataInString(name));
+ }
+
+ if (name.equals(IRequest.REQUESTOR_NAME)) {
+ String requestorName = req.getExtDataInString(name);
+
+ requestorName = requestorName.trim();
+ if (requestorName.length() > 0) {
+ arg.addStringValue(name, requestorName);
+ }
+ }
+
+ if (name.equals(IRequest.ERRORS)) {
+ Vector errorsVector = req.getExtDataInStringVector(name);
+ if (errorsVector != null) {
+ StringBuffer errInfo = new StringBuffer();
+
+ for (int i = 0; i < errorsVector.size(); i++) {
+ errInfo.append(errorsVector.elementAt(i));
+ errInfo.append("\n");
+ }
+ arg.addStringValue(IRequest.ERRORS, errInfo.toString());
+ }
+ }
+ if (name.equals(IRequest.ERROR)) {
+ arg.addStringValue(IRequest.ERRORS, req.getExtDataInString(name));
+ }
+
+ if (name.equals(IRequest.CERT_INFO)) {
+ // Get the certificate info from the request
+ RevokedCertImpl revokedCert[] = req.getExtDataInRevokedCertArray(IRequest.CERT_INFO);
+
+ if (mDetails && revokedCert != null) {
+ if (argSet != null) {
+ for (int i = 0; i < revokedCert.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ revokedCert[i].getSerialNumber(), 16);
+
+ CRLExtensions crlExtensions = revokedCert[i].getExtensions();
+
+ if (crlExtensions != null) {
+ for (int k = 0; k < crlExtensions.size(); k++) {
+ Extension ext = (Extension) crlExtensions.elementAt(k);
+
+ if (ext instanceof CRLReasonExtension) {
+ rarg.addStringValue("reason",
+ ((CRLReasonExtension) ext).getReason().toString());
+ }
+ }
+ } else {
+ rarg.addStringValue("reason",
+ RevocationReason.UNSPECIFIED.toString());
+ }
+
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ arg.addBigIntegerValue("serialNumber",
+ revokedCert[0].getSerialNumber(), 16);
+ }
+ }
+ }
+
+ if (name.equals(IRequest.OLD_SERIALS) && mDetails) {
+ BigInteger oldSerialNo[] = req.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+
+ if (oldSerialNo != null) {
+ if (argSet != null) {
+ for (int i = 0; i < oldSerialNo.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ oldSerialNo[i], 16);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ }
+
+ if (name.equals(IRequest.OLD_CERTS) && mDetails) {
+ //X509CertImpl oldCert[] =
+ // (X509CertImpl[])req.get(IRequest.OLD_CERTS);
+ Certificate oldCert[] =
+ (Certificate[]) req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCert != null && oldCert.length > 0) {
+ if (oldCert[0] instanceof X509CertImpl) {
+ X509CertImpl xcert = (X509CertImpl) oldCert[0];
+
+ arg.addBigIntegerValue("serialNumber", xcert.getSerialNumber(), 16);
+ arg.addStringValue("subject", xcert.getSubjectDN().toString());
+ if (req.getRequestType().equals(IRequest.GETCERTS_REQUEST)) {
+ for (int i = 0; i < oldCert.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ xcert = (X509CertImpl) oldCert[i];
+ rarg.addBigIntegerValue("serialNumber",
+ xcert.getSerialNumber(), 16);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ }
+ }
+
+ if (name.equals(IRequest.REVOKED_CERTS) && mDetails &&
+ req.getRequestType().equals("getRevocationInfo")) {
+ RevokedCertImpl revokedCert[] =
+ req.getExtDataInRevokedCertArray(IRequest.REVOKED_CERTS);
+
+ if (revokedCert != null && revokedCert[0] != null) {
+ boolean reasonFound = false;
+ CRLExtensions crlExtensions = revokedCert[0].getExtensions();
+
+ for (int k = 0; k < crlExtensions.size(); k++) {
+ Extension ext = (Extension) crlExtensions.elementAt(k);
+
+ if (ext instanceof CRLReasonExtension) {
+ arg.addStringValue("reason",
+ ((CRLReasonExtension) ext).getReason().toString());
+ reasonFound = true;
+ }
+ }
+ if (reasonFound == false) {
+ arg.addStringValue("reason", "unknown");
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java b/pki/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java
new file mode 100644
index 000000000..162946c74
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java
@@ -0,0 +1,591 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.pkcs.*;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.pkix.cmc.*;
+import org.mozilla.jss.pkix.cms.*;
+import org.mozilla.jss.pkix.cert.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.asn1.*;
+
+
+/**
+ * Check the status of a certificate request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CheckRequest extends CMSServlet {
+ // constants
+ public static String FULL_RESPONSE = "cmcFullEnrollmentResponse";
+ private final static String INFO = "CheckRequest";
+ private final static String REQ_ID = "requestId";
+ private final static String REQ_TYPE = "requestType";
+ private final static String STATUS = "status";
+ private final static String CREATE_ON = "createdOn";
+ private final static String UPDATE_ON = "updatedOn";
+ private final static String UPDATE_BY = "updatedBy";
+
+ private final static String TPL_FILE = "requestStatus.template";
+
+ // variables
+ private IRequestQueue mQueue = null;
+ private String mFormPath = null;
+ private String mAuthorityId = null;
+
+ public CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Constructs request query servlet.
+ */
+ public CheckRequest()
+ throws EBaseException {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "requestStatus.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mQueue = mAuthority.getRequestQueue();
+ mAuthorityId = mAuthority.getId();
+ mFormPath = "/" + mAuthorityId + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param requestId ID of the request to check
+ * <li>http.param format if 'id', then check the request based on
+ * the request ID parameter. If set to CMC, then use the
+ * 'queryPending' parameter.
+ * <li>http.param queryPending query formatted as a CMC request
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("checkRequest: in process!");
+ SET transIds = null, rNonces = null, sNonces = null;
+ boolean isCMCReq = false;
+ INTEGER bodyPartId = null;
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // Note error is covered in the same template as success.
+ EBaseException error = null;
+
+ String requestId = req.getParameter("requestId");
+ String format = req.getParameter("format");
+
+ CMS.debug("checkRequest: requestId " + requestId);
+
+ // They may check the status using CMC queryPending
+ String queryPending = req.getParameter("queryPending");
+
+ if (format != null && format.equals("cmc") && queryPending != null && !queryPending.equals("")) {
+ try {
+ isCMCReq = true;
+ byte[] cmcBlob = CMS.AtoB(queryPending);
+ ByteArrayInputStream cmcBlobIn =
+ new ByteArrayInputStream(cmcBlob);
+
+ org.mozilla.jss.pkix.cms.ContentInfo cii = (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(cmcBlobIn);
+ SignedData cmcFullReq = (SignedData)
+ cii.getInterpretedContent();
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+
+ OBJECT_IDENTIFIER id = ci.getContentType();
+
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) || !ci.hasContent()) {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_PKIDATA"));
+ }
+ OCTET_STRING content = ci.getContent();
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SEQUENCE controlSequence = pkiData.getControlSequence();
+ int numControls = controlSequence.size();
+
+ for (int i = 0; i < numControls; i++) {
+ // decode message.
+ TaggedAttribute taggedAttr = (TaggedAttribute) controlSequence.elementAt(i);
+ OBJECT_IDENTIFIER type = taggedAttr.getType();
+
+ if (type.equals(OBJECT_IDENTIFIER.id_cmc_QueryPending)) {
+ bodyPartId = taggedAttr.getBodyPartID();
+ SET requestIds = taggedAttr.getValues();
+ int numReq = requestIds.size();
+
+ // We only process one for now.
+ if (numReq > 0) {
+ OCTET_STRING reqId = (OCTET_STRING)
+ ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(requestIds.elementAt(0)));
+
+ requestId = new String(reqId.toByteArray());
+ }
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_transactionId)) {
+ transIds = taggedAttr.getValues();
+ }else if
+ (type.equals(OBJECT_IDENTIFIER.id_cmc_recipientNonce)) {
+ rNonces = taggedAttr.getValues();
+ } else if
+ (type.equals(OBJECT_IDENTIFIER.id_cmc_senderNonce)) {
+ sNonces = taggedAttr.getValues();
+ }
+ }
+ } catch (Exception e) {
+ error = new EBaseException(e.toString());
+ }
+ }
+
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ boolean importCert = httpParams.getValueAsBoolean("importCert",
+ false);
+ // xxx need to check why this is not available at startup
+ X509Certificate mCACerts[] = null;
+
+ try {
+ mCACerts = ((ICertAuthority) mAuthority).getCACertChain().getChain();
+ } catch (Exception e) {
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CA_CHAIN_NOT_AVAILABLE"));
+ }
+
+ if (requestId == null || requestId.trim().equals("")) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_REQUEST_ID_PROVIDED"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_REQUEST_ID_PROVIDED"));
+ }
+ try {
+ Integer.parseInt(requestId);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", requestId));
+ throw new EBaseException(
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId));
+ }
+
+ IRequest r = mQueue.findRequest(new RequestId(requestId));
+
+ if (r == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND_1", requestId));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId));
+ }
+
+ if (authToken != null) {
+ // if RA, requestOwner must match the group
+ String group = authToken.getInString("group");
+ if ((group != null) && (group != "")) {
+ if (group.equals("Registration Manager Agents")) {
+ boolean groupMatched = false;
+ String requestOwner = r.getExtDataInString("requestOwner");
+ if (requestOwner != null) {
+ if (requestOwner.equals(group))
+ groupMatched = true;
+ }
+ if (groupMatched == false) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", requestId.toString()));
+ throw new EBaseException(
+ CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId));
+ }
+ }
+ }
+ }
+
+ RequestStatus status = r.getRequestStatus();
+ String note = r.getExtDataInString("requestNotes");
+
+ header.addStringValue("authority", mAuthorityId);
+ header.addLongValue(REQ_ID, Long.parseLong(r.getRequestId().toString()));
+ header.addStringValue(STATUS, status.toString());
+ header.addLongValue(CREATE_ON, r.getCreationTime().getTime() / 1000);
+ header.addLongValue(UPDATE_ON, r.getModificationTime().getTime() / 1000);
+ if (note != null && note.length() > 0)
+ header.addStringValue("requestNotes", note);
+
+ String type = r.getRequestType();
+ Integer result = r.getExtDataInInteger(IRequest.RESULT);
+
+/* if (type.equals(IRequest.ENROLLMENT_REQUEST) && (r.get("profile") != null) && status.equals(RequestStatus.COMPLETE)) {
+ X509CertImpl cert = (X509CertImpl) r.get(IEnrollProfile.REQUEST_ISSUED_CERT);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+ argSet.addRepeatRecord(rarg);
+ }
+*/
+ String profileId = r.getExtDataInString("profileId");
+ if (profileId != null) {
+ result = IRequest.RES_SUCCESS;
+ }
+ if ((type != null) && (type.equals(IRequest.ENROLLMENT_REQUEST) ||
+ type.equals(IRequest.RENEWAL_REQUEST)) && (status != null) &&
+ status.equals(RequestStatus.COMPLETE) && (result != null) &&
+ result.equals(IRequest.RES_SUCCESS)) {
+ Object o = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (profileId != null) {
+ X509CertImpl impl[] = new X509CertImpl[1];
+ impl[0] = r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ o = impl;
+ }
+ if (o != null && (o instanceof X509CertImpl[])) {
+ X509CertImpl[] certs = (X509CertImpl[]) o;
+
+ if (certs != null && certs.length > 0) {
+ for (int i = 0; i < certs.length; i++) {
+ if (certs[i] != null) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ certs[i].getSerialNumber(), 16);
+ // add pkcs7 cert for importing
+ if (importCert || isCMCReq) {
+ //byte[] ba = certs[i].getEncoded();
+ X509CertImpl[] certsInChain = new X509CertImpl[1];;
+ if (mCACerts != null) {
+ for (int ii = 0; ii < mCACerts.length; ii++) {
+ if (certs[i].equals(mCACerts[ii])) {
+ certsInChain = new
+ X509CertImpl[mCACerts.length];
+ break;
+ }
+ certsInChain = new X509CertImpl[mCACerts.length + 1];
+ }
+ }
+
+ // Set the EE cert
+ certsInChain[0] = certs[i];
+
+ // Set the Ca certificate chain
+ if (mCACerts != null) {
+ for (int ii = 0; ii < mCACerts.length; ii++) {
+ if (!certs[i].equals(mCACerts[ii]))
+ certsInChain[ii + 1] = (X509CertImpl) mCACerts[ii];
+ }
+ }
+ // Wrap the chain into a degenerate P7 object
+ String p7Str;
+
+ try {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new netscape.security.pkcs.ContentInfo(new byte[0]),
+ certsInChain,
+ new netscape.security.pkcs.SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+
+ p7Str = CMS.BtoA(p7Bytes);
+
+ StringTokenizer tokenizer = null;
+
+ if (File.separator.equals("\\")) {
+ char[] nl = new char[2];
+
+ nl[0] = 10;
+ nl[1] = 13;
+ String nlstr = new String(nl);
+
+ tokenizer = new StringTokenizer(p7Str, nlstr);
+ } else
+ tokenizer = new StringTokenizer(p7Str, "\n");
+ StringBuffer res = new StringBuffer();
+
+ while (tokenizer.hasMoreTokens()) {
+ String elem = (String) tokenizer.nextToken();
+
+ res.append(elem);
+ }
+
+ header.addStringValue("pkcs7ChainBase64", res.toString());
+
+ // compose full response
+ if (isCMCReq) {
+ SEQUENCE controlSeq = new SEQUENCE();
+ int bpid = 1;
+ SEQUENCE bpids = new SEQUENCE();
+
+ if (bodyPartId != null)
+ bpids.addElement(bodyPartId);
+ CMCStatusInfo cmcStatusInfo = new
+ CMCStatusInfo(CMCStatusInfo.SUCCESS, bpids);
+ TaggedAttribute ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo,
+ cmcStatusInfo);
+
+ controlSeq.addElement(ta);
+
+ // copy transactionID, senderNonce,
+ // create recipientNonce
+ if (transIds != null) {
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_transactionId,
+ transIds);
+ controlSeq.addElement(ta);
+ }
+
+ if (sNonces != null) {
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_recipientNonce,
+ sNonces);
+ controlSeq.addElement(ta);
+ }
+
+ String salt = CMSServlet.generateSalt();
+ byte[] dig;
+
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+
+ dig = SHA1Digest.digest(salt.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ dig = salt.getBytes();
+ }
+ String b64E = CMS.BtoA(dig);
+ String[] newNonce = {b64E};
+
+ ta = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(newNonce[0].getBytes()));
+ controlSeq.addElement(ta);
+
+ ResponseBody rb = new ResponseBody(controlSeq, new
+ SEQUENCE(), new
+ SEQUENCE());
+ EncapsulatedContentInfo ci = new
+ EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIResponse,
+ rb);
+
+ org.mozilla.jss.crypto.X509Certificate x509cert = null;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ x509cert = ((ICertificateAuthority) mAuthority).getCaX509Cert();
+ }else if (mAuthority instanceof IRegistrationAuthority) {
+ x509cert = ((IRegistrationAuthority) mAuthority).getRACert();
+ }
+ if (x509cert == null)
+ throw new
+ ECMSGWException(CMS.getUserMessage("CMS_GW_CMC_ERROR", "No signing cert found."));
+
+ X509CertImpl cert = new X509CertImpl(x509cert.getEncoded());
+ ByteArrayInputStream issuer1 = new
+ ByteArrayInputStream(((X500Name) cert.getIssuerDN()).getEncoded());
+ Name issuer = (Name) Name.getTemplate().decode(issuer1);
+ IssuerAndSerialNumber ias = new
+ IssuerAndSerialNumber(issuer, new INTEGER(cert.getSerialNumber().toString()));
+ SignerIdentifier si = new
+ SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+
+ // SHA1 is the default digest Alg for now.
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = null;
+ org.mozilla.jss.crypto.PrivateKey privKey = CryptoManager.getInstance().findPrivKeyByCert(x509cert);
+ org.mozilla.jss.crypto.PrivateKey.Type keyType = privKey.getType();
+
+ if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.RSA))
+ signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ else if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.DSA))
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ MessageDigest SHADigest = null;
+ byte[] digest = null;
+
+ try {
+ SHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg = DigestAlgorithm.SHA1;
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ rb.encode((OutputStream) ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException ex) {
+ //log("digest fail");
+ }
+
+ org.mozilla.jss.pkix.cms.SignerInfo signInfo = new
+ org.mozilla.jss.pkix.cms.SignerInfo(si, null, null,
+ OBJECT_IDENTIFIER.id_cct_PKIResponse,
+ digest, signAlg,
+ privKey);
+ SET signInfos = new SET();
+
+ signInfos.addElement(signInfo);
+
+ SET digestAlgs = new SET();
+
+ if (digestAlg != null) {
+ AlgorithmIdentifier ai = new
+ AlgorithmIdentifier(digestAlg.toOID(),
+ null);
+
+ digestAlgs.addElement(ai);
+ }
+
+ SET jsscerts = new SET();
+
+ for (int j = 0; j < certsInChain.length; j++) {
+ ByteArrayInputStream is = new
+ ByteArrayInputStream(certsInChain[j].getEncoded());
+ org.mozilla.jss.pkix.cert.Certificate certJss = (org.mozilla.jss.pkix.cert.Certificate)
+ org.mozilla.jss.pkix.cert.Certificate.getTemplate().decode(is);
+
+ jsscerts.addElement(certJss);
+ }
+
+ SignedData fResponse = new
+ SignedData(digestAlgs, ci,
+ jsscerts, null, signInfos);
+ org.mozilla.jss.pkix.cms.ContentInfo fullResponse = new
+ org.mozilla.jss.pkix.cms.ContentInfo(org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA, fResponse);
+ ByteArrayOutputStream ostream = new
+ ByteArrayOutputStream();
+
+ fullResponse.encode((OutputStream) ostream);
+ byte[] fr = ostream.toByteArray();
+
+ header.addStringValue(FULL_RESPONSE, CMS.BtoA(fr));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_FORMING_PKCS7_ERROR"));
+ }
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ }
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/IReqParser.java b/pki/base/common/src/com/netscape/cms/servlet/request/IReqParser.java
new file mode 100644
index 000000000..a41264f70
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/IReqParser.java
@@ -0,0 +1,55 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * An interface representing a request parser which
+ * converts Java request object into name value
+ * pairs and vice versa.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IReqParser {
+
+ /**
+ * Maps request object into argument block.
+ */
+ public void fillRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java
new file mode 100644
index 000000000..00039067b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java
@@ -0,0 +1,83 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.key.KeyRecordParser;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+
+/**
+ * Output a 'pretty print' of a Key Archival request
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyReqParser extends ReqParser {
+
+ public static final KeyReqParser PARSER = new KeyReqParser();
+ public static final String OUTPUT_SERIALNO = "serialNumber";
+
+ /**
+ * Constructs a certificate request parser.
+ */
+ public KeyReqParser() {
+ }
+
+ /**
+ * Fills in certificate specific request attributes.
+ */
+ public void fillRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException {
+ // fill in the standard attributes
+ super.fillRequestIntoArg(l, req, argSet, arg);
+
+ String type = req.getRequestType();
+
+ if (type.equals(IRequest.ENROLLMENT_REQUEST)) {
+ BigInteger recSerialNo = req.getExtDataInBigInteger("keyRecord");
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority)CMS.getSubsystem("kra");
+ if (kra != null) {
+ KeyRecordParser.fillRecordIntoArg(
+ kra.getKeyRepository().readKeyRecord(recSerialNo),
+ arg);
+ } else {
+ throw new EBaseException("KRA is not available");
+ }
+
+ } else if (type.equals(IRequest.KEYRECOVERY_REQUEST)) {
+ BigInteger kid = req.getExtDataInBigInteger("serialNumber");
+
+ arg.addStringValue(OUTPUT_SERIALNO, kid.toString());
+
+ // for async recovery
+ String agents = (String) req.getExtDataInString("approvingAgents");
+ arg.addStringValue("approvingAgents", agents);
+ } else {
+ System.out.println("Bad Request " + type);
+ // invalid request
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java b/pki/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java
new file mode 100644
index 000000000..6ad77a3f6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java
@@ -0,0 +1,1912 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.extensions.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.cms.servlet.cert.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Agent operations on Certificate requests. This servlet is used
+ * by an Agent to approve, reject, reassign, or change a certificate
+ * request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProcessCertReq extends CMSServlet {
+
+ private final static String INFO = "processReq";
+ private final static String SEQNUM = "seqNum";
+ private final static String TO_DO = "toDo";
+ private final static String TPL_FILE = "processCertReq.template";
+
+ private IRequestQueue mQueue = null;
+ private String mFormPath = null;
+ private IReqParser mParser = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private boolean mExtraAgentParams = false;
+
+ // for RA only since it does not have a database.
+ private final static String
+ REQ_COMPLETED_TEMPLATE = "ra/RequestCompleted.template";
+ private final static String
+ PROP_REQ_COMPLETED_TEMPLATE = "requestCompletedTemplate";
+ private final static String
+ PROP_EXTRA_AGENT_PARAMS = "extraAgentParams";
+ private static ICMSTemplateFiller
+ REQ_COMPLETED_FILLER = new RAReqCompletedFiller();
+ private String mReqCompletedTemplate = null;
+ private final static String
+ CERT_TYPE = "certType";
+
+ private String auditServiceID = ILogger.UNIDENTIFIED;
+ private final static String AGENT_CA_CLONE_ENROLLMENT_SERVLET =
+ "caProcessCertReq";
+ private final static String AGENT_RA_CLONE_ENROLLMENT_SERVLET =
+ "raProcessCertReq";
+ private final static String SIGNED_AUDIT_ACCEPTANCE = "accept";
+ private final static String SIGNED_AUDIT_CANCELLATION = "cancel";
+ private final static String SIGNED_AUDIT_CLONING = "clone";
+ private final static String SIGNED_AUDIT_REJECTION = "reject";
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String[]
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON = new String[] {
+
+ /* 0 */ "manual non-profile cert request cancellation: "
+ + "request cannot be processed due to an "
+ + "authorization failure",
+
+ /* 1 */ "manual non-profile cert request cancellation: "
+ + "no reason has been given for cancelling this "
+ + "cert request",
+
+ /* 2 */ "manual non-profile cert request cancellation: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException",
+
+ /* 3 */ "manual non-profile cert request cancellation: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an IOException",
+
+ /* 4 */ "manual non-profile cert request cancellation: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to a CertificateException",
+
+ /* 5 */ "manual non-profile cert request cancellation: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to a NoSuchAlgorithmException"
+ };
+ private final static String[]
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON = new String[] {
+
+ /* 0 */ "manual non-profile cert request rejection: "
+ + "request cannot be processed due to an "
+ + "authorization failure",
+
+ /* 1 */ "manual non-profile cert request rejection: "
+ + "no reason has been given for rejecting this "
+ + "cert request",
+
+ /* 2 */ "manual non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException",
+
+ /* 3 */ "manual non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an IOException",
+
+ /* 4 */ "manual non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to a CertificateException",
+
+ /* 5 */ "manual non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to a NoSuchAlgorithmException"
+ };
+ private final static String
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST =
+ "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ /**
+ * Process request.
+ */
+ public ProcessCertReq()
+ throws EBaseException {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "processCertReq.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ try {
+ super.init(sc);
+
+ // determine the service ID for signed audit log messages
+ String id = sc.getInitParameter(CMSServlet.PROP_ID);
+
+ if (id != null) {
+ if (!(auditServiceID.equals(
+ AGENT_CA_CLONE_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ AGENT_RA_CLONE_ENROLLMENT_SERVLET))) {
+ auditServiceID = ILogger.UNIDENTIFIED;
+ } else {
+ auditServiceID = id.trim();
+ }
+ }
+
+ mQueue = mAuthority.getRequestQueue();
+ mPublisherProcessor =
+ ((ICertAuthority) mAuthority).getPublisherProcessor();
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mParser = CertReqParser.DETAIL_PARSER;
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ try {
+ mReqCompletedTemplate = sc.getInitParameter(
+ PROP_REQ_COMPLETED_TEMPLATE);
+ if (mReqCompletedTemplate == null)
+ mReqCompletedTemplate = REQ_COMPLETED_TEMPLATE;
+ String tmp = sc.getInitParameter(PROP_EXTRA_AGENT_PARAMS);
+
+ if (tmp != null && tmp.trim().equalsIgnoreCase("true"))
+ mExtraAgentParams = true;
+ else
+ mExtraAgentParams = false;
+ } catch (Exception e) {
+ // does not happen.
+ }
+ } catch (ServletException eAudit1) {
+ // rethrow caught exception
+ throw eAudit1;
+ }
+ }
+
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param seqNum request id
+ * <li>http.param notValidBefore certificate validity
+ * - notBefore - in seconds since jan 1, 1970
+ * <li>http.param notValidAfter certificate validity
+ * - notAfter - in seconds since jan 1, 1970
+ * <li>http.param subject certificate subject name
+ * <li>http.param toDo requested action
+ * (can be one of: clone, reject, accept, cancel)
+ * <li>http.param signatureAlgorithm certificate signing algorithm
+ * <li>http.param addExts base-64, DER encoded Extension or
+ * SEQUENCE OF Extensions to add to certificate
+ * <li>http.param pathLenConstraint integer path length constraint to
+ * use in BasicConstraint extension if applicable
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ long startTime = CMS.getCurrentDate().getTime();
+ String toDo = null;
+ String subject = null;
+ String signatureAlgorithm = null;
+ long notValidBefore = 0;
+ long notValidAfter = 0;
+ int seqNum = -1;
+ EBaseException error = null;
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ CMSTemplate form = null, errorForm = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ if (req.getParameter(SEQNUM) != null) {
+ CMS.debug(
+ "ProcessCertReq: parameter seqNum " + req.getParameter(SEQNUM));
+ seqNum = Integer.parseInt(req.getParameter(SEQNUM));
+ }
+ String notValidBeforeStr = req.getParameter("notValidBefore");
+
+ if (notValidBeforeStr != null && notValidBeforeStr.length() > 0) {
+ notValidBefore = Long.parseLong(notValidBeforeStr);
+ notValidBefore *= 1000;
+ }
+ String notValidAfterStr = req.getParameter("notValidAfter");
+
+ if (notValidAfterStr != null && notValidAfterStr.length() > 0) {
+ notValidAfter = Long.parseLong(notValidAfterStr);
+ notValidAfter *= 1000;
+ }
+
+ toDo = req.getParameter("toDo");
+
+ subject = req.getParameter("subject");
+ signatureAlgorithm = req.getParameter("signatureAlgorithm");
+
+
+ IRequest r = null;
+
+ if (seqNum > -1) {
+ r = mQueue.findRequest(new RequestId(
+ Integer.toString(seqNum)));
+ }
+
+ if(seqNum > -1 && r != null)
+ {
+ processX509(cmsReq, argSet, header, seqNum, req, resp,
+ toDo, signatureAlgorithm, subject,
+ notValidBefore, notValidAfter, locale[0], startTime);
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_REQUEST_ID_1", String.valueOf(seqNum)));
+ error = new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_REQUEST_ID",
+ String.valueOf(seqNum)));
+ }
+ } catch (EBaseException e) {
+ error = e;
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, "Error " + e);
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ String output = form.getOutput(argSet);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ return;
+ }
+
+ /**
+ * Process X509 certificate enrollment request and send request information
+ * to the caller.
+ * <P>
+ *
+ * (Certificate Request - an "agent" cert request for "cloning")
+ * <P>
+ *
+ * (Certificate Request Processed - either a manual "agent" non-profile
+ * based cert acceptance, a manual "agent" non-profile based cert
+ * cancellation, or a manual "agent" non-profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST used when a
+ * non-profile cert request is made (before approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param cmsReq a certificate enrollment request
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param seqNum sequence number
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param toDo string representing the requested action (can be one of:
+ * clone, reject, accept, cancel)
+ * @param signatureAlgorithm string containing the signature algorithm
+ * @param subject string containing the subject name of the certificate
+ * @param notValidBefore certificate validity - notBefore - in seconds
+ * since Jan 1, 1970
+ * @param notValidAfter certificate validity - notAfter - in seconds since
+ * Jan 1, 1970
+ * @param locale the system locale
+ * @param startTime the current date
+ * @exception EBaseException an error has occurred
+ */
+ private void processX509(CMSRequest cmsReq,
+ CMSTemplateParams argSet, IArgBlock header,
+ int seqNum, HttpServletRequest req,
+ HttpServletResponse resp,
+ String toDo, String signatureAlgorithm,
+ String subject,
+ long notValidBefore, long notValidAfter,
+ Locale locale, long startTime)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditCertificateSubjectName = subject;
+ String auditInfoName = auditInfoName(toDo);
+ String id = null;
+
+ // "normalize" the "auditCertificateSubjectName"
+ if (auditCertificateSubjectName != null) {
+ // NOTE: This is ok even if the cert subject name is "" (empty)!
+ auditCertificateSubjectName = auditCertificateSubjectName.trim();
+ } else {
+ // NOTE: Here, the cert subject name is MISSING, not "" (empty)!
+ auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ try {
+ IRequest r = mQueue.findRequest(new RequestId(
+ Integer.toString(seqNum)));
+
+ if (r != null) {
+ // overwrite "auditRequesterID" if and only if "id" != null
+ id = r.getRequestId().toString();
+ if (id != null) {
+ auditRequesterID = id.trim();
+ }
+ }
+
+ if (mAuthority != null)
+ header.addStringValue("authorityid", mAuthority.getId());
+
+ if (toDo != null) {
+ // for audit log
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "execute");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE",
+ e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE",
+ e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+
+ // store a message in the signed audit log file
+ if (toDo.equals(SIGNED_AUDIT_CLONING)) {
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ // (manual "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_CANCELLATION)) {
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[0]);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_REJECTION)) {
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[0]);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+ String agentID = authToken.getInString("userid");
+ String initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] = r.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ header.addStringValue("toDo", toDo);
+ if (toDo.equals("accept")) {
+
+ if (certInfo != null) {
+ int alterationCounter = 0;
+
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateAlgorithmId certAlgId =
+ (CertificateAlgorithmId)
+ certInfo[i].get(X509CertInfo.ALGORITHM_ID);
+
+ AlgorithmId algId = (AlgorithmId)
+ certAlgId.get(CertificateAlgorithmId.ALGORITHM);
+
+ if (!(algId.getName().equals(signatureAlgorithm))) {
+ alterationCounter++;
+ AlgorithmId newAlgId = AlgorithmId.getAlgorithmId(signatureAlgorithm);
+
+ certInfo[i].set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(newAlgId));
+ }
+
+ CertificateSubjectName certSubject =
+ (CertificateSubjectName)
+ certInfo[i].get(X509CertInfo.SUBJECT);
+
+ if (subject != null &&
+ !(certSubject.toString().equals(subject))) {
+
+ alterationCounter++;
+ certInfo[i].set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(
+ (new X500Name(subject))));
+ }
+
+ CertificateValidity certValidity =
+ (CertificateValidity)
+ certInfo[i].get(X509CertInfo.VALIDITY);
+ Date currentTime = CMS.getCurrentDate();
+ boolean validityChanged = false;
+
+ // only override these values if agent specified them
+ if (notValidBefore > 0) {
+ Date notBefore = (Date) certValidity.get(
+ CertificateValidity.NOT_BEFORE);
+
+ if (notBefore.getTime() == 0 ||
+ notBefore.getTime() != notValidBefore) {
+ Date validFrom = new Date(notValidBefore);
+
+ notBefore = (notValidBefore == 0) ? currentTime : validFrom;
+ certValidity.set(CertificateValidity.NOT_BEFORE,
+ notBefore);
+ validityChanged = true;
+ }
+ }
+ if (notValidAfter > 0) {
+ Date validTo = new Date(notValidAfter);
+ Date notAfter = (Date)
+ certValidity.get(CertificateValidity.NOT_AFTER);
+
+ if (notAfter.getTime() == 0 ||
+ notAfter.getTime() != notValidAfter) {
+ notAfter = currentTime;
+ notAfter = (notValidAfter == 0) ? currentTime : validTo;
+ certValidity.set(CertificateValidity.NOT_AFTER,
+ notAfter);
+ validityChanged = true;
+ }
+ }
+ if (validityChanged) {
+ // this set() trigger this rebuild of internal
+ // raw der encoding cache of X509CertInfo.
+ // Otherwise, the above change wont have effect.
+ certInfo[i].set(X509CertInfo.VALIDITY, certValidity);
+ }
+
+ if (certInfo[i].get(X509CertInfo.VERSION) == null) {
+ certInfo[i].set(X509CertInfo.VERSION,
+ new CertificateVersion(
+ CertificateVersion.V3));
+ }
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo[i].get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_PARSING_EXTENS", e.toString()));
+ }
+
+ // 99/08/31 #361906 - handling additional extensions
+ String addExts = req.getParameter("addExts");
+
+ if (addExts != null && !addExts.trim().equals("")) {
+ Vector extsToBeAdded = new Vector();
+
+ byte[] b = (byte[]) (com.netscape.osutil.OSUtil.AtoB(addExts));
+
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ try {
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ Extension de = new Extension(b_der.data.getDerValue());
+
+ extsToBeAdded.addElement(de);
+ }
+ } catch (IOException e) {
+ // it could be a single extension
+ Extension de = new Extension(new DerValue(b));
+
+ extsToBeAdded.addElement(de);
+ }
+ if (extsToBeAdded.size() > 0) {
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ certInfo[i].set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ for (int j = 0; j < extsToBeAdded.size(); j++) {
+ Extension theExt = (Extension) extsToBeAdded.elementAt(j);
+
+ extensions.set(theExt.getExtensionId().toString(), theExt);
+ }
+ }
+ }
+
+ if (extensions != null) {
+ try {
+ NSCertTypeExtension nsExtensions =
+ (NSCertTypeExtension)
+ extensions.get(
+ NSCertTypeExtension.NAME);
+
+ if (nsExtensions != null) {
+ updateNSExtension(req, nsExtensions);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_PROCESS_NETSCAPE_EXTENSION", e.toString()));
+ }
+
+ String pathLength = req.getParameter("pathLenConstraint");
+
+ if (pathLength != null) {
+ try {
+ int pathLen = Integer.parseInt(pathLength);
+ BasicConstraintsExtension bcExt =
+ (BasicConstraintsExtension)
+ extensions.get(
+ BasicConstraintsExtension.NAME);
+
+ if (bcExt != null) {
+ Integer bcPathLen = (Integer) bcExt.get(BasicConstraintsExtension.PATH_LEN);
+ Boolean isCA = (Boolean) bcExt.get(BasicConstraintsExtension.IS_CA);
+
+ if (bcPathLen != null &&
+ bcPathLen.intValue() != pathLen &&
+ isCA != null) {
+ BasicConstraintsExtension bcExt0 =
+ new BasicConstraintsExtension(isCA.booleanValue(), pathLen);
+
+ extensions.delete(BasicConstraintsExtension.NAME);
+ extensions.set(BasicConstraintsExtension.NAME, (Extension) bcExt0);
+ alterationCounter++;
+ }
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_PROCESS_CONSTRAINTS_EXTENSION", e.toString()));
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_PROCESS_CONSTRAINTS_EXTENSION", e.toString()));
+ }
+ }
+
+ // handle Presence Server Extension
+ String PSE_Enable = req.getParameter("PSE_Enable");
+
+ if (PSE_Enable != null) {
+ boolean Critical = (req.getParameter("PSE_Critical") != null);
+ int Version = 0;
+
+ try {
+ Version = Integer.parseInt(req.getParameter("PSE_Version"));
+ } catch (Exception e1) {
+ }
+ String StreetAddress = req.getParameter("PSE_StreetAddress");
+
+ if (StreetAddress == null) {
+ StreetAddress = "";
+ }
+ String TelephoneNumber = req.getParameter("PSE_TelephoneNumber");
+
+ if (TelephoneNumber == null) {
+ TelephoneNumber = "";
+ }
+ String RFC822Name = req.getParameter("PSE_RFC822Name");
+
+ if (RFC822Name == null) {
+ RFC822Name = "";
+ }
+ String IMID = req.getParameter("PSE_IMID");
+
+ if (IMID == null) {
+ IMID = "";
+ }
+ String HostName = req.getParameter("PSE_HostName");
+
+ if (HostName == null) {
+ HostName = "";
+ }
+ int PortNumber = 0;
+
+ try {
+ PortNumber = Integer.parseInt(req.getParameter("PSE_PortNumber"));
+ } catch (Exception e1) {
+ }
+ int MaxUsers = 0;
+
+ try {
+ MaxUsers = Integer.parseInt(req.getParameter("PSE_MaxUsers"));
+ } catch (Exception e1) {
+ }
+ int ServiceLevel = 0;
+
+ try {
+ ServiceLevel = Integer.parseInt(req.getParameter("PSE_ServiceLevel"));
+ } catch (Exception e1) {
+ }
+ // create extension
+ PresenceServerExtension pseExt = new PresenceServerExtension(Critical, Version, StreetAddress, TelephoneNumber, RFC822Name, IMID, HostName, PortNumber, MaxUsers, ServiceLevel);
+
+ extensions.set(pseExt.getExtensionId().toString(), pseExt);
+ }
+
+ if (mExtraAgentParams) {
+ Enumeration extraparams = req.getParameterNames();
+ int l = IRequest.AGENT_PARAMS.length() + 1;
+ int ap_counter = 0;
+ Hashtable agentparamsargblock = new Hashtable();
+
+ if (extraparams != null) {
+ while (extraparams.hasMoreElements()) {
+ String s = (String) extraparams.nextElement();
+
+ if (s.startsWith(IRequest.AGENT_PARAMS)) {
+ String param_value = req.getParameter(s);
+
+ if (param_value != null) {
+ String new_name = s.substring(l);
+
+ agentparamsargblock.put(new_name, param_value);
+ ap_counter += 1;
+ }
+ }
+ }
+ }
+ if (ap_counter > 0) {
+ r.setExtData(IRequest.AGENT_PARAMS, agentparamsargblock);
+ alterationCounter++;
+ }
+ }
+
+ // this set() trigger this rebuild of internal
+ // raw der encoding cache of X509CertInfo.
+ // Otherwise, the above change wont have effect.
+ certInfo[i].set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ alterationCounter += updateExtensionsInRequest(req, r);
+ }
+ if (alterationCounter > 0) {
+ mQueue.updateRequest(r);
+ }
+ }
+
+ mQueue.approveRequest(r);
+
+ if (r.getRequestStatus().equals(RequestStatus.PENDING)) {
+ cmsReq.setResult(r);
+ cmsReq.setStatus(CMSRequest.PENDING);
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "pending",
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "pending",
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "pending"}
+ );
+ }
+ }
+ } else if (r.getRequestStatus().equals(
+ RequestStatus.APPROVED) ||
+ r.getRequestStatus().equals(
+ RequestStatus.SVC_PENDING)) {
+ cmsReq.setResult(r);
+ cmsReq.setStatus(CMSRequest.SVC_PENDING);
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ r.getRequestStatus(),
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ r.getRequestStatus(),
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ r.getRequestStatus()}
+ );
+ }
+ }
+ } else if (r.getRequestStatus().equals(
+ RequestStatus.COMPLETE)) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // XXX make the repeat record.
+ // Get the certificate(s) from the request
+ X509CertImpl issuedCerts[] =
+ r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ // return potentially more than one certificates.
+ if (issuedCerts != null) {
+ long endTime = CMS.getCurrentDate().getTime();
+ StringBuffer sbuf = new StringBuffer();
+
+ //header.addBigIntegerValue("serialNumber",
+ //issuedCerts[0].getSerialNumber(),16);
+ for (int i = 0; i < issuedCerts.length; i++) {
+ if (i != 0)
+ sbuf.append(", ");
+ sbuf.append("0x" +
+ issuedCerts[i].getSerialNumber().toString(16));
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ issuedCerts[i].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ issuedCerts[i].getSerialNumber().toString(16) + " time: " + (endTime - startTime)}
+ );
+
+ // store a message in the signed audit log file
+ // (one for each manual "agent"
+ // cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditInfoName,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+ header.addStringValue(
+ "serialNumber", sbuf.toString());
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "completed"}
+ );
+ }
+
+ // store a message in the signed audit log file
+ // (manual "agent" cert request processed
+ // - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ }
+
+ // grant trusted manager or agent privileges
+ Object grantError = null;
+
+ try {
+ int res = grant_privileges(
+ cmsReq, r, issuedCerts, header);
+
+ if (res != 0) {
+ header.addStringValue(GRANT_ERROR, "SUCCESS");
+ grantError = "SUCCESS";
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(GRANT_ERROR, e.toString());
+ grantError = e;
+ }
+
+ // if this is a RA, show the certificate right away
+ // since ther is no cert database.
+ /*
+ if (mAuthority instanceof RegistrationAuthority) {
+ Object[] results =
+ new Object[] { issuedCerts, grantError };
+ cmsReq.setResult(results);
+ renderTemplate(cmsReq,
+ mReqCompletedTemplate, REQ_COMPLETED_FILLER);
+
+ return;
+ }
+ */
+
+ cmsReq.setResult(r);
+
+ String scheme = req.getScheme();
+
+ if (scheme.equals("http") &&
+ connectionIsSSL(req)) scheme = "https";
+
+ /*
+ header.addStringValue(
+ "authorityid", mAuthority.getId());
+ header.addStringValue("serviceURL", scheme +"://"+
+ req.getServerName() + ":"+
+ req.getServerPort() +
+ req.getRequestURI());
+ */
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+
+ Integer[] ldapPublishStatus =
+ r.getExtDataInIntegerArray("ldapPublishStatus");
+ int certsUpdated = 0;
+
+ if (ldapPublishStatus != null) {
+ for (int i = 0;
+ i < ldapPublishStatus.length; i++) {
+ if (ldapPublishStatus[i] ==
+ IRequest.RES_SUCCESS) {
+ certsUpdated++;
+ }
+ }
+ }
+ header.addIntegerValue("certsUpdated", certsUpdated);
+
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+ }
+
+ } else if (toDo.equals("reject")) {
+ mQueue.rejectRequest(r);
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "rejected",
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "rejected",
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "rejected"}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[1]);
+
+ audit(auditMessage);
+
+ } else if (toDo.equals("cancel")) {
+ mQueue.cancelRequest(r);
+
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "canceled",
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "canceled",
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "canceled"}
+ );
+ }
+
+ }
+
+ // store a message in the signed audit log file
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[1]);
+
+ audit(auditMessage);
+
+ } else if (toDo.equals("clone")) {
+ IRequest clonedRequest = mQueue.cloneAndMarkPending(r);
+
+ header.addStringValue("clonedRequestId",
+ clonedRequest.getRequestId().toString());
+
+ if (certInfo != null) {
+ for (int i = 0; i < certInfo.length; i++) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "cloned to reqID: " +
+ clonedRequest.getRequestId().toString(),
+ certInfo[i].get(X509CertInfo.SUBJECT),
+ ""}
+ );
+ }
+ } else {
+ if (subject != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "cloned to reqID: " +
+ clonedRequest.getRequestId().toString(),
+ subject,
+ ""}
+ );
+ } else {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.NODNFORMAT,
+ new Object[] {
+ r.getRequestType(),
+ r.getRequestId(),
+ initiative,
+ authMgr,
+ "cloned to reqID: " +
+ clonedRequest.getRequestId().toString()}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ }
+ }
+
+ // add authority names to know what privileges can be requested.
+ if (CMS.getSubsystem("kra") != null)
+ header.addStringValue("localkra", "yes");
+ if (CMS.getSubsystem("ca") != null)
+ header.addStringValue("localca", "yes");
+ if (CMS.getSubsystem("ra") != null)
+ header.addStringValue("localra", "yes");
+
+ header.addIntegerValue("seqNum", seqNum);
+ mParser.fillRequestIntoArg(locale, r, argSet, header);
+ String rid = r.getExtDataInString(IRequest.REMOTE_REQID);
+
+ if (rid != null)
+ header.addStringValue("remoteReqID", rid);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+
+ // store a message in the signed audit log file
+ if (toDo != null) {
+ if (toDo.equals(SIGNED_AUDIT_CLONING)) {
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ // (manual "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_CANCELLATION)) {
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[2]);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_REJECTION)) {
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[2]);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+
+ // store a message in the signed audit log file
+ if (toDo != null) {
+ if (toDo.equals(SIGNED_AUDIT_CLONING)) {
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ // (manual "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_CANCELLATION)) {
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[3]);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_REJECTION)) {
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[3]);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_ISSUED_CERT_ERROR"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+
+ // store a message in the signed audit log file
+ if (toDo != null) {
+ if (toDo.equals(SIGNED_AUDIT_CLONING)) {
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ // (manual "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_CANCELLATION)) {
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[4]);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_REJECTION)) {
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[4]);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_ISSUED_CERT_ERROR"));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_IO_ERROR_REMOTE_REQUEST", e.toString()));
+
+ // store a message in the signed audit log file
+ if (toDo != null) {
+ if (toDo.equals(SIGNED_AUDIT_CLONING)) {
+ // ("agent" cert request for "cloning")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ // (manual "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_CANCELLATION)) {
+ // (manual "agent" cert request processed - "cancelled")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_CANCELLATION_REASON[5]);
+
+ audit(auditMessage);
+ } else if (toDo.equals(SIGNED_AUDIT_REJECTION)) {
+ // (manual "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditInfoName,
+ SIGNED_AUDIT_MANUAL_REJECTION_REASON[5]);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ return;
+ }
+
+ private void updateNSExtension(HttpServletRequest req,
+ NSCertTypeExtension ext) throws IOException {
+ try {
+
+ if (req.getParameter("certTypeSSLServer") == null) {
+ ext.set(NSCertTypeExtension.SSL_SERVER, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.SSL_SERVER, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeSSLClient") == null) {
+ ext.set(NSCertTypeExtension.SSL_CLIENT, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.SSL_CLIENT, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeEmail") == null) {
+ ext.set(NSCertTypeExtension.EMAIL, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.EMAIL, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeObjSigning") == null) {
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeEmailCA") == null) {
+ ext.set(NSCertTypeExtension.EMAIL_CA, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.EMAIL_CA, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeSSLCA") == null) {
+ ext.set(NSCertTypeExtension.SSL_CA, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.SSL_CA, Boolean.valueOf(true));
+ }
+
+ if (req.getParameter("certTypeObjSigningCA") == null) {
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING_CA, Boolean.valueOf(false));
+ } else {
+ ext.set(NSCertTypeExtension.OBJECT_SIGNING_CA, Boolean.valueOf(true));
+ }
+ } catch (CertificateException e) {
+ }
+ }
+
+ /**
+ * This method sets extensions parameter into the request so
+ * that the NSCertTypeExtension policy creates new
+ * NSCertTypExtension with this setting. Note that this
+ * setting will not be used if the NSCertType Extension
+ * already exist in CertificateExtension. In that case,
+ * updateExtensions() will be called to set the extension
+ * parameter into the extension directly.
+ */
+ private int updateExtensionsInRequest(HttpServletRequest req, IRequest r) {
+ int nChanges = 0;
+
+ if (req.getParameter("certTypeSSLServer") != null) {
+ r.setExtData(NSCertTypeExtension.SSL_SERVER, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.SSL_SERVER);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeSSLClient") != null) {
+ r.setExtData(NSCertTypeExtension.SSL_CLIENT, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.SSL_CLIENT);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeEmail") != null) {
+ r.setExtData(NSCertTypeExtension.EMAIL, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.EMAIL);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeObjSigning") != null) {
+ r.setExtData(NSCertTypeExtension.OBJECT_SIGNING, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.OBJECT_SIGNING);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeEmailCA") != null) {
+ r.setExtData(NSCertTypeExtension.EMAIL_CA, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.EMAIL_CA);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeSSLCA") != null) {
+ r.setExtData(NSCertTypeExtension.SSL_CA, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.SSL_CA);
+ nChanges++;
+ }
+
+ if (req.getParameter("certTypeObjSigningCA") != null) {
+ r.setExtData(NSCertTypeExtension.OBJECT_SIGNING_CA, "true");
+ nChanges++;
+ } else {
+ r.deleteExtData(NSCertTypeExtension.OBJECT_SIGNING_CA);
+ nChanges++;
+ }
+
+ return nChanges;
+ }
+
+ protected static final String GRANT_ERROR = "grantError";
+
+ public static final String
+ GRANT_TRUSTEDMGR_PRIVILEGE = "grantTrustedManagerPrivilege";
+ public static final String
+ GRANT_CMAGENT_PRIVILEGE = "grantCMAgentPrivilege";
+ public static final String
+ GRANT_RMAGENT_PRIVILEGE = "grantRMAgentPrivilege";
+ public static final String
+ GRANT_DRMAGENT_PRIVILEGE = "grantDRMAgentPrivilege";
+ public static final String GRANT_UID = "grantUID";
+ public static final String GRANT_PRIVILEGE = "grantPrivilege";
+
+ protected int grant_privileges(
+ CMSRequest cmsReq, IRequest req, Certificate[] certs, IArgBlock header)
+ throws EBaseException {
+ // get privileges to grant
+ IArgBlock httpParams = cmsReq.getHttpParams();
+
+ boolean grantTrustedMgr =
+ httpParams.getValueAsBoolean(GRANT_TRUSTEDMGR_PRIVILEGE, false);
+ boolean grantRMAgent =
+ httpParams.getValueAsBoolean(GRANT_RMAGENT_PRIVILEGE, false);
+ boolean grantCMAgent =
+ httpParams.getValueAsBoolean(GRANT_CMAGENT_PRIVILEGE, false);
+ boolean grantDRMAgent =
+ httpParams.getValueAsBoolean(GRANT_DRMAGENT_PRIVILEGE, false);
+
+ if (!grantTrustedMgr &&
+ !grantCMAgent && !grantRMAgent && !grantDRMAgent) {
+ return 0;
+ } else {
+ IAuthToken authToken = getAuthToken(req);
+ AuthzToken authzToken = null;
+ String resourceName = "certServer." + mAuthority.getId() + ".group";
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ resourceName, "add");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ String[] obj = new String[1];
+
+ if (grantTrustedMgr)
+ obj[0] = TRUSTED_RA_GROUP;
+ else if (grantRMAgent)
+ obj[0] = RA_AGENT_GROUP;
+ else if (grantCMAgent)
+ obj[0] = CA_AGENT_GROUP;
+ else if (grantDRMAgent)
+ obj[0] = KRA_AGENT_GROUP;
+ else
+ obj[0] = "unknown group";
+
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_UNAUTHORIZED_CREATE_GROUP", obj[0]));
+ }
+ }
+
+ String uid = (String) httpParams.getValueAsString(GRANT_UID, null);
+
+ if (uid == null || uid.length() == 0) {
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_MISSING_GRANT_UID"));
+ }
+ header.addStringValue(GRANT_UID, uid);
+
+ String groupname = null, groupname1 = null;
+ String userType = "";
+
+ if (grantTrustedMgr) {
+ groupname = TRUSTED_RA_GROUP;
+ userType = Constants.PR_SUBSYSTEM_TYPE;
+ } else {
+ if (grantCMAgent)
+ groupname = CA_AGENT_GROUP;
+ else if (grantRMAgent)
+ groupname = RA_AGENT_GROUP;
+
+ if (grantDRMAgent) {
+ if (groupname != null)
+ groupname1 = KRA_AGENT_GROUP;
+ else
+ groupname = KRA_AGENT_GROUP;
+ }
+ userType = Constants.PR_AGENT_TYPE;
+ }
+
+ String privilege =
+ (groupname1 == null) ? groupname : groupname + " and " + groupname1;
+
+ header.addStringValue(GRANT_PRIVILEGE, privilege);
+
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ IUser user = ug.createUser(uid);
+
+ user.setFullName(uid);
+ user.setEmail("");
+ user.setPhone("");
+ user.setPassword("");
+ user.setUserType(userType);
+ user.setState("1");
+ IGroup group = ug.findGroup(groupname), group1 = null;
+
+ if (group == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_FIND_GROUP_1", groupname));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_FIND_GROUP_ERROR", groupname));
+ }
+ if (groupname1 != null) {
+ group1 = ug.findGroup(groupname1);
+ if (group1 == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_FIND_GROUP_1", groupname));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_FIND_GROUP_ERROR", groupname1));
+ }
+ }
+ try {
+ ug.addUser(user);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_ADDING_USER_1", uid));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_USER_ERROR", uid));
+ }
+ try {
+ if (certs[0] instanceof X509CertImpl) {
+ X509CertImpl tmp[] = (X509CertImpl[]) certs;
+
+ user.setX509Certificates(tmp);
+ }
+
+ ug.addUserCert(user);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_ADDING_CERT_1", uid));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_CERT_ERROR", uid));
+ }
+ try {
+ group.addMemberName(uid);
+ ug.modifyGroup(group);
+ // for audit log
+ SessionContext sContext = SessionContext.getContext();
+ String adminId = (String) sContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT,
+ new Object[] {adminId, uid, groupname}
+ );
+
+ if (group1 != null) {
+ group1.addMemberName(uid);
+ ug.modifyGroup(group1);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT,
+ new Object[] {adminId, uid, groupname1}
+ );
+
+ }
+ } catch (Exception e) {
+ String msg =
+ "Could not add user " + uid + " to group " + groupname;
+
+ if (group1 != null)
+ msg += " or group " + groupname1;
+ log(ILogger.LL_FAILURE, msg);
+ if (group1 == null)
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_MEMBER", uid, groupname));
+ else
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_MEMBER_1", uid, groupname, groupname1));
+ }
+ return 1;
+ }
+
+ /**
+ * Signed Audit Log Info Name
+ *
+ * This method is called to obtain the "InfoName" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param type signed audit log request processing type
+ * @return id string containing the signed audit log message InfoName
+ */
+ private String auditInfoName(String type) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters (this is done below)
+
+ String infoName = ILogger.UNIDENTIFIED;
+
+ if (mSignedAuditLogger == null) {
+ return infoName;
+ }
+
+ if (type != null) {
+ type = type.trim();
+
+ if (type.equals(SIGNED_AUDIT_ACCEPTANCE)) {
+ infoName = ILogger.SIGNED_AUDIT_ACCEPTANCE;
+ } else if (type.equals(SIGNED_AUDIT_CANCELLATION)) {
+ infoName = ILogger.SIGNED_AUDIT_CANCELLATION;
+ } else if (type.equals(SIGNED_AUDIT_REJECTION)) {
+ infoName = ILogger.SIGNED_AUDIT_REJECTION;
+ }
+ }
+
+ return infoName;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param x509cert an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(X509CertImpl x509cert) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ sb.append(base64Data.substring(i, i));
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+}
+
+
+class RAReqCompletedFiller extends ImportCertsTemplateFiller {
+ private static final String RA_AGENT_GROUP = "Registration Manager Agents";
+ private static final String KRA_AGENT_GROUP = "Data Recovery Manager Agents";
+ public RAReqCompletedFiller() {
+ super();
+ }
+
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+
+ Object[] results = (Object[]) cmsReq.getResult();
+ Object grantError = results[1];
+ //X509CertImpl[] issuedCerts = (X509CertImpl[])results[0];
+ Certificate[] issuedCerts = (Certificate[]) results[0];
+
+ cmsReq.setResult(issuedCerts);
+ CMSTemplateParams params =
+ super.getTemplateParams(cmsReq, authority, locale, e);
+
+ if (grantError != null) {
+ IArgBlock header = params.getHeader();
+
+ if (grantError instanceof String) {
+ header.addStringValue(
+ ProcessCertReq.GRANT_ERROR, (String) grantError);
+ } else {
+ EBaseException ex = (EBaseException) grantError;
+
+ header.addStringValue(
+ ProcessCertReq.GRANT_ERROR, ex.toString(locale));
+ }
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ String uid = httpParams.getValueAsString(
+ ProcessCertReq.GRANT_UID, null);
+
+ header.addStringValue(ProcessCertReq.GRANT_UID, uid);
+ boolean grantRMAgent = httpParams.getValueAsBoolean(
+ ProcessCertReq.GRANT_RMAGENT_PRIVILEGE, false);
+ boolean grantDRMAgent = httpParams.getValueAsBoolean(
+ ProcessCertReq.GRANT_DRMAGENT_PRIVILEGE, false);
+ String privilege = null;
+
+ if (grantRMAgent) {
+ privilege = RA_AGENT_GROUP;
+ }
+ if (grantDRMAgent) {
+ if (privilege != null)
+ privilege += " and " + KRA_AGENT_GROUP;
+ else
+ privilege = KRA_AGENT_GROUP;
+ }
+ header.addStringValue(ProcessCertReq.GRANT_PRIVILEGE, privilege);
+ }
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java b/pki/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java
new file mode 100644
index 000000000..899f4c309
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java
@@ -0,0 +1,327 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Display Generic Request detail to the user.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProcessReq extends CMSServlet {
+
+ private final static String INFO = "processReq";
+ private final static String SEQNUM = "seqNum";
+ private final static String DO_ASSIGN = "doAssign";
+ private final static String TPL_FILE = "processReq.template";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String PROP_PARSER = "parser";
+
+ private IRequestQueue mQueue = null;
+ private String mFormPath = null;
+ private IReqParser mParser = null;
+ private String[] mSigningAlgorithms = null;
+
+ private static String[] DEF_SIGNING_ALGORITHMS = new String[]
+ {"SHA1withRSA", "SHA256withRSA", "SHA512withRSA", "SHA1withDSA", "MD5withRSA", "MD2withRSA"};
+
+ /**
+ * Process request.
+ */
+ public ProcessReq() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "processReq.template" to process the response.
+ * The initialization parameter 'parser' is read from the
+ * servlet configration, and is used to set the type of request.
+ * The value of this parameter can be:
+ * <UL><LI><B>CertReqParser.NODETAIL_PARSER</B> - Show certificate Summary
+ * <LI><B>CertReqParser.DETAIL_PARSER</B> - Show certificate detail
+ * <LI><B>KeyReqParser.PARSER</B> - Show key archival detail
+ * </UL>
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mQueue = mAuthority.getRequestQueue();
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ String tmp = sc.getInitParameter(PROP_PARSER);
+
+ if (tmp != null) {
+ if (tmp.trim().equals("CertReqParser.NODETAIL_PARSER"))
+ mParser = CertReqParser.NODETAIL_PARSER;
+ else if (tmp.trim().equals("CertReqParser.DETAIL_PARSER"))
+ mParser = CertReqParser.DETAIL_PARSER;
+ else if (tmp.trim().equals("KeyReqParser.PARSER"))
+ mParser = KeyReqParser.PARSER;
+ }
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mTemplates.remove(CMSRequest.ERROR);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param seqNum
+ * <li>http.param doAssign reassign request. Value can be reassignToMe
+ * reassignToNobody
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ int seqNum = -1;
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String doAssign = null;
+ EBaseException error = null;
+
+ CMSTemplate form = null, errorForm = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ "Error getting template " + mFormPath + " Error " + e);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ if (req.getParameter(SEQNUM) != null) {
+ seqNum = Integer.parseInt(req.getParameter(SEQNUM));
+ }
+ doAssign = req.getParameter(DO_ASSIGN);
+
+ if (seqNum > -1) {
+ // start authorization
+ AuthzToken authzToken = null;
+
+ try {
+ if (doAssign == null) {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } else if (doAssign.equals("toMe") ||
+ doAssign.equals("reassignToMe")) {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "assign");
+ } else if (doAssign.equals("reassignToNobody")) {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "unassign");
+ }
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ process(argSet, header, seqNum, req, resp,
+ doAssign, locale[0]);
+ } else {
+ log(ILogger.LL_FAILURE, "Invalid sequence number " + seqNum);
+ error = new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_REQUEST_ID",
+ String.valueOf(seqNum)));
+ }
+ } catch (EBaseException e) {
+ error = e;
+ } catch (NumberFormatException e) {
+ error = new EBaseException(CMS.getUserMessage(locale[0], "CMS_BASE_INVALID_NUMBER_FORMAT"));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ String output = form.getOutput(argSet);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setError(error);
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ "Error getting servlet output stream for rendering template. " +
+ "Error " + e);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ return;
+ }
+
+ /**
+ * Sends request information to the calller.
+ * returns whether there was an error or not.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int seqNum, HttpServletRequest req,
+ HttpServletResponse resp,
+ String doAssign, Locale locale)
+ throws EBaseException {
+
+ header.addIntegerValue("seqNum", seqNum);
+
+ IRequest r =
+ mQueue.findRequest(new RequestId(Integer.toString(seqNum)));
+
+ if (r != null) {
+ if (doAssign != null) {
+ if ((doAssign.equals("toMe"))
+ || (doAssign.equals("reassignToMe"))) {
+ SessionContext ctx = SessionContext.getContext();
+ String id = (String) ctx.get(SessionContext.USER_ID);
+
+ r.setRequestOwner(id);
+ mQueue.updateRequest(r);
+ } else if (doAssign.equals("reassignToNobody")) {
+ r.setRequestOwner(null);
+ mQueue.updateRequest(r);
+ }
+ }
+
+ // add authority names to know what privileges can be requested.
+ if (CMS.getSubsystem("kra") != null)
+ header.addStringValue("localkra", "yes");
+ if (CMS.getSubsystem("ca") != null)
+ header.addStringValue("localca", "yes");
+ if (CMS.getSubsystem("ra") != null)
+ header.addStringValue("localra", "yes");
+
+ // DONT NEED TO DO THIS FOR DRM
+ if (mAuthority instanceof ICertAuthority) {
+ // Check/set signing algorithms dynamically.
+ // In RA mSigningAlgorithms could be null at startup if CA is not
+ // up and set later when CA comes back up.
+ // Once it's set assumed that it won't change.
+ String[] allAlgorithms = mSigningAlgorithms;
+
+ if (allAlgorithms == null) {
+ allAlgorithms = mSigningAlgorithms =
+ ((ICertAuthority) mAuthority).getCASigningAlgorithms();
+ if (allAlgorithms == null) {
+ CMS.debug(
+ "ProcessReq: signing algorithms set to All algorithms");
+ allAlgorithms = AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ } else
+ CMS.debug(
+ "ProcessReq: First signing algorithms is " + allAlgorithms[0]);
+ }
+ String validAlgorithms = null;
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < allAlgorithms.length; i++) {
+ if (i > 0) {
+ sb.append("+");
+ sb.append(allAlgorithms[i]);
+ } else {
+ sb.append(allAlgorithms[i]);
+ }
+ }
+ validAlgorithms = sb.toString();
+ if (validAlgorithms != null)
+ header.addStringValue("validAlgorithms", validAlgorithms);
+ if (mAuthority instanceof ICertificateAuthority) {
+ String signingAlgorithm = ((ICertificateAuthority) mAuthority).getDefaultAlgorithm();
+
+ if (signingAlgorithm != null)
+ header.addStringValue("caSigningAlgorithm", signingAlgorithm);
+ header.addLongValue("defaultValidityLength",
+ ((ICertificateAuthority) mAuthority).getDefaultValidity() / 1000);
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ header.addLongValue("defaultValidityLength",
+ ((IRegistrationAuthority) mAuthority).getDefaultValidity() / 1000);
+ }
+ X509CertImpl caCert = ((ICertAuthority) mAuthority).getCACert();
+
+ if (caCert != null) {
+ int caPathLen = caCert.getBasicConstraints();
+
+ header.addIntegerValue("caPathLen", caPathLen);
+ }
+ }
+
+ mParser.fillRequestIntoArg(locale, r, argSet, header);
+ } else {
+ log(ILogger.LL_FAILURE, "Invalid sequence number " + seqNum);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_REQUEST_ID",
+ String.valueOf(seqNum)));
+ }
+
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/QueryReq.java b/pki/base/common/src/com/netscape/cms/servlet/request/QueryReq.java
new file mode 100644
index 000000000..3654b1162
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/QueryReq.java
@@ -0,0 +1,547 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Show paged list of requests matching search criteria
+ *
+ * @version $Revision$, $Date$
+ */
+public class QueryReq extends CMSServlet {
+ // constants
+ private final static String INFO = "QueryReq";
+ private final static String IN_SHOW_ALL = "showAll";
+ private final static String IN_SHOW_WAITING = "showWaiting";
+ private final static String IN_SHOW_IN_SERVICE = "showInService";
+ private final static String IN_SHOW_PENDING= "showPending";
+ private final static String IN_SHOW_CANCELLED = "showCancelled";
+ private final static String IN_SHOW_REJECTED = "showRejected";
+ private final static String IN_SHOW_COMPLETED = "showCompleted";
+ private final static String IN_MAXCOUNT = "maxCount";
+ private final static String IN_TOTALCOUNT = "totalRecordCount";
+ private final static String ON = "on";
+ private final static String PROP_PARSER = "parser";
+
+ private final static String TPL_FILE = "queryReq.template";
+
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_OP = "op";
+ private final static String OUT_MAXCOUNT = IN_MAXCOUNT;
+ private final static String OUT_TOTALCOUNT = IN_TOTALCOUNT;
+ private final static String OUT_CURRENTCOUNT = "currentRecordCount";
+ private final static String OUT_SENTINEL_DOWN = "querySentinelDown";
+ private final static String OUT_SHOW_COMPLETED = IN_SHOW_COMPLETED;
+ private final static String OUT_SEQNUM = "seqNum";
+ private final static String OUT_STATUS = "status";
+ private final static String OUT_CREATE_ON = "createdOn";
+ private final static String OUT_UPDATE_ON = "updatedOn";
+ private final static String OUT_UPDATE_BY = "updatedBy";
+ private final static String OUT_REQUESTING_USER = "requestingUser";
+ //keeps track of where to begin if page down
+ private final static String OUT_FIRST_ENTRY_ON_PAGE = "firstEntryOnPage";
+ //keeps track of where to begin if page up
+ private final static String OUT_LAST_ENTRY_ON_PAGE = "lastEntryOnPage";
+ private final static String OUT_SUBJECT = "subject";
+ private final static String OUT_REQUEST_TYPE = "requestType";
+ private final static String OUT_COMMENTS = "requestorComments";
+ private final static String OUT_SERIALNO = "serialNumber";
+ private final static String OUT_OWNER_NAME = "ownerName";
+ private final static String OUT_PUBLIC_KEY_INFO =
+ "subjectPublicKeyInfo";
+ private final static String OUT_ERROR = "error";
+ private final static String OUT_AUTHORITY_ID = "authorityid";
+
+ // variables
+ private IReqParser mParser = null;
+ private IRequestQueue mQueue = null;
+ private String mFormPath = null;
+ private int mMaxReturns = 2000;
+
+ public CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Constructor
+ */
+ public QueryReq() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "queryReq.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mQueue = mAuthority.getRequestQueue();
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ try {
+ mMaxReturns = Integer.parseInt(sc.getInitParameter("maxResults"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ String tmp = sc.getInitParameter(PROP_PARSER);
+
+ if (tmp != null) {
+ if (tmp.trim().equals("CertReqParser.NODETAIL_PARSER"))
+ mParser = CertReqParser.NODETAIL_PARSER;
+ else if (tmp.trim().equals("CertReqParser.DETAIL_PARSER"))
+ mParser = CertReqParser.DETAIL_PARSER;
+ else if (tmp.trim().equals("KeyReqParser.PARSER"))
+ mParser = KeyReqParser.PARSER;
+ }
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mTemplates.remove(CMSRequest.ERROR);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ private String getRequestType(String p) {
+ String filter = "(requestType=*)";
+
+ if (p == null)
+ return filter;
+ if (p.equals(IRequest.ENROLLMENT_REQUEST)) {
+ filter = "(requestType=" + IRequest.ENROLLMENT_REQUEST + ")";
+ } else if (p.equals(IRequest.RENEWAL_REQUEST)) {
+ filter = "(requestType=" + IRequest.RENEWAL_REQUEST + ")";
+ } else if (p.equals(IRequest.REVOCATION_REQUEST)) {
+ filter = "(requestType=" + IRequest.REVOCATION_REQUEST + ")";
+ } else if (p.equals(IRequest.UNREVOCATION_REQUEST)) {
+ filter = "(requestType=" + IRequest.UNREVOCATION_REQUEST + ")";
+ } else if (p.equals(IRequest.KEYARCHIVAL_REQUEST)) {
+ filter = "(requestType=" + IRequest.KEYARCHIVAL_REQUEST + ")";
+ } else if (p.equals(IRequest.KEYRECOVERY_REQUEST)) {
+ filter = "(requestType=" + IRequest.KEYRECOVERY_REQUEST + ")";
+ } else if (p.equals(IRequest.GETCACHAIN_REQUEST)) {
+ filter = "(requestType=" + IRequest.GETCACHAIN_REQUEST + ")";
+ } else if (p.equals(IRequest.GETREVOCATIONINFO_REQUEST)) {
+ filter = "(requestType=" + IRequest.GETREVOCATIONINFO_REQUEST + ")";
+ } else if (p.equals(IRequest.GETCRL_REQUEST)) {
+ filter = "(requestType=" + IRequest.GETCRL_REQUEST + ")";
+ } else if (p.equals(IRequest.GETCERTS_REQUEST)) {
+ filter = "(requestType=" + IRequest.GETCERTS_REQUEST + ")";
+ } else if (p.equals(IRequest.NETKEY_KEYGEN_REQUEST)) {
+ filter = "(requestType=" + IRequest.NETKEY_KEYGEN_REQUEST + ")";
+ } else if (p.equals(IN_SHOW_ALL)) {
+ filter = "(requestType=*)";
+ }
+ return filter;
+ }
+
+ private String getRequestState(String p) {
+ String filter = "(requeststate=*)";
+
+ if (p == null)
+ return filter;
+ if (p.equals(IN_SHOW_WAITING)) {
+ filter = "(requeststate=pending)";
+ } else if (p.equals(IN_SHOW_IN_SERVICE)) {
+ filter = "(requeststate=svc_pending)";
+ } else if (p.equals(IN_SHOW_PENDING)) {
+ filter = "(requeststate=pending)";
+ } else if (p.equals(IN_SHOW_CANCELLED)) {
+ filter = "(requeststate=canceled)";
+ } else if (p.equals(IN_SHOW_REJECTED)) {
+ filter = "(requeststate=rejected)";
+ } else if (p.equals(IN_SHOW_COMPLETED)) {
+ filter = "(requeststate=complete)";
+ } else if (p.equals(IN_SHOW_ALL)) {
+ filter = "(requeststate=*)";
+ }
+ return filter;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param reqState request state
+ * (one of showAll, showWaiting, showInService,
+ * showCancelled, showRejected, showCompleted)
+ * <li>http.param reqType
+ * <li>http.param seqNumFromDown request ID to start at (decimal, or hex if
+ * when paging down
+ * seqNumFromDown starts with 0x)
+ * <li>http.param seqNumFromUp request ID to start at (decimal, or hex if
+ * when paging up
+ * seqNumFromUp starts with 0x)
+ * <li>http.param maxCount maximum number of records to show
+ * <li>http.param totalCount total number of records in set of pages
+ * <li>http.param direction "up", "down", "begin", or "end"
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ CMS.debug("in QueryReq servlet");
+
+ // Authentication / Authorization
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+
+
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ // if get a EBaseException we just throw it.
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ /**
+ * WARNING:
+ *
+ * PLEASE DO NOT TOUCH THE FILTER HERE. ALL FILTERS ARE INDEXED.
+ *
+ **/
+ String filter = null;
+ String reqState = req.getParameter("reqState");
+ String reqType = req.getParameter("reqType");
+
+ if (reqState == null || reqType == null) {
+ filter = "(requeststate=*)";
+ } else if (reqState.equals(IN_SHOW_ALL) &&
+ reqType.equals(IN_SHOW_ALL)) {
+ filter = "(requeststate=*)";
+ } else if (reqState.equals(IN_SHOW_ALL)) {
+ filter = getRequestType(reqType);
+ } else if (reqType.equals(IN_SHOW_ALL)) {
+ filter = getRequestState(reqState);
+ } else {
+ filter = "(&" + getRequestState(reqState) +
+ getRequestType(reqType) + ")";
+ }
+
+ String direction = "begin";
+ if (req.getParameter("direction") != null) {
+ direction = req.getParameter("direction").trim();
+ }
+
+
+ int top=0, bottom=0;
+
+ try {
+ String top_s = req.getParameter(OUT_FIRST_ENTRY_ON_PAGE);
+ if (top_s == null) top_s = "0";
+
+ String bottom_s = req.getParameter(OUT_LAST_ENTRY_ON_PAGE);
+ if (bottom_s == null) bottom_s = "0";
+
+ top = Integer.parseInt(top_s);
+ bottom = Integer.parseInt(bottom_s);
+
+ } catch (NumberFormatException e) {
+
+ }
+
+ // avoid NumberFormatException to the user interface
+ int maxCount = 10;
+ try {
+ maxCount = Integer.parseInt(req.getParameter(IN_MAXCOUNT));
+ } catch (Exception e) {
+ }
+ if (maxCount > mMaxReturns) {
+ CMS.debug("Resetting page size from " + maxCount + " to " + mMaxReturns);
+ maxCount = mMaxReturns;
+ }
+
+ HttpServletResponse resp = cmsReq.getHttpResp();
+ CMSTemplateParams argset = doSearch(locale[0],filter, maxCount, direction, top, bottom );
+
+
+ argset.getFixed().addStringValue("reqType",reqType);
+ argset.getFixed().addStringValue("reqState", reqState);
+ argset.getFixed().addIntegerValue("maxCount",maxCount);
+
+
+ try {
+ form.getOutput(argset);
+ resp.setContentType("text/html");
+ form.renderOutput(resp.getOutputStream(), argset);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private static String makeRequestStatusEq(RequestStatus s) {
+ return "(" + "requestState" + "=" + s + ")";
+ }
+
+ private static String makeRequestIdCmp(String op, int bound) {
+ return "(requestId" + op + bound + ")";
+ }
+
+ /**
+ * Perform search based on direction button pressed
+ * @param filter ldap filter indicating which VLV to search through. This can be
+ * 'all requests', 'pending', etc
+ * @param count the number of requests to show per page
+ * @param direction either 'begin', 'end', 'previous' or 'next' (defaults to end)
+ * @param top the number of the request shown on at the top of the current page
+ * @param bottom the number of the request shown on at the bottom of the current page
+ * @return
+ */
+
+ private CMSTemplateParams doSearch(Locale l, String filter,
+ int count, String direction, int top, int bottom)
+ {
+ CMSTemplateParams ctp = null;
+ if (direction.equals("previous")) {
+ ctp = doSearch(l, filter, -count, top-1);
+ } else if (direction.equals("next")) {
+ ctp = doSearch(l,filter, count, bottom+1);
+ } else if (direction.equals("begin")) {
+ ctp = doSearch(l,filter, count, 0);
+ } else { // if 'direction is 'end', default here
+ ctp = doSearch(l,filter, -count, -1);
+ }
+ return ctp;
+ }
+
+
+
+ /**
+ *
+ * @param locale
+ * @param filter the types of requests to return - this must match the VLV index
+ * @param count maximum number of records to return
+ * @param marker indication of the request ID where the page is anchored
+ * @return
+ */
+
+ private CMSTemplateParams doSearch(
+ Locale locale,
+ String filter,
+ int count,
+ int marker) {
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock context = CMS.createArgBlock();
+ CMSTemplateParams argset = new CMSTemplateParams(header, context);
+
+ try {
+ long startTime = CMS.getCurrentDate().getTime();
+ // preserve the type of request that we are
+ // requesting.
+
+ header.addStringValue(OUT_AUTHORITY_ID, mAuthority.getId());
+ header.addStringValue(OUT_REQUESTING_USER, "admin");
+
+
+ boolean jumptoend = false;
+ if (marker == -1) {
+ marker = 0; // I think this is inconsequential
+ jumptoend = true; // override to '99' during search
+ }
+
+ RequestId id = new RequestId(Integer.toString(marker));
+ IRequestVirtualList list = mQueue.getPagedRequestsByFilter(
+ id,
+ jumptoend,
+ filter,
+ count+1,
+ "requestId");
+
+ int totalCount = list.getSize() - list.getCurrentIndex();
+ header.addIntegerValue(OUT_TOTALCOUNT, totalCount);
+ header.addIntegerValue(OUT_CURRENTCOUNT, list.getSize());
+
+ int numEntries = list.getSize() - list.getCurrentIndex();
+
+ Vector v = fetchRecords(list,Math.abs(count));
+ v = normalizeOrder(v);
+ trim(v,id);
+
+
+ int currentCount = 0;
+ int curNum = 0;
+ int firstNum = -1;
+ Enumeration requests = v.elements();
+
+ while (requests.hasMoreElements()) {
+ IRequest request = null;
+ try {
+ request = (IRequest) requests.nextElement();
+ } catch (Exception e) {
+ CMS.debug("Error displaying request:"+e.getMessage());
+ // handled below
+ }
+ if (request == null) {
+ log(ILogger.LL_WARN, "Error display request on page");
+ continue;
+ }
+
+ curNum = Integer.parseInt(
+ request.getRequestId().toString());
+
+ if (firstNum == -1) {
+ firstNum = curNum;
+ }
+
+ IArgBlock rec = CMS.createArgBlock();
+ mParser.fillRequestIntoArg(locale, request, argset, rec);
+ mQueue.releaseRequest(request);
+ argset.addRepeatRecord(rec);
+
+ currentCount++;
+
+ }// while
+ long endTime = CMS.getCurrentDate().getTime();
+
+ header.addIntegerValue(OUT_CURRENTCOUNT, currentCount);
+ header.addStringValue("time", Long.toString(endTime - startTime));
+ header.addIntegerValue(OUT_FIRST_ENTRY_ON_PAGE, firstNum);
+ header.addIntegerValue(OUT_LAST_ENTRY_ON_PAGE, curNum);
+
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ } catch (Exception e) {
+ }
+ return argset;
+
+ }
+
+ /**
+ * If the vector contains the marker element at the end, remove it.
+ * @param v The vector to trim
+ * @param marker the marker to look for.
+ */
+ private void trim(Vector v, RequestId marker) {
+ int i = v.size()-1;
+ if (((IRequest)v.elementAt(i)).getRequestId().equals(marker)) {
+ v.remove(i);
+ }
+
+ }
+
+ /**
+ * Sometimes the list comes back from LDAP in reverse order. This function makes
+ * sure the results are in 'forward' order.
+ * @param list
+ * @return
+ */
+ private Vector fetchRecords(IRequestVirtualList list, int maxCount) {
+
+ Vector v = new Vector();
+ int count = list.getSize();
+ int c=0;
+ for (int i=0; i<count; i++) {
+ IRequest request = list.getElementAt(i);
+ if (request != null) {
+ v.add(request);
+ c++;
+ }
+ if (c >= maxCount) break;
+ }
+
+ return v;
+
+ }
+
+ /**
+ * If the requests are in backwards order, reverse the list
+ * @param list
+ * @return
+ */
+ private Vector normalizeOrder(Vector list) {
+
+ int firstrequestnum = Integer.parseInt(((IRequest) list.elementAt(0))
+ .getRequestId().toString());
+ int lastrequestnum = Integer.parseInt(((IRequest) list.elementAt(list
+ .size() - 1)).getRequestId().toString());
+ boolean reverse = false;
+ if (firstrequestnum > lastrequestnum) {
+ reverse = true; // if the order is backwards, place items at the beginning
+ }
+ Vector v = new Vector();
+ int count = list.size();
+ for (int i = 0; i < count; i++) {
+ Object request = list.elementAt(i);
+ if (request != null) {
+ if (reverse)
+ v.add(0, request);
+ else
+ v.add(request);
+ }
+ }
+
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/ReqParser.java b/pki/base/common/src/com/netscape/cms/servlet/request/ReqParser.java
new file mode 100644
index 000000000..a9fc6aaac
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/ReqParser.java
@@ -0,0 +1,88 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * A class representing a request parser.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ReqParser implements IReqParser {
+
+ private final static String TYPE = "requestType";
+ private final static String STATUS = "status";
+ private final static String CREATE_ON = "createdOn";
+ private final static String UPDATE_ON = "updatedOn";
+ private final static String UPDATE_BY = "updatedBy";
+
+ /**
+ * Constructs a request parser.
+ */
+ public ReqParser() {
+ }
+
+ /**
+ * Maps request object into argument block.
+ */
+ public void fillRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
+ throws EBaseException {
+ arg.addStringValue(TYPE, req.getRequestType());
+ arg.addLongValue("seqNum",
+ Long.parseLong(req.getRequestId().toString()));
+ arg.addStringValue(STATUS,
+ req.getRequestStatus().toString());
+ arg.addLongValue(CREATE_ON,
+ req.getCreationTime().getTime() / 1000);
+ arg.addLongValue(UPDATE_ON,
+ req.getModificationTime().getTime() / 1000);
+ String updatedBy = req.getExtDataInString(IRequest.UPDATED_BY);
+
+ if (updatedBy == null) updatedBy = "";
+ arg.addStringValue(UPDATE_BY, updatedBy);
+
+ SessionContext ctx = SessionContext.getContext();
+ String id = (String) ctx.get(SessionContext.USER_ID);
+
+ arg.addStringValue("callerName", id);
+
+ String owner = req.getRequestOwner();
+
+ if (owner != null)
+ arg.addStringValue("assignedTo", owner);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java b/pki/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java
new file mode 100644
index 000000000..0211c311e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java
@@ -0,0 +1,327 @@
+// --- 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.servlet.request;
+
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+//import netscape.security.provider.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * Search for certificates matching complex query filter
+ *
+ * @version $Revision$, $Date$
+ */
+public class SearchReqs extends CMSServlet {
+
+ private final static String TPL_FILE = "queryReq.template";
+ private final static String INFO = "QueryReq";
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReqReturns";
+ private final static String PROP_PARSER = "parser";
+ private final static String CURRENT_TIME = "currentTime";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+ private final static String OUT_AUTHORITY_ID = "authorityid";
+ private final static String OUT_REQUESTING_USER = "requestingUser";
+ private final static String OUT_SEQNUM_FROM = "seqNumFrom";
+ private final static String OUT_MAXCOUNT = "maxCount";
+ private final static String OUT_TOTALCOUNT = "totalRecordCount";
+ private final static String OUT_CURRENTCOUNT = "currentRecordCount";
+ private final static String OUT_SENTINEL = "querySentinel";
+ private final static String OUT_ERROR = "error";
+ private final static int MAX_RESULTS = 1000;
+
+ private IRequestQueue mQueue = null;
+ private IReqParser mParser = null;
+ private String mFormPath = null;
+ private int mMaxReturns = MAX_RESULTS;
+ private int mTimeLimits = 30; /* in seconds */
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SearchReqs() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses queryReq.template
+ * to render the response
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ISubsystem) {
+ ISubsystem sub = (ISubsystem) mAuthority;
+ IConfigStore authConfig = sub.getConfigStore();
+
+ if (authConfig != null) {
+ try {
+ mMaxReturns = authConfig.getInteger(PROP_MAX_SEARCH_RETURNS, MAX_RESULTS);
+ } catch (EBaseException e) {
+ // do nothing
+ }
+ }
+ }
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+ mQueue = ca.getRequestQueue();
+ }
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ /* Server-Side time limit */
+ try {
+ int maxResults = Integer.parseInt(sc.getInitParameter("maxResults"));
+ if (maxResults < mMaxReturns)
+ mMaxReturns = maxResults;
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ String tmp = sc.getInitParameter(PROP_PARSER);
+
+ if (tmp != null) {
+ if (tmp.trim().equals("CertReqParser.NODETAIL_PARSER"))
+ mParser = CertReqParser.NODETAIL_PARSER;
+ else if (tmp.trim().equals("CertReqParser.DETAIL_PARSER"))
+ mParser = CertReqParser.DETAIL_PARSER;
+ else if (tmp.trim().equals("KeyReqParser.PARSER"))
+ mParser = KeyReqParser.PARSER;
+ }
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mTemplates.remove(CMSRequest.ERROR);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Serves HTTP request. This format of this request is as follows:
+ * queryCert?
+ * [maxCount=<number>]
+ * [queryFilter=<filter>]
+ * [revokeAll=<filter>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (EAuthzAccessDenied e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ EBaseException error = null;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ String maxResultsStr = req.getParameter("maxResults");
+
+ if (maxResultsStr != null && maxResultsStr.length() > 0)
+ maxResults = Integer.parseInt(maxResultsStr);
+ String timeLimitStr = req.getParameter("timeLimit");
+
+ if (timeLimitStr != null && timeLimitStr.length() > 0)
+ timeLimit = Integer.parseInt(timeLimitStr);
+
+ process(argSet, header, req.getParameter("queryRequestFilter"), authToken,
+ maxResults, timeLimit, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ String filter, IAuthToken token,
+ int maxResults, int timeLimit,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+
+ try {
+ long startTime = CMS.getCurrentDate().getTime();
+
+ if (filter.indexOf(CURRENT_TIME, 0) > -1) {
+ filter = insertCurrentTime(filter);
+ }
+
+ String owner = req.getParameter("owner");
+ String requestowner_filter = "";
+ String newfilter = "";
+ if (owner.length() == 0) {
+ newfilter = filter;
+ } else {
+ if (owner.equals("self")) {
+ String self_uid = token.getInString(IAuthToken.USER_ID);
+ requestowner_filter = "(requestowner="+self_uid+")";
+ } else {
+ String uid = req.getParameter("uid");
+ requestowner_filter = "(requestowner="+uid+")";
+ }
+ newfilter = "(&"+requestowner_filter+filter.substring(2);
+ }
+ // xxx the filter includes serial number range???
+ if (maxResults == -1 || maxResults > mMaxReturns) {
+ CMS.debug("Resetting maximum of returned results from " + maxResults + " to " + mMaxReturns);
+ maxResults = mMaxReturns;
+ }
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ IRequestList list = (timeLimit > 0) ?
+ mQueue.listRequestsByFilter(newfilter, maxResults, timeLimit) :
+ mQueue.listRequestsByFilter(newfilter, maxResults);
+
+ int count = 0;
+
+ while (list != null && list.hasMoreElements()) {
+ IRequest request = (IRequest) list.nextRequestObject();
+
+ if (request != null) {
+ count++;
+ IArgBlock rarg = CMS.createArgBlock();
+ mParser.fillRequestIntoArg(locale, request, argSet, rarg);
+ argSet.addRepeatRecord(rarg);
+ long endTime = CMS.getCurrentDate().getTime();
+
+ header.addIntegerValue(OUT_CURRENTCOUNT, count);
+ header.addStringValue("time", Long.toString(endTime - startTime));
+ }
+ }
+ header.addIntegerValue(OUT_TOTALCOUNT, count);
+ } catch (EBaseException e) {
+ CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString());
+ throw e;
+ }
+ return;
+ }
+
+ private String insertCurrentTime(String filter) {
+ Date now = null;
+ StringBuffer newFilter = new StringBuffer();
+ int k = 0;
+ int i = filter.indexOf(CURRENT_TIME, k);
+
+ while (i > -1) {
+ if (now == null) now = new Date();
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ k = i + CURRENT_TIME.length();
+ i = filter.indexOf(CURRENT_TIME, k);
+ }
+ if (k > 0) {
+ newFilter.append(filter.substring(k, filter.length()));
+ }
+ return newFilter.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java b/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
new file mode 100644
index 000000000..9e0901a2c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -0,0 +1,1380 @@
+// --- 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.servlet.tks;
+
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.pkcs11.*;
+
+import sun.misc.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import java.net.URLEncoder;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cmsutil.util.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.tks.*;
+import com.netscape.symkey.*;
+
+
+
+/**
+ * A class representings an administration servlet for Token Key
+ * Service Authority. This servlet is responsible to serve
+ * tks administrative operation such as configuration
+ * parameter updates.
+ *
+ * @version $Revision$, $Date$
+ */
+public class TokenServlet extends CMSServlet {
+ protected static final String PROP_ENABLED = "enabled";
+
+ private final static String INFO = "TokenServlet";
+ public static int ERROR = 1;
+ private ITKSAuthority mTKS = null;
+ private String mSelectedToken = null;
+ private String mNewSelectedToken = null;
+ String mKeyNickName = null;
+ String mNewKeyNickName = null;
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_DRM =
+ "LOGGING_SIGNED_AUDIT_CONFIG_DRM_3";
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_3";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS_8";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE_9";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST =
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_5";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS_6";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE_7";
+
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST =
+ "LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_4";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS_7";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE_8";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_2";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS_3";
+
+ private final static String
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE_4";
+
+ /**
+ * Constructs tks servlet.
+ */
+ public TokenServlet() {
+ super();
+
+ }
+
+ public static String trim(String a)
+ {
+ StringBuffer newa = new StringBuffer();
+ StringTokenizer tokens = new StringTokenizer(a, "\n");
+ while (tokens.hasMoreTokens()) {
+ newa.append(tokens.nextToken());
+ }
+ return newa.toString();
+ }
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ }
+
+ /**
+ * Returns serlvet information.
+ *
+ * @return name of this servlet
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+ /**
+ * Process the HTTP request.
+ *
+ * @param s The URL to decode.
+ */
+ protected String URLdecode(String s) {
+ if (s == null)
+ return null;
+ ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = (int) s.charAt(i);
+
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '%') {
+ int c1 = Character.digit(s.charAt(++i), 16);
+ int c2 = Character.digit(s.charAt(++i), 16);
+
+ out.write((char) (c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ } // end for
+ return out.toString();
+ }
+
+ private void setDefaultSlotAndKeyName(HttpServletRequest req)
+ {
+ try {
+
+ String keySet = req.getParameter("keySet");
+ if (keySet == null || keySet.equals("")) {
+ keySet = "defKeySet";
+ }
+ CMS.debug("keySet selected: " + keySet);
+
+ mNewSelectedToken = null;
+
+ mSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot");
+ String masterKeyPrefix = CMS.getConfigStore().getString("tks.master_key_prefix", null);
+ String temp = req.getParameter("KeyInfo"); //#xx#xx
+ String keyInfoMap = "tks." + keySet + ".mk_mappings." + temp;
+ String mappingValue = CMS.getConfigStore().getString(keyInfoMap, null);
+ if(mappingValue!=null)
+ {
+ StringTokenizer st = new StringTokenizer(mappingValue, ":");
+ int tokenNumber=0;
+ while (st.hasMoreTokens()) {
+
+ String currentToken= st.nextToken();
+ if(tokenNumber==0)
+ mSelectedToken = currentToken;
+ else if(tokenNumber==1)
+ mKeyNickName = currentToken;
+ tokenNumber++;
+
+ }
+ }
+ if(req.getParameter("newKeyInfo")!=null) // for diversification
+ {
+ temp = req.getParameter("newKeyInfo"); //#xx#xx
+ String newKeyInfoMap = "tks." + keySet + ".mk_mappings." + temp;
+ String newMappingValue = CMS.getConfigStore().getString(newKeyInfoMap, null);
+ if(newMappingValue!=null)
+ {
+ StringTokenizer st = new StringTokenizer(newMappingValue, ":");
+ int tokenNumber=0;
+ while (st.hasMoreTokens()) {
+ String currentToken= st.nextToken();
+ if(tokenNumber==0)
+ mNewSelectedToken = currentToken;
+ else if(tokenNumber==1)
+ mNewKeyNickName = currentToken;
+ tokenNumber++;
+
+ }
+ }
+ }
+
+ SessionKey.SetDefaultPrefix(masterKeyPrefix);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ CMS.debug("Exception in TokenServlet::setDefaultSlotAndKeyName");
+ }
+
+ }
+
+ private void processComputeSessionKey(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException
+ {
+ byte[] card_challenge ,host_challenge,keyInfo, xCUID, CUID, session_key;
+ byte[] card_crypto, host_cryptogram, input_card_crypto;
+ byte[] xcard_challenge, xhost_challenge;
+ byte[] enc_session_key, xkeyInfo;
+ String auditMessage = null;
+ String errorMsg = "";
+ String badParams = "";
+
+ String rCUID = req.getParameter("CUID");
+ String keySet = req.getParameter("keySet");
+ if (keySet == null || keySet.equals("")) {
+ keySet = "defKeySet";
+ }
+ CMS.debug("keySet selected: " + keySet);
+
+ boolean serversideKeygen = false;
+ byte[] drm_trans_wrapped_desKey = null;
+ SymmetricKey desKey = null;
+ // PK11SymKey kek_session_key;
+ PK11SymKey kek_key;
+
+ IConfigStore sconfig = CMS.getConfigStore();
+ boolean isCryptoValidate = true;
+ boolean missingParam = false;
+ session_key = null;
+ card_crypto = null;
+ host_cryptogram = null;
+ enc_session_key = null;
+ // kek_session_key = null;
+
+ SessionContext sContext = SessionContext.getContext();
+
+ String agentId="";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST,
+ rCUID,
+ ILogger.SUCCESS,
+ agentId);
+
+ audit(auditMessage);
+
+ String kek_wrapped_desKeyString = null;
+ String keycheck_s = null;
+
+ CMS.debug("processComputeSessionKey:");
+ String useSoftToken_s = CMS.getConfigStore().getString("tks.useSoftToken", "true");
+ if (!useSoftToken_s.equalsIgnoreCase("true"))
+ useSoftToken_s = "false";
+
+ String rServersideKeygen = (String) req.getParameter("serversideKeygen");
+ if (rServersideKeygen.equals("true")) {
+ CMS.debug("TokenServlet: serversideKeygen requested");
+ serversideKeygen = true;
+ } else {
+ CMS.debug("TokenServlet: serversideKeygen not requested");
+ }
+
+ try {
+ isCryptoValidate = sconfig.getBoolean("cardcryptogram.validate.enable", true);
+ } catch (EBaseException eee) {
+ }
+
+ String rcard_challenge = req.getParameter("card_challenge");
+ String rhost_challenge = req.getParameter("host_challenge");
+ String rKeyInfo = req.getParameter("KeyInfo");
+ String rcard_cryptogram = req.getParameter("card_cryptogram");
+ if ((rCUID == null) || (rCUID.equals(""))) {
+ CMS.debug("TokenServlet: ComputeSessionKey(): missing request parameter: CUID");
+ badParams += " CUID,";
+ missingParam = true;
+ }
+
+ if ((rcard_challenge == null) || (rcard_challenge.equals(""))) {
+ badParams += " card_challenge,";
+ CMS.debug("TokenServlet: ComputeSessionKey(): missing request parameter: card challenge");
+ missingParam = true;
+ }
+
+ if ((rhost_challenge == null) || (rhost_challenge.equals(""))) {
+ badParams += " host_challenge,";
+ CMS.debug("TokenServlet: ComputeSessionKey(): missing request parameter: host challenge");
+ missingParam = true;
+ }
+
+ if ((rKeyInfo == null) || (rKeyInfo.equals(""))) {
+ badParams += " KeyInfo,";
+ CMS.debug("TokenServlet: ComputeSessionKey(): missing request parameter: key info");
+ missingParam = true;
+ }
+
+
+ String selectedToken = null;
+ String keyNickName = null;
+ boolean sameCardCrypto = true;
+
+ if (!missingParam) {
+
+ xCUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ if (xCUID == null || xCUID.length != 10) {
+ badParams += " CUID length,";
+ CMS.debug("TokenServlet: Invalid CUID length");
+ missingParam = true;
+ }
+ xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
+ if (xkeyInfo == null || xkeyInfo.length != 2) {
+ badParams += " KeyInfo length,";
+ CMS.debug("TokenServlet: Invalid key info length.");
+ missingParam = true;
+ }
+ xcard_challenge =
+ com.netscape.cmsutil.util.Utils.SpecialDecode(rcard_challenge);
+ if (xcard_challenge == null || xcard_challenge.length != 8) {
+ badParams += " card_challenge length,";
+ CMS.debug("TokenServlet: Invalid card challenge length.");
+ missingParam = true;
+ }
+
+ xhost_challenge = com.netscape.cmsutil.util.Utils.SpecialDecode(rhost_challenge);
+ if (xhost_challenge == null || xhost_challenge.length != 8) {
+ badParams += " host_challenge length,";
+ CMS.debug("TokenServlet: Invalid host challenge length");
+ missingParam = true;
+ }
+
+ }
+
+ CUID = null;
+ if (!missingParam) {
+ card_challenge =
+ com.netscape.cmsutil.util.Utils.SpecialDecode(rcard_challenge);
+
+ host_challenge = com.netscape.cmsutil.util.Utils.SpecialDecode(rhost_challenge);
+ keyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
+
+ CUID =com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+
+ String keyInfoMap = "tks." + keySet + ".mk_mappings." + rKeyInfo; //#xx#xx
+ String mappingValue = CMS.getConfigStore().getString(keyInfoMap, null);
+ if (mappingValue == null) {
+ selectedToken =
+ CMS.getConfigStore().getString("tks.defaultSlot", "internal");
+ keyNickName = rKeyInfo;
+ } else {
+ StringTokenizer st = new StringTokenizer(mappingValue, ":");
+ if (st.hasMoreTokens())
+ selectedToken = st.nextToken();
+ if (st.hasMoreTokens())
+ keyNickName = st.nextToken();
+ }
+
+ if (selectedToken != null && keyNickName != null) {
+
+ try {
+
+ byte macKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".mac_key"));
+ CMS.debug("TokenServlet about to try ComputeSessionKey selectedToken=" + selectedToken + " keyNickName=" + keyNickName);
+ session_key = SessionKey.ComputeSessionKey(
+ selectedToken,keyNickName,card_challenge,
+ host_challenge,keyInfo,CUID, macKeyArray, useSoftToken_s);
+
+ if(session_key == null)
+ {
+ CMS.debug("TokenServlet:Tried ComputeSessionKey, got NULL ");
+ throw new Exception("Can't compute session key!");
+
+ }
+
+ byte encKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".auth_key"));
+ enc_session_key = SessionKey.ComputeEncSessionKey(
+ selectedToken,keyNickName,card_challenge,
+ host_challenge,keyInfo,CUID, encKeyArray, useSoftToken_s);
+
+ if(enc_session_key == null)
+ {
+ CMS.debug("TokenServlet:Tried ComputeEncSessionKey, got NULL ");
+ throw new Exception("Can't compute enc session key!");
+
+ }
+
+ if (serversideKeygen == true) {
+
+ /**
+ * 0. generate des key
+ * 1. encrypt des key with kek key
+ * 2. encrypt des key with DRM transport key
+ * These two wrapped items are to be sent back to
+ * TPS. 2nd item is to DRM
+ **/
+ CMS.debug("TokenServlet: calling ComputeKekKey");
+
+ byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+ kek_key = SessionKey.ComputeKekKey(
+ selectedToken,keyNickName,card_challenge,
+ host_challenge,keyInfo,CUID, kekKeyArray, useSoftToken_s);
+ CMS.debug("TokenServlet: called ComputeKekKey");
+
+ if(kek_key == null)
+ {
+ CMS.debug("TokenServlet:Tried ComputeKekKey, got NULL ");
+ throw new Exception("Can't compute kek key!");
+
+ }
+ // now use kek key to wrap kek session key..
+ CMS.debug("computeSessionKey:kek key len ="+
+ kek_key.getLength());
+
+ // (1) generate DES key
+ /* applet does not support DES3
+ org.mozilla.jss.crypto.KeyGenerator kg =
+ internalToken.getKeyGenerator(KeyGenAlgorithm.DES3);
+ desKey = kg.generate();*/
+
+ /*
+ * XXX GenerateSymkey firt generates a 16 byte DES2 key.
+ * It then pads it into a 24 byte key with last
+ * 8 bytes copied from the 1st 8 bytes. Effectively
+ * making it a 24 byte DES2 key. We need this for
+ * wrapping private keys on DRM.
+ */
+ /*generate it on whichever token the master key is at*/
+ if (useSoftToken_s.equals("true")) {
+ CMS.debug("TokenServlet: key encryption key generated on internal");
+//cfu audit here? sym key gen
+ desKey = SessionKey.GenerateSymkey("internal");
+//cfu audit here? sym key gen done
+ } else {
+ CMS.debug("TokenServlet: key encryption key generated on " + selectedToken);
+ desKey = SessionKey.GenerateSymkey(selectedToken);
+ }
+ if (desKey != null)
+ CMS.debug("TokenServlet: key encryption key generated for "+rCUID);
+ else {
+ CMS.debug("TokenServlet: key encryption key generation failed for "+rCUID);
+ throw new Exception ("can't generate key encryption key");
+ }
+
+ /*
+ * XXX ECBencrypt actually takes the 24 byte DES2 key
+ * and discard the last 8 bytes before it encrypts.
+ * This is done so that the applet can digest it
+ */
+ byte[] encDesKey =
+ SessionKey.ECBencrypt( kek_key,
+ desKey.getKeyData());
+ /*
+ CMS.debug("computeSessionKey:encrypted desKey size = "+encDesKey.length);
+ CMS.debug(encDesKey);
+ */
+
+ kek_wrapped_desKeyString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(encDesKey);
+
+ // get keycheck
+ byte[] keycheck =
+ SessionKey.ComputeKeyCheck(desKey.getKeyData());
+ /*
+ CMS.debug("computeSessionKey:keycheck size = "+keycheck.length);
+ CMS.debug(keycheck);
+ */
+ keycheck_s =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(keycheck);
+
+ //XXX use DRM transport cert to wrap desKey
+ String drmTransNickname = CMS.getConfigStore().getString("tks.drm_transport_cert_nickname", "");
+
+ if ((drmTransNickname == null) || (drmTransNickname == "")) {
+ CMS.debug("TokenServlet:did not find DRM transport certificate nickname");
+ throw new Exception("can't find DRM transport certificate nickname");
+ } else {
+ CMS.debug("TokenServlet:drmtransport_cert_nickname="+drmTransNickname);
+ }
+
+ X509Certificate drmTransCert = null;
+ drmTransCert = CryptoManager.getInstance().findCertByNickname(drmTransNickname);
+ // wrap kek session key with DRM transport public key
+ CryptoToken token = null;
+ if (useSoftToken_s.equals("true")) {
+ token = CryptoManager.getInstance().getTokenByName("Internal Key Storage Token");
+ } else {
+ token = CryptoManager.getInstance().getTokenByName(selectedToken);
+ }
+ PublicKey pubKey = drmTransCert.getPublicKey();
+ String pubKeyAlgo = pubKey.getAlgorithm();
+ CMS.debug("Transport Cert Key Algorithm: " + pubKeyAlgo);
+ KeyWrapper keyWrapper = null;
+ //For wrapping symmetric keys don't need IV, use ECB
+ if (pubKeyAlgo.equals("EC")) {
+ keyWrapper = token.getKeyWrapper(KeyWrapAlgorithm.AES_ECB);
+ keyWrapper.initWrap(pubKey, null);
+ } else {
+ keyWrapper = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+ keyWrapper.initWrap(pubKey, null);
+ }
+ drm_trans_wrapped_desKey = keyWrapper.wrap(desKey);
+ CMS.debug("computeSessionKey:desKey wrapped with drm transportation key.");
+
+ } // if (serversideKeygen == true)
+
+ byte authKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".auth_key"));
+ host_cryptogram = SessionKey.ComputeCryptogram(
+ selectedToken,keyNickName,card_challenge,
+ host_challenge,keyInfo,CUID,0, authKeyArray, useSoftToken_s);
+
+ if(host_cryptogram == null)
+ {
+ CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
+ throw new Exception("Can't compute host cryptogram!");
+
+ }
+ card_crypto = SessionKey.ComputeCryptogram(
+ selectedToken,keyNickName,card_challenge,
+ host_challenge,keyInfo,CUID,1, authKeyArray, useSoftToken_s);
+
+ if(card_crypto == null)
+ {
+ CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
+ throw new Exception("Can't compute card cryptogram!");
+
+ }
+
+ if (isCryptoValidate) {
+ if (rcard_cryptogram == null) {
+ CMS.debug("TokenServlet: ComputeCryptogram(): missing card cryptogram");
+ throw new Exception("Missing card cryptogram");
+ }
+ input_card_crypto =
+ com.netscape.cmsutil.util.Utils.SpecialDecode(rcard_cryptogram);
+ if (card_crypto.length == input_card_crypto.length) {
+ for (int i=0; i<card_crypto.length; i++) {
+ if (card_crypto[i] != input_card_crypto[i]) {
+ sameCardCrypto = false;
+ break;
+ }
+ }
+ } else {
+ // different length; must be different
+ sameCardCrypto = false;
+ }
+ }
+
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_TKS,
+ ILogger.LL_INFO,"processComputeSessionKey for CUID=" +
+ trim(pp.toHexString(CUID)));
+ } catch (Exception e) {
+ CMS.debug(e);
+ CMS.debug("TokenServlet Computing Session Key: " + e.toString());
+ if (isCryptoValidate)
+ sameCardCrypto = false;
+ }
+ }
+ } // ! missingParam
+
+ String value = "";
+
+ resp.setContentType("text/html");
+
+ String outputString = "";
+ String encSessionKeyString = "";
+ String drm_trans_wrapped_desKeyString = "";
+ String cryptogram = "";
+ String status = "0";
+ if (session_key != null && session_key.length > 0) {
+ outputString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(session_key);
+ } else {
+
+ status = "1";
+ }
+
+ if (enc_session_key != null && enc_session_key.length > 0) {
+ encSessionKeyString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(enc_session_key);
+ } else {
+ status = "1";
+ }
+
+
+ if (serversideKeygen == true) {
+ if ( drm_trans_wrapped_desKey != null && drm_trans_wrapped_desKey.length > 0)
+ drm_trans_wrapped_desKeyString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(drm_trans_wrapped_desKey);
+ else {
+ status = "1";
+ }
+ }
+
+
+ if (host_cryptogram != null && host_cryptogram.length > 0) {
+ cryptogram =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(host_cryptogram);
+ } else {
+ status = "2";
+ }
+
+ if (selectedToken == null || keyNickName == null) {
+ status = "4";
+ }
+
+ if (!sameCardCrypto) {
+ status = "3";
+ }
+
+ if (missingParam) {
+ status = "3";
+ }
+
+ if (!status.equals("0")) {
+
+
+ if(status.equals("1")) {
+ errorMsg = "Problem generating session key info.";
+ }
+
+ if(status.equals("2")) {
+ errorMsg = "Problem creating host_cryptogram.";
+ }
+
+ if(status.equals("4")) {
+ errorMsg = "Problem obtaining token information.";
+ }
+
+ if(status.equals("3")) {
+ if(badParams.endsWith(",")) {
+ badParams = badParams.substring(0,badParams.length() -1);
+ }
+ errorMsg = "Missing input parameters :" + badParams;
+ }
+
+ value = "status="+status;
+ }
+ else {
+ if (serversideKeygen == true) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("status=0&");
+ sb.append("sessionKey=");
+ sb.append(outputString);
+ sb.append("&hostCryptogram=");
+ sb.append(cryptogram);
+ sb.append("&encSessionKey=");
+ sb.append(encSessionKeyString);
+ sb.append("&kek_wrapped_desKey=");
+ sb.append(kek_wrapped_desKeyString);
+ sb.append("&keycheck=");
+ sb.append(keycheck_s);
+ sb.append("&drm_trans_wrapped_desKey=");
+ sb.append(drm_trans_wrapped_desKeyString);
+ value = sb.toString();
+ } else {
+ StringBuffer sb = new StringBuffer();
+ sb.append("status=0&");
+ sb.append("sessionKey=");
+ sb.append(outputString);
+ sb.append("&hostCryptogram=");
+ sb.append(cryptogram);
+ sb.append("&encSessionKey=");
+ sb.append(encSessionKeyString);
+ value = sb.toString();
+ }
+
+ }
+ CMS.debug("TokenServlet:outputString.encode " +value);
+
+ try{
+ resp.setContentLength(value.length());
+ CMS.debug("TokenServlet:outputString.length " +value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (IOException e) {
+ CMS.debug("TokenServlet: " + e.toString());
+ }
+
+ if(status.equals("0")) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS,
+ rCUID,
+ ILogger.SUCCESS,
+ status,
+ agentId,
+ isCryptoValidate? "true":"false",
+ serversideKeygen? "true":"false",
+ selectedToken,
+ keyNickName);
+
+ } else {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,
+ rCUID,
+ ILogger.FAILURE,
+ status,
+ agentId,
+ isCryptoValidate? "true":"false",
+ serversideKeygen? "true":"false",
+ selectedToken,
+ keyNickName,
+ errorMsg);
+ }
+
+ audit(auditMessage);
+ }
+
+ private void processDiversifyKey(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException {
+ byte[] KeySetData,KeysValues,CUID,xCUID;
+ byte[] xkeyInfo,xnewkeyInfo;
+ boolean missingParam = false;
+ String errorMsg = "";
+ String badParams = "";
+
+ IConfigStore sconfig = CMS.getConfigStore();
+ String rnewKeyInfo = req.getParameter("newKeyInfo");
+ String newMasterKeyName = req.getParameter("newKeyInfo");
+ String oldMasterKeyName = req.getParameter("KeyInfo");
+ String rCUID =req.getParameter("CUID");
+ String auditMessage="";
+
+ String keySet = req.getParameter("keySet");
+ if (keySet == null || keySet.equals("")) {
+ keySet = "defKeySet";
+ }
+ CMS.debug("keySet selected: " + keySet);
+
+ SessionContext sContext = SessionContext.getContext();
+
+ String agentId="";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST,
+ rCUID,
+ ILogger.SUCCESS,
+ agentId,
+ oldMasterKeyName,
+ newMasterKeyName);
+
+ audit(auditMessage);
+
+
+ if ((rCUID == null) || (rCUID.equals(""))) {
+ badParams += " CUID,";
+ CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: CUID");
+ missingParam = true;
+ }
+ if ((rnewKeyInfo == null) || (rnewKeyInfo.equals(""))) {
+ badParams += " newKeyInfo,";
+ CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: newKeyInfo");
+ missingParam = true;
+ }
+ if ((oldMasterKeyName == null) || (oldMasterKeyName.equals(""))){
+ badParams += " KeyInfo,";
+ CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: KeyInfo");
+ missingParam = true;
+ }
+
+ if (!missingParam) {
+ xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(oldMasterKeyName);
+ if (xkeyInfo == null || xkeyInfo.length != 2) {
+ badParams += " KeyInfo length,";
+ CMS.debug("TokenServlet: Invalid key info length");
+ missingParam = true;
+ }
+ xnewkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(newMasterKeyName);
+ if (xnewkeyInfo == null || xnewkeyInfo.length != 2) {
+ badParams += " NewKeyInfo length,";
+ CMS.debug("TokenServlet: Invalid new key info length");
+ missingParam = true;
+ }
+ }
+ String useSoftToken_s = CMS.getConfigStore().getString("tks.useSoftToken", "true");
+ if (!useSoftToken_s.equalsIgnoreCase("true"))
+ useSoftToken_s = "false";
+
+ KeySetData = null;
+ String outputString = null;
+ if (!missingParam) {
+ xCUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ if (xCUID == null || xCUID.length != 10) {
+ badParams += " CUID length,";
+ CMS.debug("TokenServlet: Invalid CUID length");
+ missingParam = true;
+ }
+ }
+ if (!missingParam) {
+ CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+
+ if (mKeyNickName!=null)
+ oldMasterKeyName = mKeyNickName;
+ if (mNewKeyNickName!=null)
+ newMasterKeyName = mNewKeyNickName;
+
+ String oldKeyInfoMap = "tks." + keySet + ".mk_mappings." + req.getParameter("KeyInfo"); //#xx#xx
+ String oldMappingValue = CMS.getConfigStore().getString(oldKeyInfoMap, null);
+ String oldSelectedToken = null;
+ String oldKeyNickName = null;
+ if (oldMappingValue == null) {
+ oldSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot", "internal");
+ oldKeyNickName = req.getParameter("KeyInfo");
+ } else {
+ StringTokenizer st = new StringTokenizer(oldMappingValue, ":");
+ oldSelectedToken = st.nextToken();
+ oldKeyNickName = st.nextToken();
+ }
+
+ String newKeyInfoMap = "tks.mk_mappings." + rnewKeyInfo; //#xx#xx
+ String newMappingValue = CMS.getConfigStore().getString(newKeyInfoMap, null);
+ String newSelectedToken = null;
+ String newKeyNickName = null;
+ if (newMappingValue == null) {
+ newSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot", "internal");
+ newKeyNickName = rnewKeyInfo;
+ } else {
+ StringTokenizer st = new StringTokenizer(newMappingValue, ":");
+ newSelectedToken = st.nextToken();
+ newKeyNickName = st.nextToken();
+ }
+
+ CMS.debug("process DiversifyKey for oldSelectedToke="+
+ oldSelectedToken + " newSelectedToken=" + newSelectedToken +
+ " oldKeyNickName=" + oldKeyNickName + " newKeyNickName=" +
+ newKeyNickName);
+
+ byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+ KeySetData = SessionKey.DiversifyKey(oldSelectedToken,
+ newSelectedToken, oldKeyNickName,
+ newKeyNickName,rnewKeyInfo,CUID, kekKeyArray, useSoftToken_s);
+
+ if (KeySetData == null || KeySetData.length<=1) {
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_TKS,
+ ILogger.LL_INFO,"process DiversifyKey: Missing MasterKey in Slot");
+ }
+
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_TKS,
+ ILogger.LL_INFO,"process DiversifyKey for CUID ="+ trim(pp.toHexString(CUID))
+ + ";from oldMasterKeyName="+oldSelectedToken + ":" + oldKeyNickName
+ +";to newMasterKeyName="+newSelectedToken + ":" + newKeyNickName);
+
+ resp.setContentType("text/html");
+
+ if (KeySetData != null) {
+ outputString = new String(KeySetData);
+ }
+ } // ! missingParam
+
+ //CMS.debug("TokenServlet:processDiversifyKey " +outputString);
+ //String value="keySetData=%00" if the KeySetData=byte[0]=0;
+
+ String value = "";
+ String status = "0";
+
+ if (KeySetData != null && KeySetData.length > 1) {
+ value = "status=0&"+"keySetData=" +
+ com.netscape.cmsutil.util.Utils.SpecialEncode(KeySetData);
+ CMS.debug("TokenServlet:process DiversifyKey.encode " +value);
+ } else if (missingParam) {
+ status = "3";
+ if(badParams.endsWith(",")) {
+ badParams = badParams.substring(0,badParams.length() -1);
+ }
+ errorMsg = "Missing input parameters: " + badParams;
+ value = "status=" + status;
+ } else {
+ errorMsg = "Problem diversifying key data.";
+ status = "1";
+ value = "status=" + status;
+ }
+
+ resp.setContentLength(value.length());
+ CMS.debug("TokenServlet:outputString.length " +value.length());
+
+ try{
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (Exception e) {
+ CMS.debug("TokenServlet:process DiversifyKey: " + e.toString());
+ }
+
+ if(status.equals("0")) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS,
+ rCUID,
+ ILogger.SUCCESS,
+ status,
+ agentId,
+ oldMasterKeyName,
+ newMasterKeyName);
+
+ } else {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,
+ rCUID,
+ ILogger.FAILURE,
+ status,
+ agentId,
+ oldMasterKeyName,
+ newMasterKeyName,
+ errorMsg);
+ }
+
+ audit(auditMessage);
+ }
+
+ private void processEncryptData(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException {
+ byte[] keyInfo, CUID, xCUID, encryptedData, xkeyInfo;
+ boolean missingParam = false;
+ byte[] data = null;
+ boolean isRandom = true; // randomly generate the data to be encrypted
+
+ String errorMsg = "";
+ String badParams = "";
+ IConfigStore sconfig = CMS.getConfigStore();
+ encryptedData = null;
+ String rdata = req.getParameter("data");
+ String rKeyInfo = req.getParameter("KeyInfo");
+ String rCUID = req.getParameter("CUID");
+ String keySet = req.getParameter("keySet");
+ if (keySet == null || keySet.equals("")) {
+ keySet = "defKeySet";
+ }
+
+ SessionContext sContext = SessionContext.getContext();
+
+ String agentId="";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ CMS.debug("keySet selected: " + keySet);
+
+ String s_isRandom = sconfig.getString("tks.EncryptData.isRandom", "true");
+ if (s_isRandom.equalsIgnoreCase("false")) {
+ CMS.debug("TokenServlet: processEncryptData(): Random number not to be generated");
+ isRandom = false;
+ } else {
+ CMS.debug("TokenServlet: processEncryptData(): Random number generation required");
+ isRandom = true;
+ }
+
+ String auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST,
+ rCUID,
+ ILogger.SUCCESS,
+ agentId,
+ s_isRandom);
+
+ audit(auditMessage);
+
+ if (isRandom) {
+ if ((rdata == null) || (rdata.equals(""))) {
+ CMS.debug("TokenServlet: processEncryptData(): no data in request. Generating random number as data");
+ } else {
+ CMS.debug("TokenServlet: processEncryptData(): contain data in request, however, random generation on TKS is required. Generating...");
+ }
+ try {
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ data = new byte[16];
+ random.nextBytes(data);
+ } catch (Exception e) {
+ CMS.debug("TokenServlet: processEncryptData():"+ e.toString());
+ badParams += " Random Number,";
+ missingParam = true;
+ }
+ } else if ((!isRandom) && (((rdata == null) || (rdata.equals(""))))){
+ CMS.debug("TokenServlet: processEncryptData(): missing request parameter: data.");
+ badParams += " data,";
+ missingParam = true;
+ }
+
+ if ((rCUID == null) || (rCUID.equals(""))) {
+ badParams += " CUID,";
+ CMS.debug("TokenServlet: processEncryptData(): missing request parameter: CUID");
+ missingParam = true;
+ }
+
+ if ((rKeyInfo == null) || (rKeyInfo.equals(""))) {
+ badParams += " KeyInfo,";
+ CMS.debug("TokenServlet: processEncryptData(): missing request parameter: key info");
+ missingParam = true;
+ }
+
+
+ if (!missingParam) {
+ xCUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ if (xCUID == null || xCUID.length != 10) {
+ badParams += " CUID length,";
+ CMS.debug("TokenServlet: Invalid CUID length");
+ missingParam = true;
+ }
+ xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
+ if (xkeyInfo == null || xkeyInfo.length != 2) {
+ badParams += " KeyInfo length,";
+ CMS.debug("TokenServlet: Invalid key info length");
+ missingParam = true;
+ }
+ }
+
+ String useSoftToken_s = CMS.getConfigStore().getString("tks.useSoftToken","true");
+ if (!useSoftToken_s.equalsIgnoreCase("true"))
+ useSoftToken_s = "false";
+
+ String selectedToken = null;
+ String keyNickName = null;
+ if (!missingParam) {
+ if (!isRandom)
+ data = com.netscape.cmsutil.util.Utils.SpecialDecode(rdata);
+ keyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
+ CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+
+ String keyInfoMap = "tks." + keySet + ".mk_mappings." + rKeyInfo;
+ String mappingValue = CMS.getConfigStore().getString(keyInfoMap, null);
+ if (mappingValue == null) {
+ selectedToken = CMS.getConfigStore().getString("tks.defaultSlot", "internal");
+ keyNickName = rKeyInfo;
+ } else {
+ StringTokenizer st = new StringTokenizer(mappingValue, ":");
+ selectedToken = st.nextToken();
+ keyNickName = st.nextToken();
+ }
+
+ byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+ encryptedData = SessionKey.EncryptData(
+ selectedToken,keyNickName,data,keyInfo,CUID, kekKeyArray, useSoftToken_s);
+
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_TKS,
+ ILogger.LL_INFO,"process EncryptData for CUID ="+ trim(pp.toHexString(CUID)));
+ } // !missingParam
+
+ resp.setContentType("text/html");
+
+ String value = "";
+ String status = "0";
+ if (encryptedData != null && encryptedData.length > 0) {
+ String outputString = new String(encryptedData);
+ // sending both the pre-encrypted and encrypted data back
+ value = "status=0&"+"data="+
+ com.netscape.cmsutil.util.Utils.SpecialEncode(data)+
+ "&encryptedData=" +
+ com.netscape.cmsutil.util.Utils.SpecialEncode(encryptedData);
+ } else if (missingParam) {
+ if(badParams.endsWith(",")) {
+ badParams = badParams.substring(0,badParams.length() -1);
+ }
+ errorMsg = "Missing input parameters: " + badParams;
+ status = "3";
+ value = "status=" + status;
+ } else {
+ errorMsg = "Problem encrypting data.";
+ status = "1";
+ value = "status=" + status;
+ }
+
+ CMS.debug("TokenServlet:process EncryptData.encode " +value);
+
+ try {
+ resp.setContentLength(value.length());
+ CMS.debug("TokenServlet:outputString.lenght " +value.length());
+
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (Exception e) {
+ CMS.debug("TokenServlet: " + e.toString());
+ }
+
+ if(status.equals("0")) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,
+ rCUID,
+ ILogger.SUCCESS,
+ status,
+ agentId,
+ s_isRandom,
+ selectedToken,
+ keyNickName);
+
+ } else {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,
+ rCUID,
+ ILogger.FAILURE,
+ status,
+ agentId,
+ s_isRandom,
+ selectedToken,
+ keyNickName,
+ errorMsg);
+ }
+
+ audit(auditMessage);
+ }
+
+ /*
+ * For EncryptData:
+ * data=value1
+ * CUID=value2 // missing from RA
+ * versionID=value3 // missing from RA
+ *
+ * For ComputeSession:
+ * card_challenge=value1
+ * host_challenge=value2
+
+ * For DiversifyKey:
+ * new_master_key_index
+ * master_key_index
+ */
+
+ private void processComputeRandomData(HttpServletRequest req,
+ HttpServletResponse resp) throws EBaseException {
+
+ byte[] randomData = null;
+ String status = "0";
+ String errorMsg = "";
+ String badParams = "";
+ boolean missingParam = false;
+ int dataSize = 0;
+
+ CMS.debug("TokenServlet::processComputeRandomData");
+
+ SessionContext sContext = SessionContext.getContext();
+
+ String agentId="";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ String sDataSize = req.getParameter("dataNumBytes");
+
+ if(sDataSize == null || sDataSize.equals("")) {
+ CMS.debug("TokenServlet::processComputeRandomData missing param dataNumBytes");
+ badParams += " Random Data size, ";
+ missingParam = true;
+ status = "1";
+ } else {
+ try
+ {
+ dataSize = Integer.parseInt(sDataSize.trim());
+ }
+ catch (NumberFormatException nfe)
+ {
+ CMS.debug("TokenServlet::processComputeRandomData invalid data size input!");
+ badParams += " Random Data size, ";
+ missingParam = true;
+ status = "1";
+ }
+
+ }
+
+ CMS.debug("TokenServlet::processComputeRandomData data size requested: " + dataSize);
+
+ String auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST,
+ ILogger.SUCCESS,
+ agentId);
+
+ audit(auditMessage);
+
+ if(!missingParam) {
+ try {
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ randomData = new byte[dataSize];
+ random.nextBytes(randomData);
+ } catch (Exception e) {
+ CMS.debug("TokenServlet::processComputeRandomData:"+ e.toString());
+ errorMsg = "Can't generate random data!";
+ status = "2";
+ }
+ }
+
+ String randomDataOut = "";
+ if(status.equals("0")) {
+ if (randomData != null && randomData.length == dataSize) {
+ randomDataOut =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(randomData);
+ } else {
+ status = "2";
+ errorMsg = "Can't convert random data!";
+ }
+ }
+
+ if(status.equals("1") && missingParam) {
+
+ if(badParams.endsWith(",")) {
+ badParams = badParams.substring(0,badParams.length() -1);
+ }
+ errorMsg = "Missing input parameters :" + badParams;
+ }
+
+ resp.setContentType("text/html");
+ String value = "";
+
+ value = "status="+status;
+ if(status.equals("0")) {
+ value = value + "&DATA="+randomDataOut;
+ }
+
+ try {
+ resp.setContentLength(value.length());
+ CMS.debug("TokenServler::processComputeRandomData :outputString.length " +value.length());
+
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ } catch (Exception e) {
+ CMS.debug("TokenServlet::processComputeRandomData " + e.toString());
+ }
+
+ if(status.equals("0")) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,
+ ILogger.SUCCESS,
+ status,
+ agentId);
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,
+ ILogger.FAILURE,
+ status,
+ agentId,
+ errorMsg);
+ }
+
+ audit(auditMessage);
+ }
+
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "execute");
+ } catch (Exception e) {
+ }
+
+ if (authzToken == null) {
+
+ try{
+ resp.setContentType("text/html");
+ String value = "unauthorized=";
+ CMS.debug("TokenServlet: Unauthorized");
+
+ resp.setContentLength(value.length());
+ OutputStream ooss = resp.getOutputStream();
+ ooss.write(value.getBytes());
+ ooss.flush();
+ mRenderResult = false;
+ }catch (Exception e) {
+ CMS.debug("TokenServlet: " + e.toString());
+ }
+
+ // cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String temp = req.getParameter("card_challenge");
+ mSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot");
+ setDefaultSlotAndKeyName(req);
+ if(temp!=null)
+ {
+ processComputeSessionKey(req,resp);
+ }else if(req.getParameter("data")!=null){
+ processEncryptData(req,resp);
+ }else if(req.getParameter("newKeyInfo")!=null){
+ processDiversifyKey(req,resp);
+ }else if(req.getParameter("dataNumBytes") !=null){
+ processComputeRandomData(req,resp);
+ }
+ }
+
+ /**
+ * Serves HTTP admin request.
+ *
+ * @param req HTTP request
+ * @param resp HTTP response
+ */
+ public void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ String scope = req.getParameter(Constants.OP_SCOPE);
+ String op = req.getParameter(Constants.OP_TYPE);
+
+ super.service(req, resp);
+ }
+
+ /**
+ * Parses uid0=pwd0,uid1=pwd1,... into AgentCredential.
+ *
+ * @param s credential string
+ * @return a list of credentials
+ */
+ private Credential[] parseCredentialStr(String s) {
+ StringTokenizer st = new StringTokenizer(s, ",");
+ Vector v = new Vector();
+
+ while (st.hasMoreTokens()) {
+ String a = st.nextToken();
+ StringTokenizer st0 = new StringTokenizer(a, "=");
+
+ v.addElement(new Credential(st0.nextToken(),
+ st0.nextToken()));
+ }
+ Credential ac[] = new Credential[v.size()];
+
+ v.copyInto(ac);
+ return ac;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java b/pki/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java
new file mode 100644
index 000000000..199a4f4d1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java
@@ -0,0 +1,106 @@
+// --- 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.servlet.wizard;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.io.*;
+import com.netscape.certsrv.property.*;
+
+public interface IWizardPanel {
+
+ /**
+ * Initializes this panel.
+ */
+ public void init(ServletConfig config, int panelno)
+ throws ServletException;
+
+ public void init(WizardServlet servlet, ServletConfig config,
+ int panelno, String id) throws ServletException;
+
+ public String getName();
+
+ public int getPanelNo();
+
+ public void setId(String id);
+ public String getId();
+ public PropertySet getUsage();
+
+ /**
+ * Should we skip this panel to the next one?
+ */
+ public boolean shouldSkip();
+
+ /**
+ * Cleans up panel so that isPanelDone returns false
+ */
+ public void cleanUp() throws IOException;
+
+ /**
+ * Is this panel done
+ */
+ public boolean isPanelDone();
+
+ /**
+ * Show "Apply" button on frame?
+ */
+ public boolean showApplyButton();
+
+ /**
+ * Is this a subPanel?
+ */
+ public boolean isSubPanel();
+
+ public boolean isLoopbackPanel();
+
+ /**
+ * has subPanels?
+ */
+ public boolean hasSubPanel();
+
+ /**
+ * Display the panel.
+ */
+ public void display(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context );
+ /**
+ * Checks if the given parameters are valid.
+ */
+ public void validate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context ) throws IOException;
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context ) throws IOException;
+ /**
+ * If validiate() returns false, this method will be called.
+ */
+ public void displayError(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context);
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java b/pki/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java
new file mode 100644
index 000000000..5de52fc28
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java
@@ -0,0 +1,498 @@
+// --- 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.servlet.wizard;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import javax.servlet.http.*;
+import javax.servlet.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.netscape.cmsutil.crypto.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.csadmin.*;
+
+/**
+ * wizard?p=[panel number]&op=usage <= usage in xml
+ * wizard?p=[panel number]&op=display
+ * wizard?p=[panel number]&op=next&...[additional parameters]...
+ * wizard?p=[panel number]&op=apply
+ * wizard?p=[panel number]&op=back
+ * wizard?op=menu
+ * return menu options
+ */
+public class WizardServlet extends VelocityServlet {
+
+ private String name = null;
+ private Vector mPanels = new Vector();
+
+ public void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+
+ /* load sequence map */
+ name = config.getInitParameter("name");
+ String panels = config.getInitParameter("panels");
+ StringTokenizer st = new StringTokenizer(panels, ",");
+ int pno = 0;
+ while (st.hasMoreTokens()) {
+ String p = st.nextToken();
+ StringTokenizer st1 = new StringTokenizer(p, "=");
+ String id = st1.nextToken();
+ String pvalue = st1.nextToken();
+ try {
+ IWizardPanel panel = (IWizardPanel)Class.forName(pvalue).newInstance();
+ panel.init(this, config, pno, id);
+ CMS.debug("WizardServlet: panel name=" + panel.getName());
+ mPanels.addElement(panel);
+ } catch (Exception e) {
+ CMS.debug("WizardServlet: " + e.toString());
+ }
+ pno++;
+ }
+ CMS.debug("WizardServlet: done");
+
+ }
+
+ public void exposePanels(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context )
+ {
+ Enumeration e = mPanels.elements();
+ Vector panels = new Vector();
+ while (e.hasMoreElements()) {
+ IWizardPanel p = (IWizardPanel)e.nextElement();
+ panels.addElement(p);
+ }
+ context.put("panels", panels);
+ }
+
+ /**
+ * Cleans up panels from a particular panel.
+ */
+ public void cleanUpFromPanel(int pno) throws IOException
+ {
+ /* panel number starts from zero */
+ int s = mPanels.size();
+ for (int i = pno; i < s; i++) {
+ IWizardPanel panel = (IWizardPanel)mPanels.elementAt(i);
+ panel.cleanUp();
+ }
+ }
+
+ public IWizardPanel getPanelByNo(int p)
+ {
+ IWizardPanel panel = (IWizardPanel)mPanels.elementAt(p);
+ if (panel.shouldSkip()) {
+ panel = getPanelByNo(p+1);
+ }
+ return panel;
+ }
+
+ public Template displayPanel(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context )
+ {
+ CMS.debug("WizardServlet: in display");
+ int p = getPanelNo(request);
+
+ if (p == 0) {
+ CMS.debug("WizardServlet: firstpanel");
+ context.put("firstpanel", Boolean.TRUE);
+ }
+ if (p == (mPanels.size() - 1)) {
+ CMS.debug("WizardServlet: lastpanel");
+ context.put("lastpanel", Boolean.TRUE);
+ }
+ IWizardPanel panel = getPanelByNo(p);
+ CMS.debug("WizardServlet: panel=" + panel);
+
+ if (panel.showApplyButton() == true)
+ context.put("showApplyButton", Boolean.TRUE);
+ else
+ context.put("showApplyButton", Boolean.FALSE);
+
+ panel.display(request, response, context);
+ context.put("p", Integer.toString(panel.getPanelNo()));
+
+ try {
+ return Velocity.getTemplate("admin/console/config/wizard.vm");
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public String xml_value_flatten(Object v)
+ {
+ String ret = "";
+ if (v instanceof String) {
+ ret += v;
+ } else if (v instanceof Integer) {
+ ret += ((Integer)v).toString();
+ } else if (v instanceof Vector) {
+ ret += "<Vector>";
+ Vector v1 = (Vector)v;
+ Enumeration e = v1.elements();
+ StringBuffer sb = new StringBuffer();
+ while (e.hasMoreElements()) {
+ sb.append(xml_value_flatten(e.nextElement()));
+ }
+ ret += sb.toString();
+ ret += "</Vector>";
+ } else if (v instanceof Module) { // for hardware token
+ Module m = (Module)v;
+ ret += "<Module>";
+ ret += "<CommonName>" + m.getCommonName() + "</CommonName>";
+ ret += "<UserFriendlyName>" + m.getUserFriendlyName() + "</UserFriendlyName>";
+ ret += "<ImagePath>" + m.getImagePath() + "</ImagePath>";
+ ret += "</Module>";
+ } else if (v instanceof Cert) {
+ Cert m = (Cert)v;
+ ret += "<CertReqPair>";
+ ret += "<Nickname>" + m.getNickname() + "</Nickname>";
+ ret += "<Tokenname>" + m.getTokenname() + "</Tokenname>";
+ ret += "<Request>" + m.getRequest() + "</Request>";
+ ret += "<Certificate>" + m.getCert() + "</Certificate>";
+ ret += "<Type>" + m.getType() + "</Type>";
+ ret += "<DN>" + m.getDN() + "</DN>";
+ ret += "<CertPP>" + m.getCertpp() + "</CertPP>";
+ ret += "<KeyOption>" + m.getKeyOption() + "</KeyOption>";
+ ret += "</CertReqPair>";
+ } else if (v instanceof IWizardPanel) {
+ IWizardPanel m = (IWizardPanel)v;
+ ret += "<Panel>";
+ ret += "<Id>" + m.getId() + "</Id>";
+ ret += "<Name>" + m.getName() + "</Name>";
+ ret += "</Panel>";
+ } else {
+ CMS.debug("Error: unknown type " + v.getClass().getName());
+ }
+ return ret;
+ }
+
+ public String xml_flatten(Context context)
+ {
+ StringBuffer ret = new StringBuffer();
+ Object o[] = context.getKeys();
+ for (int i = 0; i < o.length; i ++) {
+ if (o[i] instanceof String) {
+ String key = (String)o[i];
+ if (key.startsWith("__")) {
+ continue;
+ }
+ ret.append("<");
+ ret.append(key);
+ ret.append(">");
+ if (key.equals("bindpwd")) {
+ ret.append("(sensitive)");
+ } else {
+ Object v = context.get(key);
+ ret.append(xml_value_flatten(v));
+ }
+ ret.append("</");
+ ret.append(key);
+ ret.append(">");
+ }
+ }
+ return ret.toString();
+ }
+
+ public int getPanelNo(HttpServletRequest request)
+ {
+ int p = 0;
+
+ // panel number can be identified by either
+ // panel no (p parameter) directly, or
+ // panel name (panelname parameter).
+ if (request.getParameter("panelname") != null) {
+ String name = request.getParameter("panelname");
+ for (int i = 0; i < mPanels.size(); i++) {
+ IWizardPanel panel = (IWizardPanel)mPanels.elementAt(i);
+ if (panel.getId().equals(name)) {
+ return i;
+ }
+ }
+ } else if (request.getParameter("p") != null) {
+ p = Integer.parseInt(request.getParameter("p"));
+ }
+ return p;
+ }
+
+ public String getNameFromPanelNo(int p)
+ {
+ IWizardPanel wp = (IWizardPanel)mPanels.elementAt(p);
+ return wp.getId();
+ }
+
+ public IWizardPanel getPreviousPanel(int p)
+ {
+ CMS.debug("getPreviousPanel input p=" + p);
+ IWizardPanel backpanel = (IWizardPanel)mPanels.elementAt(p-1);
+ if (backpanel.isSubPanel()) {
+ backpanel = (IWizardPanel)mPanels.elementAt(p-1-1);
+ }
+ while (backpanel.shouldSkip()) {
+ backpanel = (IWizardPanel)
+ mPanels.elementAt(backpanel.getPanelNo() - 1);
+ }
+ CMS.debug("getPreviousPanel output p=" + backpanel.getPanelNo());
+ return backpanel;
+ }
+
+ public IWizardPanel getNextPanel(int p)
+ {
+ CMS.debug("getNextPanel input p=" + p);
+ IWizardPanel panel = (IWizardPanel)mPanels.elementAt(p);
+ if (p == (mPanels.size() - 1)) {
+ p = p;
+ } else if(panel.isSubPanel()) {
+ if (panel.isLoopbackPanel()) {
+ p = p-1; // Login Panel is a loop back panel
+ } else {
+ p = p+1;
+ }
+ } else if (panel.hasSubPanel()) {
+ p = p + 2;
+ } else {
+ p = p + 1;
+ }
+ IWizardPanel nextpanel = getPanelByNo(p);
+ CMS.debug("getNextPanel output p=" + p);
+ return nextpanel;
+ }
+
+ public Template goApply(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context)
+ {
+ return goNextApply(request, response, context, true);
+ }
+
+ public Template goNext(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context )
+ {
+ return goNextApply(request, response, context, false);
+ }
+
+ /*
+ * The parameter "stay" is used to indicate "apply" without
+ * moving to the next panel
+ */
+ public Template goNextApply(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context, boolean stay )
+ {
+ int p = getPanelNo(request);
+ if (stay == true)
+ CMS.debug("WizardServlet: in reply " + p);
+ else
+ CMS.debug("WizardServlet: in next " + p);
+
+ IWizardPanel panel = (IWizardPanel)mPanels.elementAt(p);
+ try {
+ panel.validate(request, response, context);
+ try {
+ panel.update(request, response, context);
+ if (stay == true) { // "apply"
+
+ if (panel.showApplyButton() == true)
+ context.put("showApplyButton", Boolean.TRUE);
+ else
+ context.put("showApplyButton", Boolean.FALSE);
+ panel.display(request, response, context);
+ } else { // "next"
+ IWizardPanel nextpanel = getNextPanel(p);
+
+ if (nextpanel.showApplyButton() == true)
+ context.put("showApplyButton", Boolean.TRUE);
+ else
+ context.put("showApplyButton", Boolean.FALSE);
+ nextpanel.display(request, response, context);
+ panel = nextpanel;
+ }
+ context.put("errorString", "");
+ } catch (Exception e) {
+ context.put("errorString", e.getMessage());
+ panel.displayError(request, response, context);
+ }
+ } catch (IOException eee) {
+ context.put("errorString", eee.getMessage());
+ panel.displayError(request, response, context);
+ }
+ p = panel.getPanelNo();
+ CMS.debug("panel no=" + p);
+ CMS.debug("panel name=" + getNameFromPanelNo(p));
+ CMS.debug("total number of panels="+mPanels.size());
+ context.put("p", Integer.toString(p));
+ context.put("panelname", getNameFromPanelNo(p));
+ if (p == 0) {
+ CMS.debug("WizardServlet: firstpanel");
+ context.put("firstpanel", Boolean.TRUE);
+ }
+ if (p == (mPanels.size() - 1)) {
+ CMS.debug("WizardServlet: lastpanel");
+ context.put("lastpanel", Boolean.TRUE);
+ }
+ // this is where we handle the xml request
+ String xml = request.getParameter("xml");
+ if (xml != null && xml.equals("true")) {
+ CMS.debug("WizardServlet: found xml");
+
+ response.setContentType("application/xml");
+ String xmlstr = xml_flatten(context);
+ context.put("xml", xmlstr);
+ try {
+ return Velocity.getTemplate("admin/console/config/xml.vm");
+ } catch (Exception e) {
+ CMS.debug("Failing to get template" + e );
+ }
+ } else {
+ try {
+ return Velocity.getTemplate("admin/console/config/wizard.vm");
+ } catch (Exception e) {
+ CMS.debug("Failing to get template" + e );
+ }
+ }
+ return null;
+ }
+
+ public Template goBack(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context )
+ {
+ int p = getPanelNo(request);
+ CMS.debug("WizardServlet: in back " + p);
+ IWizardPanel backpanel = getPreviousPanel(p);
+
+ if (backpanel.showApplyButton() == true)
+ context.put("showApplyButton", Boolean.TRUE);
+ else
+ context.put("showApplyButton", Boolean.FALSE);
+ backpanel.display(request, response, context);
+ context.put("p", Integer.toString(backpanel.getPanelNo()));
+ context.put("panelname", getNameFromPanelNo(backpanel.getPanelNo()));
+
+ p = backpanel.getPanelNo();
+
+ if (p == 0) {
+ CMS.debug("WizardServlet: firstpanel");
+ context.put("firstpanel", Boolean.TRUE);
+ }
+ if (p == (mPanels.size() - 1)) {
+ CMS.debug("WizardServlet: lastpanel");
+ context.put("lastpanel", Boolean.TRUE);
+ }
+ try {
+ return Velocity.getTemplate("admin/console/config/wizard.vm");
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public boolean authenticate(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context ) {
+ String pin = (String)request.getSession().getAttribute("pin");
+ if (pin == null) {
+ try {
+ response.sendRedirect("login");
+ } catch (IOException e) {
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public void outputHttpParameters(HttpServletRequest httpReq)
+ {
+ CMS.debug("WizardServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = (String)paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("WizardServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("WizardServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+
+ public Template handleRequest(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context )
+ {
+ CMS.debug("WizardServlet: process");
+
+ if (CMS.debugOn()) {
+ outputHttpParameters(request);
+ }
+
+ if (!authenticate(request, response, context)) {
+ CMS.debug("WizardServlet: authentication failure");
+ return null;
+ }
+
+ String op = request.getParameter("op"); /* operation */
+ if (op == null) {
+ op = "display";
+ }
+ CMS.debug("WizardServlet: op=" + op);
+ CMS.debug("WizardServlet: size=" + mPanels.size());
+
+ context.put("name", name);
+ context.put("size", Integer.toString(mPanels.size()));
+ exposePanels(request, response, context);
+
+ if (op.equals("display")) {
+ return displayPanel(request, response, context);
+ } else if (op.equals("next")) {
+ return goNext(request, response, context);
+ } else if (op.equals("apply")) {
+ return goApply(request, response, context);
+ } else if (op.equals("back")) {
+ return goBack(request, response, context);
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/shares/OldJoinShares.java b/pki/base/common/src/com/netscape/cms/shares/OldJoinShares.java
new file mode 100644
index 000000000..0e29e1f0c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/shares/OldJoinShares.java
@@ -0,0 +1,90 @@
+// --- 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.shares;
+
+import java.lang.reflect.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.apps.*;
+
+/**
+ * Use Java's reflection API to leverage CMS's
+ * old Share and JoinShares implementations.
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class OldJoinShares implements IJoinShares {
+
+ public Object mOldImpl = null;
+
+ public OldJoinShares()
+ {
+ }
+
+ public void initialize(int threshold) throws Exception
+ {
+ Class c = Class.forName("com.netscape.cmscore.shares.JoinShares");
+ Class types[] = { int.class };
+ Constructor con = c.getConstructor(types);
+ Object params[] = {Integer.valueOf(threshold)};
+ mOldImpl = con.newInstance(params);
+ }
+
+ public void addShare(int shareNum, byte[] share)
+ {
+ try {
+ Class types[] = { int.class, share.getClass() };
+ Class c = mOldImpl.getClass();
+ Method method = c.getMethod("addShare", types);
+ Object params[] = {Integer.valueOf(shareNum), share};
+ method.invoke(mOldImpl, params);
+ } catch (Exception e) {
+ }
+ }
+
+ public int getShareCount()
+ {
+ if (mOldImpl == null)
+ return -1;
+ try {
+ Class types[] = null;
+ Class c = mOldImpl.getClass();
+ Method method = c.getMethod("getShareCount", types);
+ Object params[] = null;
+ Integer result = (Integer)method.invoke(mOldImpl, params);
+ return result.intValue();
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ public byte[] recoverSecret()
+ {
+ if (mOldImpl == null)
+ return null;
+ try {
+ Class types[] = null;
+ Class c = mOldImpl.getClass();
+ Method method = c.getMethod("recoverSecret", types);
+ Object params[] = null;
+ return (byte[])method.invoke(mOldImpl, params);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/shares/OldShare.java b/pki/base/common/src/com/netscape/cms/shares/OldShare.java
new file mode 100644
index 000000000..8c3d75b22
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/shares/OldShare.java
@@ -0,0 +1,68 @@
+// --- 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.shares;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.kra.*;
+
+import java.lang.reflect.*;
+import java.io.*;
+
+/**
+ * Use Java's reflection API to leverage CMS's
+ * old Share and JoinShares implementations.
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class OldShare implements IShare
+{
+ public Object mOldImpl = null;
+
+ public OldShare()
+ {
+ }
+
+ public void initialize(byte[] secret, int threshold) throws Exception
+ {
+ try {
+ Class c = Class.forName("com.netscape.cmscore.shares.Share");
+ Class types[] = { secret.getClass(), int.class };
+ Constructor cs[] = c.getConstructors();
+ Constructor con = c.getConstructor(types);
+ Object params[] = {secret, Integer.valueOf(threshold)};
+ mOldImpl = con.newInstance(params);
+ } catch (Exception e) {
+ }
+ }
+
+ public byte[] createShare(int sharenumber)
+ {
+ if (mOldImpl == null)
+ return null;
+ try {
+ Class types[] = { int.class };
+ Class c = mOldImpl.getClass();
+ Method method = c.getMethod("createShare", types);
+ Object params[] = {Integer.valueOf(sharenumber)};
+ return (byte[])method.invoke(mOldImpl, params);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/CMSEngine.java b/pki/base/common/src/com/netscape/cmscore/apps/CMSEngine.java
new file mode 100644
index 000000000..afaa5c9fc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -0,0 +1,1915 @@
+// --- 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.cmscore.apps;
+
+
+import java.util.*;
+import java.math.*;
+import java.text.*;
+import java.io.*;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Date;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CRL;
+
+import netscape.ldap.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.cms.servlet.csadmin.*;
+import com.netscape.cmsutil.net.*;
+import netscape.security.extensions.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.security.NoSuchAlgorithmException;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.password.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogQueue;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cmscore.cert.CertPrettyPrint;
+import com.netscape.cmscore.cert.CrlPrettyPrint;
+import com.netscape.cmscore.cert.ExtPrettyPrint;
+import com.netscape.cmscore.policy.*;
+import com.netscape.cmscore.time.*;
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmscore.connector.*;
+import com.netscape.cmscore.notification.*;
+import com.netscape.cmscore.request.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.logging.LogSubsystem;
+import com.netscape.cmscore.logging.Logger;
+import com.netscape.cmscore.logging.SignedAuditLogger;
+import com.netscape.cmscore.util.OsSubsystem;
+import com.netscape.cmscore.security.JssSubsystem;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.authentication.*;
+import com.netscape.cmscore.authorization.AuthzSubsystem;
+import com.netscape.cmscore.usrgrp.UGSubsystem;
+import com.netscape.cmscore.request.RequestSubsystem;
+import com.netscape.cmscore.jobs.JobsScheduler;
+import com.netscape.osutil.*;
+
+import com.netscape.cmscore.cert.OidLoaderSubsystem;
+import com.netscape.cmscore.cert.X500NameSubsystem;
+
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import netscape.security.pkcs.*;
+import com.netscape.cmscore.security.*;
+import com.netscape.cmscore.registry.*;
+import com.netscape.cmsutil.password.*;
+import org.w3c.dom.*;
+import org.apache.xerces.parsers.DOMParser;
+
+public class CMSEngine implements ICMSEngine {
+ private static final String ID = "MAIN";
+
+ private static final String PROP_SUBSYSTEM = "subsystem";
+ private static final String PROP_ID = "id";
+ private static final String PROP_CLASS = "class";
+ private static final String SERVER_XML = "server.xml";
+
+ public static final SubsystemRegistry mSSReg = SubsystemRegistry.getInstance();
+
+ public static String instanceDir; /* path to instance <server-root>/cert-<instance-name> */
+
+ private IConfigStore mConfig = null;
+ private ISubsystem mOwner = null;
+ private long mStartupTime = 0;
+ private boolean isStarted = false;
+ private StringBuffer mWarning = new StringBuffer();
+ private ITimeSource mTimeSource = null;
+ private IPasswordStore mPasswordStore = null;
+ private WarningListener mWarningListener = null;
+ private ILogQueue mQueue = null;
+ private ISecurityDomainSessionTable mSecurityDomainSessionTable = null;
+ private String mConfigSDSessionId = null;
+ private Timer mSDTimer = null;
+
+ // static subsystems - must be singletons
+ private static SubsystemInfo[] mStaticSubsystems = {
+ new SubsystemInfo(
+ Debug.ID, Debug.getInstance()),
+ new SubsystemInfo(LogSubsystem.ID,
+ LogSubsystem.getInstance()),
+ new SubsystemInfo(
+ OsSubsystem.ID, OsSubsystem.getInstance()),
+ new SubsystemInfo(
+ JssSubsystem.ID, JssSubsystem.getInstance()),
+ new SubsystemInfo(
+ DBSubsystem.ID, DBSubsystem.getInstance()),
+ new SubsystemInfo(
+ UGSubsystem.ID, UGSubsystem.getInstance()),
+ new SubsystemInfo(
+ PluginRegistry.ID, new PluginRegistry()),
+ new SubsystemInfo(
+ OidLoaderSubsystem.ID, OidLoaderSubsystem.getInstance()),
+ new SubsystemInfo(
+ X500NameSubsystem.ID, X500NameSubsystem.getInstance()),
+ // skip TP subsystem;
+ // problem in needing dbsubsystem in constructor. and it's not used.
+ new SubsystemInfo(
+ RequestSubsystem.ID, RequestSubsystem.getInstance()),
+ };
+
+ // dynamic subsystems are loaded at init time, not neccessarily singletons.
+ private static SubsystemInfo[] mDynSubsystems = null;
+
+ // final static subsystems - must be singletons.
+ private static SubsystemInfo[] mFinalSubsystems = {
+ new SubsystemInfo(
+ AuthSubsystem.ID, AuthSubsystem.getInstance()),
+ new SubsystemInfo(
+ AuthzSubsystem.ID, AuthzSubsystem.getInstance()),
+ new SubsystemInfo(
+ JobsScheduler.ID, JobsScheduler.getInstance()),
+ };
+
+ private static final int IP = 0;
+ private static final int PORT = 1;
+ private static final int HOST = 2;
+ private static final int AGENT = 0;
+ private static final int ADMIN = 1;
+ private static final int EE_SSL = 2;
+ private static final int EE_NON_SSL = 3;
+ private static final int EE_CLIENT_AUTH_SSL = 4;
+ private static String mServerCertNickname = null;
+ private static String info[][] = { {null, null, null},//agent
+ {null, null, null},//admin
+ {null, null, null},//sslEE
+ {null, null, null},//non_sslEE
+ {null, null, null} //ssl_clientauth_EE
+ };
+
+ /**
+ * private constructor.
+ */
+ public CMSEngine() {
+ }
+
+ /**
+ * gets this ID
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * should never be called. returns error.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Retrieves the instance roort path of this server.
+ */
+ public String getInstanceDir() {
+ return instanceDir;
+ }
+
+ public synchronized IPasswordStore getPasswordStore() {
+ // initialize the PasswordReader and PasswordWriter
+ try {
+ String pwdPath = mConfig.getString("passwordFile");
+ if (mPasswordStore == null) {
+ CMS.debug("CMSEngine: getPasswordStore(): password store not initialized before.");
+ String pwdClass = mConfig.getString("passwordClass");
+
+ if (pwdClass != null) {
+ try {
+ mPasswordStore = (IPasswordStore)Class.forName(pwdClass).newInstance();
+ } catch (Exception e) {
+ CMS.debug("CMSEngine: getPasswordStore(): password store initialization failure:" + e.toString());
+ }
+ }
+ } else {
+ CMS.debug("CMSEngine: getPasswordStore(): password store initialized before.");
+ }
+
+ // have to initialize it because other places don't always
+ mPasswordStore.init(pwdPath);
+ CMS.debug("CMSEngine: getPasswordStore(): password store initialized.");
+ } catch (Exception e) {
+ CMS.debug("CMSEngine: getPasswordStore(): failure:" + e.toString());
+ }
+
+ return mPasswordStore;
+ }
+
+ /**
+ * initialize all static, dynamic and final static subsystems.
+ * @param owner null
+ * @param config main config store.
+ * @exception EBaseException if any error occur in subsystems during
+ * initialization.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOwner = owner;
+ mConfig = config;
+ int state = mConfig.getInteger("cs.state");
+ String sd = mConfig.getString("securitydomain.select", "");
+ // my default is 1 day
+ String flush_timeout = config.getString("securitydomain.flushinterval", "86400000");
+ String secdomain_source = config.getString("securitydomain.source", "memory");
+ String secdomain_check_interval = config.getString("securitydomain.checkinterval", "5000");
+
+ if (secdomain_source.equals("ldap")) {
+ mSecurityDomainSessionTable = new LDAPSecurityDomainSessionTable((new Long(flush_timeout)).longValue());
+ } else {
+ mSecurityDomainSessionTable = new SecurityDomainSessionTable((new Long(flush_timeout)).longValue());
+ }
+
+ mSDTimer = new Timer();
+ SessionTimer timertask = new SessionTimer(mSecurityDomainSessionTable);
+ if ((state != 1) || (sd.equals("existing"))) {
+ // for non-security domain hosts or if not yet configured,
+ // do not check session domain table
+ } else {
+ mSDTimer.schedule(timertask, 5, (new Long(secdomain_check_interval)).longValue());
+ }
+
+ String tsClass = config.getString("timeSourceClass", null);
+
+ if (tsClass != null) {
+ try {
+ mTimeSource = (ITimeSource)
+ Class.forName(tsClass).newInstance();
+ } catch (Exception e) {
+ // nothing to do
+ }
+ }
+ if (mTimeSource == null) {
+ // if time source is not set, set it to simple time source
+ mTimeSource = new SimpleTimeSource();
+ }
+
+ instanceDir = config.getString("instanceRoot");
+
+ loadDynSubsystems();
+
+ java.security.Security.addProvider(
+ new netscape.security.provider.CMS());
+
+ mSSReg.put(ID, this);
+ initSubsystems(mStaticSubsystems, false);
+
+ // Once the log subsystem is initialized, we
+ // want to register a listener to catch
+ // all the warning message so that we can
+ // display them in the console.
+ mQueue = Logger.getLogger().getLogQueue();
+ mWarningListener = new WarningListener(mWarning);
+ mQueue.addLogEventListener(mWarningListener);
+
+ initSubsystems(mDynSubsystems, true);
+ initSubsystems(mFinalSubsystems, false);
+
+ CMS.debug("Java version=" + (String)System.getProperty("java.version"));
+ java.security.Provider ps[] = java.security.Security.getProviders();
+
+ if (ps == null || ps.length <= 0) {
+ CMS.debug("CMSEngine: Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ CMS.debug("CMSEngine: Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+ parseServerXML();
+ fixProxyPorts();
+ }
+
+ /**
+ * Parse ACL resource attributes
+ * @param resACLs same format as the resourceACLs attribute:
+ * <PRE>
+ * <resource name>:<permission1,permission2,...permissionn>:
+ * <allow|deny> (<subset of the permission set>) <evaluator expression>
+ * </PRE>
+ * @exception EACLsException ACL related parsing errors for resACLs
+ * @return an ACL instance built from the parsed resACLs
+ */
+ public IACL parseACL(String resACLs) throws EACLsException {
+ if (resACLs == null) {
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_NULL_VALUE", "resACLs"));
+ }
+
+ ACL acl = null;
+ Vector rights = null;
+ int idx1 = resACLs.indexOf(":");
+
+ if (idx1 <= 0) {
+ acl = new ACL(resACLs, rights, resACLs);
+ } else {
+ // getting resource id
+ String resource = resACLs.substring(0, idx1);
+
+ if (resource == null) {
+ String infoMsg = "resource not specified in resourceACLS attribute:" +
+ resACLs;
+
+ String[] params = new String[2];
+
+ params[0] = resACLs;
+ params[1] = infoMsg;
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PARSING_ERROR", params));
+ }
+
+ // getting list of applicable rights
+ String st = resACLs.substring(idx1 + 1);
+ int idx2 = st.indexOf(":");
+ String rightsString = null;
+
+ if (idx2 != -1)
+ rightsString = st.substring(0, idx2);
+ else {
+ String infoMsg =
+ "rights not specified in resourceACLS attribute:" + resACLs;
+ String[] params = new String[2];
+
+ params[0] = resACLs;
+ params[1] = infoMsg;
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PARSING_ERROR", params));
+ }
+
+ if (rightsString != null) {
+ rights = new Vector();
+ StringTokenizer rtok = new StringTokenizer(rightsString, ",");
+
+ while (rtok.hasMoreTokens()) {
+ rights.addElement(rtok.nextToken());
+ }
+ }
+
+ acl = new ACL(resource, rights, resACLs);
+
+ String stx = st.substring(idx2 + 1);
+ int idx3 = stx.indexOf(":");
+ String aclStr = stx.substring(0, idx3);
+
+ // getting list of acl entries
+ if (aclStr != null) {
+ StringTokenizer atok = new StringTokenizer(aclStr, ";");
+
+ if (atok == null) {
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_NULL_VALUE", "atok"));
+ }
+
+ while (atok.hasMoreTokens()) {
+ String acs = (String) atok.nextToken();
+
+ // construct ACL entry
+ ACLEntry entry = ACLEntry.parseACLEntry(acl, acs);
+
+ if (entry == null) {
+ String infoMsg = "parseACLEntry() call failed";
+ String[] params = new String[2];
+
+ params[0] = "ACLEntry = " + acs;
+ params[1] = infoMsg;
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PARSING_ERROR", params));
+ }
+
+ entry.setACLEntryString(acs);
+ acl.addEntry(entry);
+ }
+ } else {
+ // fine
+ String infoMsg = "acls not specified in resourceACLS attribute:" +
+
+ resACLs;
+
+ String[] params = new String[2];
+
+ params[0] = resACLs;
+ params[1] = infoMsg;
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_PARSING_ERROR", params));
+ }
+
+ // getting description
+ String desc = stx.substring(idx3 + 1);
+
+ acl.setDescription(desc);
+ }
+
+ return (acl);
+ }
+
+ /**
+ * Parse server.xml to get the ports and IPs
+ */
+ private void parseServerXML() {
+ try {
+ String instanceRoot = mConfig.getString("instanceRoot");
+ String path = instanceRoot+File.separator+"conf"+File.separator+SERVER_XML;
+ DOMParser parser = new DOMParser();
+ parser.parse(path);
+ NodeList nodes = parser.getDocument().getElementsByTagName("Connector");
+ String parentName="";
+ String name="";
+ String port="";
+ for (int i=0; i<nodes.getLength(); i++) {
+ Element n = (Element)nodes.item(i);
+
+ parentName = "";
+ Element p = (Element) n.getParentNode();
+ if(p != null) {
+ parentName = p.getAttribute("name");
+ }
+ name = n.getAttribute("name");
+ port = n.getAttribute("port");
+
+ // The "server.xml" file is parsed from top-to-bottom, and
+ // supports BOTH "Port Separation" (the new default method)
+ // as well as "Shared Ports" (the old legacy method). Since
+ // both methods must be supported, the file structure MUST
+ // conform to ONE AND ONLY ONE of the following formats:
+ //
+ // Port Separation:
+ //
+ // <Catalina>
+ // ...
+ // <!-- Port Separation: Unsecure Port -->
+ // <Connector name="Unsecure" . . .
+ // ...
+ // <!-- Port Separation: Agent Secure Port -->
+ // <Connector name="Agent" . . .
+ // ...
+ // <!-- Port Separation: Admin Secure Port -->
+ // <Connector name="Admin" . . .
+ // ...
+ // <!-- Port Separation: EE Secure Port -->
+ // <Connector name="EE" . . .
+ // ...
+ // </Catalina>
+ //
+ //
+ // Shared Ports:
+ //
+ // <Catalina>
+ // ...
+ // <!-- Shared Ports: Unsecure Port -->
+ // <Connector name="Unsecure" . . .
+ // ...
+ // <!-- Shared Ports: Agent, EE, and Admin Secure Port -->
+ // <Connector name="Secure" . . .
+ // ...
+ // <!--
+ // <Connector name="Unused" . . .
+ // -->
+ // ...
+ // <!--
+ // <Connector name="Unused" . . .
+ // -->
+ // ...
+ // </Catalina>
+ //
+ if ( parentName.equals("Catalina")) {
+ if( name.equals( "Unsecure" ) ) {
+ // Port Separation: Unsecure Port
+ // OR
+ // Shared Ports: Unsecure Port
+ info[EE_NON_SSL][PORT] = port;
+ } else if( name.equals( "Agent" ) ) {
+ // Port Separation: Agent Secure Port
+ info[AGENT][PORT] = port;
+ } else if( name.equals( "Admin" ) ) {
+ // Port Separation: Admin Secure Port
+ info[ADMIN][PORT] = port;
+ } else if( name.equals( "EE" ) ) {
+ // Port Separation: EE Secure Port
+ info[EE_SSL][PORT] = port;
+ } else if( name.equals( "EEClientAuth" ) ) {
+ // Port Separation: EE Client Auth Secure Port
+ info[EE_CLIENT_AUTH_SSL][PORT] = port;
+ } else if( name.equals( "Secure" ) ) {
+ // Shared Ports: Agent, EE, and Admin Secure Port
+ info[AGENT][PORT] = port;
+ info[ADMIN][PORT] = port;
+ info[EE_SSL][PORT] = port;
+ info[EE_CLIENT_AUTH_SSL][PORT] = port;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ CMS.debug("CMSEngine: parseServerXML exception: " + e.toString());
+ }
+ }
+
+ private void fixProxyPorts() throws EBaseException {
+ try {
+ String port = mConfig.getString("proxy.securePort", "");
+ if (!port.equals("")) {
+ info[EE_SSL][PORT] = port;
+ info[ADMIN][PORT] = port;
+ info[AGENT][PORT] = port;
+ info[EE_CLIENT_AUTH_SSL][PORT] = port;
+ }
+
+ port = mConfig.getString("proxy.unsecurePort", "");
+ if (!port.equals("")) {
+ info[EE_NON_SSL][PORT] = port;
+ }
+ } catch (EBaseException e) {
+ CMS.debug("CMSEngine: fixProxyPorts exception: " + e.toString());
+ throw e;
+ }
+ }
+
+
+ public IConfigStore createFileConfigStore(String path) throws EBaseException {
+ try {
+ /* if the file is not there, create one */
+ File f = new File(path);
+ if (!f.exists()) {
+ f.createNewFile();
+ }
+ } catch (Exception e) {
+ }
+
+
+ return new FileConfigStore(path);
+ }
+
+ public IArgBlock createArgBlock() {
+ return new ArgBlock();
+ }
+
+ public IArgBlock createArgBlock(Hashtable httpReq) {
+ return new ArgBlock(httpReq);
+ }
+
+ public IArgBlock createArgBlock(String realm, Hashtable httpReq) {
+ return new ArgBlock(realm, httpReq);
+ }
+
+ public boolean isPreOpMode() {
+ if (getCSState() == CMS.PRE_OP_MODE)
+ return true;
+ return false;
+ }
+
+ public boolean isRunningMode() {
+ if (getCSState() == CMS.RUNNING_MODE)
+ return true;
+ return false;
+ }
+
+ public void setCSState(int mode) {
+ mConfig.putInteger("cs.state", mode);
+ }
+
+ public int getCSState() {
+ int mode = 0;
+ try {
+ mode = mConfig.getInteger("cs.state");
+ } catch (Exception e) {
+ }
+ return mode;
+ }
+
+ public IRepositoryRecord createRepositoryRecord() {
+ return new RepositoryRecord();
+ }
+
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(String
+ id, BigInteger crlNumber, Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return new CRLIssuingPointRecord(id, crlNumber, crlSize, thisUpdate, nextUpdate);
+ }
+
+ public ISecurityDomainSessionTable getSecurityDomainSessionTable() {
+ return mSecurityDomainSessionTable;
+ }
+
+ public String getCRLIssuingPointRecordName() {
+ return CRLIssuingPointRecord.class.getName();
+ }
+
+ public String getEEHost() {
+ String host = "";
+ try {
+ host = mConfig.getString("machineName");
+ } catch (Exception e) {
+ }
+ return host;
+ }
+
+ public String getEENonSSLHost() {
+ String host = "";
+ try {
+ host = mConfig.getString("machineName");
+ } catch (Exception e) {
+ }
+ return host;
+ }
+
+ public String getEENonSSLIP() {
+ return info[EE_NON_SSL][IP];
+ }
+
+ public String getEENonSSLPort() {
+ return info[EE_NON_SSL][PORT];
+ }
+
+ public String getEESSLHost() {
+ String host = "";
+ try {
+ host = mConfig.getString("machineName");
+ } catch (Exception e) {
+ }
+ return host;
+ }
+
+ public String getEESSLIP() {
+ return info[EE_SSL][IP];
+ }
+
+ public String getEESSLPort() {
+ return info[EE_SSL][PORT];
+ }
+
+ public String getEEClientAuthSSLPort() {
+ return info[EE_CLIENT_AUTH_SSL][PORT];
+ }
+
+ public String getAgentHost() {
+ String host = "";
+ try {
+ host = mConfig.getString("machineName");
+ } catch (Exception e) {
+ }
+ return host;
+ }
+
+ public String getAgentIP() {
+ return info[AGENT][IP];
+ }
+
+ public String getAgentPort() {
+ return info[AGENT][PORT];
+ }
+
+ public String getAdminHost() {
+ String host = "";
+ try {
+ host = mConfig.getString("machineName");
+ } catch (Exception e) {
+ }
+ return host;
+ }
+
+ public String getAdminIP() {
+ return info[ADMIN][IP];
+ }
+
+ public String getAdminPort() {
+ return info[ADMIN][PORT];
+ }
+
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory) {
+ return new HttpConnection(authority, factory);
+ }
+
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority,
+ ISocketFactory factory, int timeout) {
+ return new HttpConnection(authority, factory, timeout);
+ }
+
+ public IResender getResender(IAuthority authority, String nickname,
+ IRemoteAuthority remote, int interval) {
+ return new Resender(authority, nickname, remote, interval);
+ }
+
+ public IPKIMessage getHttpPKIMessage() {
+ return new HttpPKIMessage();
+ }
+
+ public ILdapConnInfo getLdapConnInfo(IConfigStore config)
+ throws EBaseException, ELdapException {
+ return new LdapConnInfo(config);
+ }
+
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory(
+ String certNickname) {
+ return new LdapJssSSLSocketFactory(certNickname);
+ }
+
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory() {
+ return new LdapJssSSLSocketFactory();
+ }
+
+ public ILdapAuthInfo getLdapAuthInfo() {
+ return new LdapAuthInfo();
+ }
+
+ public ILdapConnFactory getLdapBoundConnFactory()
+ throws ELdapException {
+ return new LdapBoundConnFactory();
+ }
+
+ public ILdapConnFactory getLdapAnonConnFactory()
+ throws ELdapException {
+ return new LdapAnonConnFactory();
+ }
+
+ public IRequestEncoder getHttpRequestEncoder() {
+ return new HttpRequestEncoder();
+ }
+
+ public Enumeration getSubsystemNames() {
+ return mSSReg.keys();
+ }
+
+ public Enumeration getSubsystems() {
+ return mSSReg.elements();
+ }
+
+ public ISubsystem getSubsystem(String name) {
+ return (ISubsystem) mSSReg.get(name);
+ }
+
+ /**
+ * initialize an array of subsystem info.
+ */
+ private void initSubsystems(SubsystemInfo[] sslist, boolean doSetId)
+ throws EBaseException {
+ if (sslist == null)
+ return;
+ for (int i = 0; i < sslist.length; i++) {
+ initSubsystem(sslist[i], doSetId);
+ }
+ }
+
+ /**
+ * load dynamic subsystems
+ */
+ private void loadDynSubsystems()
+ throws EBaseException {
+ IConfigStore ssconfig = mConfig.getSubStore(PROP_SUBSYSTEM);
+
+ // count number of dyn loaded subsystems.
+ Enumeration ssnames = ssconfig.getSubStoreNames();
+ int nsubsystems = 0;
+
+ for (nsubsystems = 0; ssnames.hasMoreElements(); nsubsystems++)
+ ssnames.nextElement();
+ if (Debug.ON) {
+ Debug.trace(nsubsystems + " dyn subsystems loading..");
+ }
+ if (nsubsystems == 0)
+ return;
+
+ // load dyn subsystems.
+ mDynSubsystems = new SubsystemInfo[nsubsystems];
+ ssnames = ssconfig.getSubStoreNames();
+ for (int i = 0; i < mDynSubsystems.length; i++) {
+ IConfigStore config =
+ ssconfig.getSubStore(String.valueOf(i));
+ String id = config.getString(PROP_ID);
+ String classname = config.getString(PROP_CLASS);
+ ISubsystem ss = null;
+
+ try {
+ ss = (ISubsystem) Class.forName(classname).newInstance();
+ } catch (InstantiationException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_LOAD_FAILED_1", id, e.toString()));
+ } catch (IllegalAccessException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_LOAD_FAILED_1", id, e.toString()));
+ } catch (ClassNotFoundException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_LOAD_FAILED_1", id, e.toString()));
+ }
+ mDynSubsystems[i] = new SubsystemInfo(id, ss);
+ Debug.trace("loaded dyn subsystem " + id);
+ }
+ }
+
+ public LDAPConnection getBoundConnection(String host, int port,
+ int version, LDAPSSLSocketFactoryExt fac, String bindDN,
+ String bindPW) throws LDAPException
+ {
+ return new LdapBoundConnection(host, port, version, fac,
+ bindDN, bindPW);
+ }
+
+ /**
+ * initialize a subsystem
+ */
+ private void initSubsystem(SubsystemInfo ssinfo, boolean doSetId)
+ throws EBaseException {
+ String id = ssinfo.mId;
+ ISubsystem ss = ssinfo.mInstance;
+ IConfigStore ssConfig = mConfig.getSubStore(id);
+
+ CMS.debug("CMSEngine: initSubsystem id=" + id);
+ if (doSetId)
+ ss.setId(id);
+ CMS.debug("CMSEngine: ready to init id=" + id);
+ ss.init(this, ssConfig);
+ // add to id - subsystem hash table.
+ CMS.debug("CMSEngine: done init id=" + id);
+ mSSReg.put(id, ss);
+ CMS.debug("CMSEngine: initialized " + id);
+
+ if(id.equals("ca") || id.equals("ocsp") ||
+ id.equals("kra") || id.equals("tks")) {
+ CMS.debug("CMSEngine::initSubsystem " + id + " Java subsytem about to calculate serverCertNickname. ");
+ // get SSL server nickname
+ IConfigStore serverCertStore = mConfig.getSubStore(id + "." + "sslserver");
+ if (serverCertStore != null && serverCertStore.size() > 0) {
+ String nickName = serverCertStore.getString("nickname");
+ String tokenName = serverCertStore.getString("tokenname");
+ if (tokenName != null && tokenName.length() > 0 &&
+ nickName != null && nickName.length() > 0) {
+ CMS.setServerCertNickname(tokenName, nickName);
+ CMS.debug("Subsystem " + id + " init sslserver: tokenName:"+tokenName+" nickName:"+nickName);
+ } else if (nickName != null && nickName.length() > 0) {
+ CMS.setServerCertNickname(nickName);
+ CMS.debug("Subsystem " + id + " init sslserver: nickName:"+nickName);
+ } else {
+ CMS.debug("Subsystem " + id + " init error: SSL server certificate nickname is not available.");
+ }
+ }
+ }
+ }
+
+ public void reinit(String id) throws EBaseException {
+ ISubsystem system = getSubsystem(id);
+ IConfigStore cs = mConfig.getSubStore(id);
+ system.init(this, cs);
+ }
+
+ /**
+ * Starts up all subsystems. subsystems must be initialized.
+ * @exception EBaseException if any subsystem fails to startup.
+ */
+ public void startup() throws EBaseException {
+ //OsSubsystem.nativeExit(0);
+ startupSubsystems(mStaticSubsystems);
+ if (mDynSubsystems != null)
+ startupSubsystems(mDynSubsystems);
+ startupSubsystems(mFinalSubsystems);
+
+ // global admin servlet. (anywhere else more fit for this ?)
+
+ mStartupTime = System.currentTimeMillis();
+
+ mQueue.removeLogEventListener(mWarningListener);
+ if (!mWarning.toString().equals("")) {
+ System.out.println(Constants.SERVER_STARTUP_WARNING_MESSAGE + mWarning);
+ }
+
+ // check serial number ranges if a CA/KRA
+ ICertificateAuthority ca = (ICertificateAuthority) getSubsystem("ca");
+ if ((ca != null) && !isPreOpMode()) {
+ CMS.debug("CMSEngine: checking request serial number ranges for the CA");
+ ca.getRequestQueue().getRequestRepository().checkRanges();
+
+ CMS.debug("CMSEngine: checking certificate serial number ranges");
+ ca.getCertificateRepository().checkRanges();
+ }
+
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority) getSubsystem("kra");
+ if ((kra != null) && !isPreOpMode()) {
+ CMS.debug("CMSEngine: checking request serial number ranges for the KRA");
+ kra.getRequestQueue().getRequestRepository().checkRanges();
+
+ CMS.debug("CMSEngine: checking key serial number ranges");
+ kra.getKeyRepository().checkRanges();
+ }
+
+ /*LogDoc
+ *
+ * @phase server startup
+ * @reason all subsystems are initialized and started.
+ */
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN,
+ ILogger.LL_INFO, CMS.getLogMessage("SERVER_STARTUP"));
+ System.out.println(Constants.SERVER_STARTUP_MESSAGE);
+ isStarted = true;
+
+ }
+
+ public boolean isInRunningState() {
+ return isStarted;
+ }
+
+ public byte[] getPKCS7(Locale locale, IRequest req) {
+ try {
+ X509CertImpl cert = req.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null)
+ return null;
+
+ ICertificateAuthority ca = (ICertificateAuthority)
+ CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) cacerts[n];
+ }
+
+ userChain[0] = cert;
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ return bos.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public String getServerCertNickname() {
+ return mServerCertNickname;
+ }
+
+ public void setServerCertNickname(String tokenName, String
+ nickName) {
+ String newName = null;
+
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME) ||
+ tokenName.equalsIgnoreCase("Internal Key Storage Token"))
+ newName = nickName;
+ else {
+ if (tokenName.equals("") && nickName.equals(""))
+ return; // not sure the logic
+ else
+ newName = tokenName + ":" + nickName;
+ }
+ setServerCertNickname(newName);
+ }
+
+ public void setServerCertNickname(String newName) {
+ // modify server.xml
+/*
+ String filePrefix = instanceDir + File.separator +
+ "config" + File.separator;
+ String orig = filePrefix + "server.xml";
+ String dest = filePrefix + "server.xml.bak";
+ String newF = filePrefix + "server.xml.new";
+
+ // save the old copy
+ Utils.copy(orig, dest);
+
+ BufferedReader in1 = null;
+ PrintWriter out1 = null;
+
+ try {
+ in1 = new BufferedReader(new FileReader(dest));
+ out1 = new PrintWriter(
+ new BufferedWriter(new FileWriter(newF)));
+ String line = "";
+
+ while (in1.ready()) {
+ line = in1.readLine();
+ if (line != null)
+ out1.println(lineParsing(line, newName));
+ }
+
+ out1.close();
+ in1.close();
+ } catch (Exception eee) {
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", eee.toString()));
+ }
+
+ File file = new File(newF);
+ File nfile = new File(orig);
+
+ try {
+ boolean success = file.renameTo(nfile);
+
+ if (!success) {
+ if (Utils.isNT()) {
+ // NT is very picky on the path
+ Utils.exec("copy " +
+ file.getAbsolutePath().replace('/', '\\') + " " +
+ nfile.getAbsolutePath().replace('/', '\\'));
+ } else {
+ Utils.exec("cp " + file.getAbsolutePath() + " " +
+ nfile.getAbsolutePath());
+ }
+ }
+ } catch (Exception exx) {
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN,
+ ILogger.LL_FAILURE, "CMSEngine: Error " + exx.toString());
+ }
+ // update "cache" for CMS.getServerCertNickname()
+*/
+ mServerCertNickname = newName;
+ }
+
+ private String lineParsing(String input, String newName) {
+ //<SSLPARAMS servercertnickname="Server-Cert cert-firefly"
+ int index = input.indexOf("servercertnickname");
+
+ if (index >= 0) {
+ String str = input.substring(index + 20);
+ int index2 = str.indexOf("\"");
+ String newLine = input.substring(0, index + 20)
+ + newName + str.substring(index2);
+
+ return newLine;
+ } else {
+ return input;
+ }
+ }
+
+ public String getFingerPrint(Certificate cert)
+ throws CertificateEncodingException, NoSuchAlgorithmException {
+ return CertUtils.getFingerPrint(cert);
+ }
+
+ public String getFingerPrints(Certificate cert)
+ throws NoSuchAlgorithmException, CertificateEncodingException {
+ return CertUtils.getFingerPrints(cert);
+ }
+
+ public String getFingerPrints(byte[] certDer)
+ throws NoSuchAlgorithmException {
+ return CertUtils.getFingerPrints(certDer);
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String params[]) {
+ // if locale is null, try to get it out from session context
+ if (locale == null) {
+ SessionContext sc = SessionContext.getExistingContext();
+
+ if (sc != null)
+ locale = (Locale) sc.get(SessionContext.LOCALE);
+ }
+ ResourceBundle rb = null;
+
+ if (locale == null) {
+ rb = ResourceBundle.getBundle(
+ "UserMessages", Locale.ENGLISH);
+ } else {
+ rb = ResourceBundle.getBundle(
+ "UserMessages", locale);
+ }
+ String msg = rb.getString(msgID);
+
+ if (params == null)
+ return msg;
+ MessageFormat mf = new MessageFormat(msg);
+
+ return mf.format(params);
+ }
+
+ public String getUserMessage(Locale locale, String msgID) {
+ return getUserMessage(locale, msgID, (String[]) null);
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p1) {
+ String params[] = { p1 };
+
+ return getUserMessage(locale, msgID, params);
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p1, String p2) {
+ String params[] = { p1, p2 };
+
+ return getUserMessage(locale, msgID, params);
+ }
+
+ public String getUserMessage(Locale locale, String msgID,
+ String p1, String p2, String p3) {
+ String params[] = { p1, p2, p3 };
+
+ return getUserMessage(locale, msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String params[]) {
+ ResourceBundle rb = ResourceBundle.getBundle(
+ "LogMessages");
+ String msg = rb.getString(msgID);
+
+ if (params == null)
+ return msg;
+ MessageFormat mf = new MessageFormat(msg);
+
+ return mf.format(params);
+ }
+
+ public void debug(byte data[]) {
+ if (!debugOn()) {
+ // this helps to not saving stuff to file when debug
+ // is disable
+ return;
+ }
+ Debug.print(data);
+ }
+
+ public void debug(int level, String msg) {
+ if (!debugOn()) {
+ // this helps to not saving stuff to file when debug
+ // is disable
+ return;
+ }
+ Debug.trace(level, msg);
+ }
+
+ public void debug(String msg) {
+ if (!debugOn()) {
+ // this helps to not saving stuff to file when debug
+ // is disable
+ return;
+ }
+ Debug.trace(msg);
+ }
+
+ public void debug(Throwable e) {
+ if (!debugOn()) {
+ // this helps to not saving stuff to file when debug
+ // is disable
+ return;
+ }
+ Debug.printStackTrace(e);
+ }
+
+ public boolean debugOn() {
+ return Debug.on();
+ }
+
+ public void debugStackTrace() {
+ Debug.printStackTrace();
+ }
+
+ public void traceHashKey(String type, String key) {
+ Debug.traceHashKey(type, key);
+ }
+ public void traceHashKey(String type, String key, String val) {
+ Debug.traceHashKey(type, key, val);
+ }
+ public void traceHashKey(String type, String key, String val, String def) {
+ Debug.traceHashKey(type, key, val, def);
+ }
+
+
+ public String getLogMessage(String msgID) {
+ return getLogMessage(msgID, (String[]) null);
+ }
+
+ public String getLogMessage(String msgID, String p1) {
+ String params[] = { p1 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2) {
+ String params[] = { p1, p2 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3) {
+ String params[] = { p1, p2, p3 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4) {
+ String params[] = { p1, p2, p3, p4 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5) {
+ String params[] = { p1, p2, p3, p4, p5 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6) {
+ String params[] = { p1, p2, p3, p4, p5, p6 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7) {
+ String params[] = { p1, p2, p3, p4, p5, p6, p7 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8) {
+ String params[] = { p1, p2, p3, p4, p5, p6, p7, p8 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+ String params[] = { p1, p2, p3, p4, p5, p6, p7, p8, p9 };
+
+ return getLogMessage(msgID, params);
+ }
+
+ public void getSubjAltNameConfigDefaultParams(String name,
+ Vector params) {
+ GeneralNameUtil.SubjAltNameGN.getDefaultParams(name, params);
+ }
+
+ public void getSubjAltNameConfigExtendedPluginInfo(String name,
+ Vector params) {
+ GeneralNameUtil.SubjAltNameGN.getExtendedPluginInfo(name, params);
+ }
+
+ public ISubjAltNameConfig createSubjAltNameConfig(String name, IConfigStore config, boolean isValueConfigured) throws EBaseException {
+ return new GeneralNameUtil.SubjAltNameGN(name, config, isValueConfigured);
+ }
+
+ public GeneralName form_GeneralNameAsConstraints(String generalNameChoice, String value) throws EBaseException {
+ return GeneralNameUtil.form_GeneralNameAsConstraints(generalNameChoice, value);
+ }
+
+ public GeneralName form_GeneralName(String generalNameChoice,
+ String value) throws EBaseException {
+ return GeneralNameUtil.form_GeneralName(generalNameChoice, value);
+ }
+
+ public void getGeneralNameConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params) {
+ GeneralNameUtil.GeneralNameConfig.getDefaultParams(name, isValueConfigured, params);
+ }
+
+ public void getGeneralNamesConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector params) {
+ GeneralNameUtil.GeneralNamesConfig.getDefaultParams(name, isValueConfigured, params);
+ }
+
+ public void getGeneralNameConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info) {
+ GeneralNameUtil.GeneralNameConfig.getExtendedPluginInfo(name, isValueConfigured, info);
+ }
+
+ public void getGeneralNamesConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector info) {
+ GeneralNameUtil.GeneralNamesConfig.getExtendedPluginInfo(name, isValueConfigured, info);
+ }
+
+ public IGeneralNamesConfig createGeneralNamesConfig(String name,
+ IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return new GeneralNameUtil.GeneralNamesConfig(name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ public IGeneralNameAsConstraintsConfig createGeneralNameAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return new GeneralNameUtil.GeneralNameAsConstraintsConfig(name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ public IGeneralNamesAsConstraintsConfig createGeneralNamesAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured,
+ boolean isPolicyEnabled) throws EBaseException {
+ return new GeneralNameUtil.GeneralNamesAsConstraintsConfig(name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ public ObjectIdentifier checkOID(String attrName, String value)
+ throws EBaseException {
+ return CertUtils.checkOID(attrName, value);
+ }
+
+ public String BtoA(byte data[]) {
+ return OSUtil.BtoA(data);
+ }
+
+ public byte[] AtoB(String data) {
+ return OSUtil.AtoB(data);
+ }
+
+ public String getEncodedCert(X509Certificate cert) {
+ try {
+ return
+ "-----BEGIN CERTIFICATE-----\n" +
+ CMS.BtoA(cert.getEncoded()) +
+ "\n-----END CERTIFICATE-----\n";
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public boolean verifySystemCerts() {
+ return CertUtils.verifySystemCerts();
+ }
+
+ public boolean verifySystemCertByTag(String tag) {
+ return CertUtils.verifySystemCertByTag(tag);
+ }
+
+ public boolean verifySystemCertByNickname(String nickname, String certificateUsage) {
+ return CertUtils.verifySystemCertByNickname(nickname, certificateUsage);
+ }
+
+ public CertificateUsage getCertificateUsage(String certusage) {
+ return CertUtils.getCertificateUsage(certusage);
+ }
+
+ public boolean isSigningCert(X509Certificate cert) {
+ return CertUtils.isSigningCert((X509CertImpl) cert);
+ }
+
+ public boolean isEncryptionCert(X509Certificate cert) {
+ return CertUtils.isEncryptionCert((X509CertImpl) cert);
+ }
+
+ public X509CertInfo getDefaultX509CertInfo() {
+ return new CertInfo();
+ }
+
+ public IEmailResolverKeys getEmailResolverKeys() {
+ return new EmailResolverKeys();
+ }
+
+ public IEmailResolver getReqCertSANameEmailResolver() {
+ return new ReqCertSANameEmailResolver();
+ }
+
+ public IEmailFormProcessor getEmailFormProcessor() {
+ return new EmailFormProcessor();
+ }
+
+ public IEmailTemplate getEmailTemplate(String path) {
+ return new EmailTemplate(path);
+ }
+
+ public IMailNotification getMailNotification() {
+ try {
+ String className = mConfig.getString("notificationClassName",
+ "com.netscape.cms.notification.MailNotification");
+ IMailNotification notification = (IMailNotification)
+ Class.forName(className).newInstance();
+
+ return notification;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public IPrettyPrintFormat getPrettyPrintFormat(String delimiter) {
+ return new com.netscape.cmscore.cert.PrettyPrintFormat(delimiter);
+ }
+
+ public IExtPrettyPrint getExtPrettyPrint(Extension e, int indent) {
+ return new ExtPrettyPrint(e, indent);
+ }
+
+ public ICertPrettyPrint getCertPrettyPrint(X509Certificate cert) {
+ return new CertPrettyPrint(cert);
+ }
+
+ public ICRLPrettyPrint getCRLPrettyPrint(X509CRL crl) {
+ return new CrlPrettyPrint((X509CRLImpl) crl);
+ }
+
+ public ICRLPrettyPrint getCRLCachePrettyPrint(ICRLIssuingPoint ip) {
+ return new CrlCachePrettyPrint(ip);
+ }
+
+ public IPasswordCheck getPasswordChecker() {
+ try {
+ String className = mConfig.getString("passwordCheckerClass",
+ "com.netscape.cms.password.PasswordChecker");
+ IPasswordCheck check = (IPasswordCheck)
+ Class.forName(className).newInstance();
+
+ return check;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public ILogger getLogger() {
+ return Logger.getLogger();
+ }
+
+ public ILogger getSignedAuditLogger() {
+ return SignedAuditLogger.getLogger();
+ }
+
+ /**
+ * starts up subsystems in a subsystem list..
+ */
+ private void startupSubsystems(SubsystemInfo[] sslist)
+ throws EBaseException {
+ ISubsystem ss = null;
+
+ for (int i = 0; i < sslist.length; i++) {
+ CMS.debug("CMSEngine: " + sslist[i].mId + " startup start");
+ ss = sslist[i].mInstance;
+ ss.startup();
+ CMS.debug("CMSEngine: " + sslist[i].mId + " startup done");
+ }
+ }
+
+ public void disableRequests() {
+ CommandQueue.mShuttingDown = true;
+ }
+
+ public boolean areRequestsDisabled() {
+ return CommandQueue.mShuttingDown;
+ }
+
+ public void terminateRequests() {
+ java.util.Enumeration e = CommandQueue.mCommandQueue.keys();
+
+ while (e.hasMoreElements()) {
+ Object thisRequest = e.nextElement();
+
+ HttpServlet thisServlet = (HttpServlet) CommandQueue.mCommandQueue.get(thisRequest);
+
+ if (thisServlet != null) {
+ CommandQueue.mCommandQueue.remove((Object) thisRequest);
+ thisServlet.destroy();
+ }
+ }
+ }
+ public static boolean isNT() {
+ return (File.separator.equals("\\"));
+ }
+
+ private static void shutdownHttpServer() {
+
+ try {
+ String cmds[] = null;
+ String cmd = "stop-cert";
+ if (isNT()) {
+ // NT
+ cmds = new String[3];
+ cmds[0] = "cmd";
+ cmds[1] = "/c";
+ cmds[2] = instanceDir +"\\" + cmd;
+ } else {
+ // UNIX
+ cmds = new String[3];
+ cmds[0] = "/bin/sh";
+ cmds[1] = "-c";
+ cmds[2] = instanceDir +"/" +cmd;
+ }
+
+ Process process = Runtime.getRuntime().exec(cmds);
+
+
+ process.waitFor();
+
+ BufferedReader pOut = null;
+ String l = null;
+ } catch (Exception e) {
+
+ }
+ } // end shutdownHttpServer
+ /**
+ * Shuts down subsystems in backwards order
+ * exceptions are ignored. process exists at end to force exit.
+ */
+ public void shutdown() {
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN,
+ ILogger.LL_INFO, Constants.SERVER_SHUTDOWN_MESSAGE);
+
+ CMS.debug("CMSEngine.shutdown()");
+
+/*
+ CommandQueue commandQueue = new CommandQueue();
+ Thread t1 = new Thread(commandQueue);
+
+ t1.setDaemon(true);
+ t1.start();
+
+ // wait for command queue to emptied before proceeding to shutting down subsystems
+ Date time = new Date();
+ long startTime = time.getTime();
+ long timeOut = time.getTime();
+
+ while (t1.isAlive() && ((timeOut - startTime) < (60 * 1000))) //wait for 1 minute
+ {
+ try {
+ Thread.currentThread().sleep(5000); // sleep for 5 sec
+ }catch (java.lang.InterruptedException e) {
+ }
+ timeOut = time.getTime();
+ }
+ terminateRequests();
+*/
+
+ shutdownSubsystems(mFinalSubsystems);
+ shutdownSubsystems(mDynSubsystems);
+ shutdownSubsystems(mStaticSubsystems);
+
+ System.exit(0);
+ }
+
+ /**
+ * Shuts down subsystems in backwards order
+ * exceptions are ignored. process exists at end to force exit.
+ * Added extra call to shutdown the web server.
+ */
+
+ public void forceShutdown() {
+
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN,
+ ILogger.LL_INFO, Constants.SERVER_SHUTDOWN_MESSAGE);
+
+ CMS.debug("CMSEngine.forceShutdown()");
+
+ CommandQueue commandQueue = new CommandQueue();
+ Thread t1 = new Thread(commandQueue);
+
+ t1.setDaemon(true);
+ t1.start();
+
+ // wait for command queue to emptied before proceeding to shutting down subsystems
+ Date time = new Date();
+ long startTime = time.getTime();
+ long timeOut = time.getTime();
+
+ while (t1.isAlive() && ((timeOut - startTime) < (60 * 1000))) //wait for 1 minute
+ {
+ try {
+ Thread.currentThread().sleep(5000); // sleep for 5 sec
+ }catch (java.lang.InterruptedException e) {
+ }
+ timeOut = time.getTime();
+ }
+ terminateRequests();
+
+ shutdownSubsystems(mFinalSubsystems);
+ shutdownSubsystems(mDynSubsystems);
+ shutdownSubsystems(mStaticSubsystems);
+ shutdownHttpServer();
+
+ }
+
+ /**
+ * shuts down a subsystem list in reverse order.
+ */
+ private void shutdownSubsystems(SubsystemInfo[] sslist) {
+ if (sslist == null)
+ return;
+
+ for (int i = sslist.length - 1; i >= 0; i--) {
+ if (sslist[i] != null && sslist[i].mInstance != null)
+ {
+ sslist[i].mInstance.shutdown();
+ }
+ }
+ }
+
+ /**
+ * returns the main config store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * get time server started up
+ */
+ public long getStartupTime() {
+ return mStartupTime;
+ }
+
+ public void putPasswordCache(String tag, String pw) {
+ try {
+ PWsdrCache pwc = new PWsdrCache();
+ pwc.addEntry(tag, pw);
+ } catch (EBaseException e) {
+ // intercept this for now -- don't want to change the callers
+ Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SDR_ADD_ERROR", e.toString()));
+ }
+ }
+
+ public PasswordCallback getPasswordCallback() {
+ return new PWCBsdr();
+ }
+
+ public int getpid() {
+ return OsSubsystem.getpid();
+ }
+
+ public Date getCurrentDate() {
+ if (mTimeSource == null) {
+ return new Date();
+ }
+ return mTimeSource.getCurrentDate();
+ }
+
+ public void setConfigSDSessionId(String val) {
+ mConfigSDSessionId = val;
+ }
+
+ public String getConfigSDSessionId() {
+ return mConfigSDSessionId;
+ }
+
+ public static void upgradeConfig(IConfigStore c)
+ throws EBaseException {
+ String version = c.getString("cms.version", "pre4.2");
+
+ if (version.equals("4.22")) {
+ Upgrade.perform422to45(c);
+ }else if (version.equals("4.2")) {
+ // SUPPORT UPGRADE FROM 4.2 to 4.2 (SP2)
+ Upgrade.perform42to422(c);
+ Upgrade.perform422to45(c);
+ } else {
+ // ONLY SUPPORT UPGRADE FROM 4.2 to 4.2 (SP2)
+ /**
+ if (!version.equals("pre4.2"))
+ return;
+
+ Upgrade.perform(c);
+ **/
+ }
+ }
+
+ public ICommandQueue getCommandQueue() {
+ return new CommandQueue();
+ }
+
+ private ICertificateRepository getCertDB() {
+ ICertificateRepository certDB = null;
+
+ try {
+ ICertificateAuthority ca = (ICertificateAuthority)
+ SubsystemRegistry.getInstance().get("ca");
+
+ if (ca != null) {
+ certDB = (ICertificateRepository) ca.getCertificateRepository();
+ }
+ } catch (Exception e) {
+ CMS.debug("CMSEngine: " + CMS.getLogMessage("CMSCORE_AUTH_AGENT_CERT_REPO"));
+ }
+
+ return certDB;
+ }
+
+ private IRequestQueue getReqQueue() {
+ IRequestQueue queue = null;
+
+ try {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ SubsystemRegistry.getInstance().get("ra");
+
+ if (ra != null) {
+ queue = ra.getRequestQueue();
+ }
+
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_REQUEST_QUEUE"));
+ }
+
+ return queue;
+ }
+
+ private VerifiedCerts mVCList = null;
+ private int mVCListSize = 0;
+
+ public void setListOfVerifiedCerts(int size, long interval, long unknownStateInterval) {
+ if (size > 0 && mVCListSize == 0) {
+ mVCListSize = size;
+ mVCList = new VerifiedCerts(size, interval, unknownStateInterval);
+ }
+ }
+
+ public boolean isRevoked(X509Certificate[] certificates) {
+ boolean revoked = false;
+
+ if (certificates != null) {
+ X509CertImpl cert = (X509CertImpl) certificates[0];
+
+ int result = VerifiedCert.UNKNOWN;
+
+ if (mVCList != null) {
+ result = mVCList.check(cert);
+ }
+ if (result != VerifiedCert.REVOKED &&
+ result != VerifiedCert.NOT_REVOKED &&
+ result != VerifiedCert.CHECKED) {
+
+ CertificateRepository certDB = (CertificateRepository) getCertDB();
+
+ if (certDB != null) {
+ try {
+ if (certDB.isCertificateRevoked(cert) != null) {
+ revoked = true;
+ if (mVCList != null)
+ mVCList.update(cert, VerifiedCert.REVOKED);
+ } else {
+ if (mVCList != null)
+ mVCList.update(cert, VerifiedCert.NOT_REVOKED);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_REVO_STATUS"));
+ }
+ } else {
+ IRequestQueue queue = getReqQueue();
+
+ if (queue != null) {
+ IRequest checkRevReq = null;
+
+ try {
+ checkRevReq = queue.newRequest(CertRequestConstants.GETREVOCATIONINFO_REQUEST);
+ checkRevReq.setExtData(IRequest.REQ_TYPE,
+ CertRequestConstants.GETREVOCATIONINFO_REQUEST);
+ checkRevReq.setExtData(IRequest.REQUESTOR_TYPE,
+ IRequest.REQUESTOR_RA);
+
+ X509CertImpl agentCerts[] = new X509CertImpl[certificates.length];
+
+ for (int i = 0; i < certificates.length; i++) {
+ agentCerts[i] = (X509CertImpl) certificates[i];
+ }
+ checkRevReq.setExtData(IRequest.ISSUED_CERTS, agentCerts);
+
+ queue.processRequest(checkRevReq);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_PROCESS_CHECKING"));
+ }
+
+ RequestStatus status = checkRevReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ Enumeration enum1 = checkRevReq.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(IRequest.REVOKED_CERTS)) {
+ revoked = true;
+ if (mVCList != null)
+ mVCList.update(cert, VerifiedCert.REVOKED);
+ }
+ }
+ if (revoked == false) {
+ if (mVCList != null)
+ mVCList.update(cert, VerifiedCert.NOT_REVOKED);
+ }
+
+ } else {
+ if (mVCList != null)
+ mVCList.update(cert, VerifiedCert.CHECKED);
+ }
+ }
+ }
+ } else if (result == VerifiedCert.REVOKED) {
+ revoked = true;
+ }
+ }
+
+ return revoked;
+ }
+
+ private void log(int level, String msg) {
+ Logger.getLogger().log(ILogger.EV_SYSTEM, null,
+ ILogger.S_AUTHENTICATION, level, msg);
+ }
+}
+
+
+class WarningListener implements ILogEventListener {
+ private StringBuffer mSB = null;
+
+ public WarningListener(StringBuffer sb) {
+ mSB = sb;
+ }
+
+ public void log(ILogEvent event) throws ELogException {
+ String str = event.toString();
+
+ // start.cc and restart.cc does not like carriage
+ // return. They are the programs that pass the
+ // log messages to the console
+ str = str.replace('\n', ' ');
+ if (event.getLevel() == ILogger.LL_FAILURE) {
+ mSB.append("FAILURE: " + str + "|");
+ }
+ if (event.getLevel() == ILogger.LL_WARN) {
+ mSB.append("WARNING: " + str + "|");
+ }
+ }
+
+ public void flush() {
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public void startup() {
+ }
+
+ /**
+ * Retrieve last "maxLine" number of system log with log lever >"level"
+ * and from source "source". If the parameter is omitted. All entries
+ * are sent back.
+ */
+ public synchronized NameValuePairs retrieveLogContent(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ /**
+ * Retrieve log file list.
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "ConsoleLog";
+ }
+
+ public String getDescription() {
+ return "ConsoleLog";
+ }
+
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+}
+
+
+class SubsystemInfo {
+ public final String mId;
+ public final ISubsystem mInstance;
+ public SubsystemInfo(String id, ISubsystem ssInstance) {
+ mId = id;
+ mInstance = ssInstance;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/CommandQueue.java b/pki/base/common/src/com/netscape/cmscore/apps/CommandQueue.java
new file mode 100644
index 000000000..638eae082
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/CommandQueue.java
@@ -0,0 +1,98 @@
+// --- 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.cmscore.apps;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.TimeZone;
+import com.netscape.certsrv.apps.*;
+
+
+/*---------------------------------------------------------------
+ ** CommandQueue - Class
+ */
+
+/**
+ * register and unregister proccess for clean shutdown
+ */
+public class CommandQueue implements Runnable, ICommandQueue {
+
+ public static Hashtable mCommandQueue = new Hashtable();
+ public static boolean mShuttingDown = false;
+
+ /*-----------------------------------------------------------
+ ** CommandQueue - Constructor
+ */
+
+ /**
+ * Main constructor.
+ */
+ public CommandQueue() {
+
+ } // CommandQueue
+
+ /*-----------------------------------------------------------
+ ** run
+ */
+
+ /**
+ * Overrides Thread.run(), calls batchPublish().
+ */
+ public void run() {
+ //int priority = Thread.MIN_PRIORITY;
+ //Thread.currentThread().setPriority(priority);
+ /*-------------------------------------------------
+ ** Loop until queue is empty
+ */
+ mShuttingDown = true;
+ while (mCommandQueue.isEmpty() == false) {
+ try {
+ Thread.currentThread().sleep(5 * 1000);
+ //gcProcess();
+ } catch (Exception e) {
+
+ }
+ }
+ } // run
+
+ public boolean registerProcess(Object currentRequest, Object currentServlet) {
+ if (mShuttingDown == false) {
+ if ((currentServlet instanceof com.netscape.cms.servlet.base.CMSStartServlet) == false)
+ mCommandQueue.put(currentRequest, currentServlet);
+ return true;
+ }else
+ return false;
+
+ }
+
+ public void unRegisterProccess(Object currentRequest, Object currentServlet) {
+ java.util.Enumeration e = mCommandQueue.keys();
+
+ while (e.hasMoreElements()) {
+ Object thisRequest = e.nextElement();
+
+ if (thisRequest.equals(currentRequest)) {
+ if (mCommandQueue.get(currentRequest).equals(currentServlet))
+ mCommandQueue.remove(currentRequest);
+ }
+ }
+
+ }
+} // CommandQueue
+
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java b/pki/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java
new file mode 100644
index 000000000..27d2e3f7d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java
@@ -0,0 +1,43 @@
+// --- 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.cmscore.apps;
+
+
+/**
+ * A class represents a PKIServer event.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class PKIServerEvent {
+
+ public final static int INITIALIZED = 0;
+ public final static int STARTED_UP = 1;
+ public final static int STOPPED = 2;
+
+ public int mStatus;
+
+ public PKIServerEvent(int status) {
+ mStatus = status;
+ }
+
+ public int getStatus() {
+ return mStatus;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java b/pki/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java
new file mode 100644
index 000000000..78fe9069f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java
@@ -0,0 +1,36 @@
+// --- 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.cmscore.apps;
+
+
+/**
+ * A class represents a listener that listens to
+ * PKIServer event.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class PKIServerListener {
+
+ /**
+ * Updates listener with the server event.
+ */
+ public void update(PKIServerEvent e) {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/Setup.java b/pki/base/common/src/com/netscape/cmscore/apps/Setup.java
new file mode 100644
index 000000000..21a39ec8f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/Setup.java
@@ -0,0 +1,347 @@
+// --- 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.cmscore.apps;
+
+
+import java.io.File;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.base.EBaseException;
+import netscape.ldap.*;
+import java.io.*;
+
+
+/**
+ * Select certificate server serices.
+ *
+ * @author thomask
+ * @author nicolson
+ * @version $Revision$, $Date$
+ */
+public class Setup {
+
+ // These are a bunch of fixed values that just need to be stored to the
+ // config file before the server is started.
+ public static final String[][] authEntries = new String[][] {
+ {"auths._000", "##"},
+ {"auths._001", "## new authentication"},
+ {"auths._002", "##"},
+ {"auths.impl._000", "##"},
+ {"auths.impl._001", "## authentication manager implementations"},
+ {"auths.impl._002", "##"},
+ {"auths.impl.UidPwdDirAuth.class", "com.netscape.cms.authentication.UidPwdDirAuthentication"},
+ {"auths.impl.UidPwdPinDirAuth.class", "com.netscape.cms.authentication.UidPwdPinDirAuthentication"},
+ {"auths.impl.UdnPwdDirAuth.class", "com.netscape.cms.authentication.UdnPwdDirAuthentication"},
+ {"auths.impl.NISAuth.class", "com.netscape.cms.authentication.NISAuth"},
+ {"auths.impl.CMCAuth.class", "com.netscape.cms.authentication.CMCAuth"},
+ {"auths.impl.AgentCertAuth.class", "com.netscape.cms.authentication.AgentCertAuthentication"},
+ {"auths.impl.PortalEnroll.class", "com.netscape.cms.authentication.PortalEnroll"
+ },
+ {"auths.revocationChecking.bufferSize", "50"},
+ };
+ public static void installAuthImpls(IConfigStore c)
+ throws EBaseException {
+ for (int i = 0; i < authEntries.length; i++) {
+ c.putString(authEntries[i][0], authEntries[i][1]);
+ }
+ }
+
+ public static final String[][] oidmapEntries = new String[][] {
+ {"oidmap.pse.class", "netscape.security.extensions.PresenceServerExtension"},
+ {"oidmap.pse.oid", "2.16.840.1.113730.1.18"},
+ {"oidmap.ocsp_no_check.class", "netscape.security.extensions.OCSPNoCheckExtension"},
+ {"oidmap.ocsp_no_check.oid", "1.3.6.1.5.5.7.48.1.5"},
+ {"oidmap.netscape_comment.class", "netscape.security.x509.NSCCommentExtension"},
+ {"oidmap.netscape_comment.oid", "2.16.840.1.113730.1.13"},
+ {"oidmap.extended_key_usage.class", "netscape.security.extensions.ExtendedKeyUsageExtension"},
+ {"oidmap.extended_key_usage.oid", "2.5.29.37"},
+ {"oidmap.subject_info_access.class", "netscape.security.extensions.SubjectInfoAccessExtension"},
+ {"oidmap.subject_info_access.oid", "1.3.6.1.5.5.7.1.11"},
+ {"oidmap.auth_info_access.class", "netscape.security.extensions.AuthInfoAccessExtension"},
+ {"oidmap.auth_info_access.oid", "1.3.6.1.5.5.7.1.1"},
+ {"oidmap.challenge_password.class", "com.netscape.cms.servlet.cert.scep.ChallengePassword"},
+ {"oidmap.challenge_password.oid", "1.2.840.113549.1.9.7"},
+ {"oidmap.extensions_requested_vsgn.class", "com.netscape.cms.servlet.cert.scep.ExtensionsRequested"},
+ {"oidmap.extensions_requested_vsgn.oid", "2.16.840.1.113733.1.9.8"},
+ {"oidmap.extensions_requested_pkcs9.class", "com.netscape.cms.servlet.cert.scep.ExtensionsRequested"},
+ {"oidmap.extensions_requested_pkcs9.oid", "1.2.840.113549.1.9.14"},
+ };
+
+ public static void installOIDMap(IConfigStore c)
+ throws EBaseException {
+ for (int i = 0; i < oidmapEntries.length; i++) {
+ c.putString(oidmapEntries[i][0], oidmapEntries[i][1]);
+ }
+ }
+
+ /**
+ * This function is used for installation and upgrade.
+ */
+ public static void installPolicyImpls(String prefix, IConfigStore c)
+ throws EBaseException {
+ boolean isCA = false;
+
+ if (prefix.equals("ca"))
+ isCA = true;
+
+ //
+ // Policy implementations (class names)
+ //
+ c.putString(prefix + ".Policy.impl._000", "##");
+ c.putString(prefix + ".Policy.impl._001",
+ "## Policy Implementations");
+ c.putString(prefix + ".Policy.impl._002", "##");
+ c.putString(
+ prefix + ".Policy.impl.KeyAlgorithmConstraints.class",
+ "com.netscape.cmscore.policy.KeyAlgorithmConstraints");
+ c.putString(
+ prefix + ".Policy.impl.DSAKeyConstraints.class",
+ "com.netscape.cmscore.policy.DSAKeyConstraints");
+ c.putString(
+ prefix + ".Policy.impl.RSAKeyConstraints.class",
+ "com.netscape.cmscore.policy.RSAKeyConstraints");
+ c.putString(
+ prefix + ".Policy.impl.SigningAlgorithmConstraints.class",
+ "com.netscape.cmscore.policy.SigningAlgorithmConstraints");
+ c.putString(
+ prefix + ".Policy.impl.ValidityConstraints.class",
+ "com.netscape.cmscore.policy.ValidityConstraints");
+
+ /**
+ c.putString(
+ prefix + ".Policy.impl.NameConstraints.class",
+ "com.netscape.cmscore.policy.NameConstraints");
+ **/
+ c.putString(
+ prefix + ".Policy.impl.RenewalConstraints.class",
+ "com.netscape.cmscore.policy.RenewalConstraints");
+ c.putString(
+ prefix + ".Policy.impl.RenewalValidityConstraints.class",
+ "com.netscape.cmscore.policy.RenewalValidityConstraints");
+ c.putString(
+ prefix + ".Policy.impl.RevocationConstraints.class",
+ "com.netscape.cmscore.policy.RevocationConstraints");
+ //getTempCMSConfig().putString(
+ // prefix + ".Policy.impl.DefaultRevocation.class",
+ // "com.netscape.cmscore.policy.DefaultRevocation");
+ c.putString(
+ prefix + ".Policy.impl.NSCertTypeExt.class",
+ "com.netscape.cmscore.policy.NSCertTypeExt");
+ c.putString(
+ prefix + ".Policy.impl.KeyUsageExt.class",
+ "com.netscape.cmscore.policy.KeyUsageExt");
+ c.putString(
+ prefix + ".Policy.impl.SubjectKeyIdentifierExt.class",
+ "com.netscape.cmscore.policy.SubjectKeyIdentifierExt");
+ c.putString(
+ prefix + ".Policy.impl.CertificatePoliciesExt.class",
+ "com.netscape.cmscore.policy.CertificatePoliciesExt");
+ c.putString(
+ prefix + ".Policy.impl.NSCCommentExt.class",
+ "com.netscape.cmscore.policy.NSCCommentExt");
+ c.putString(
+ prefix + ".Policy.impl.IssuerAltNameExt.class",
+ "com.netscape.cmscore.policy.IssuerAltNameExt");
+ c.putString(
+ prefix + ".Policy.impl.PrivateKeyUsagePeriodExt.class",
+ "com.netscape.cmscore.policy.PrivateKeyUsagePeriodExt");
+ c.putString(
+ prefix + ".Policy.impl.AttributePresentConstraints.class",
+ "com.netscape.cmscore.policy.AttributePresentConstraints");
+ c.putString(
+ prefix + ".Policy.impl.SubjectAltNameExt.class",
+ "com.netscape.cmscore.policy.SubjectAltNameExt");
+ c.putString(
+ prefix + ".Policy.impl.SubjectDirectoryAttributesExt.class",
+ "com.netscape.cmscore.policy.SubjectDirectoryAttributesExt");
+ c.putString(
+ prefix + ".Policy.impl.CertificateRenewalWindowExt.class",
+ "com.netscape.cmscore.policy.CertificateRenewalWindowExt");
+ c.putString(
+ prefix + ".Policy.impl.CertificateScopeOfUseExt.class",
+ "com.netscape.cmscore.policy.CertificateScopeOfUseExt");
+ if (isCA) {
+ c.putString(
+ prefix + ".Policy.impl.AuthorityKeyIdentifierExt.class",
+ "com.netscape.cmscore.policy.AuthorityKeyIdentifierExt");
+ c.putString(
+ prefix + ".Policy.impl.BasicConstraintsExt.class",
+ "com.netscape.cmscore.policy.BasicConstraintsExt");
+ c.putString(
+ prefix + ".Policy.impl.SubCANameConstraints.class",
+ "com.netscape.cmscore.policy.SubCANameConstraints");
+ }
+ c.putString(
+ prefix + ".Policy.impl.CRLDistributionPointsExt.class",
+ "com.netscape.cmscore.policy.CRLDistributionPointsExt");
+ c.putString(
+ prefix + ".Policy.impl.AuthInfoAccessExt.class",
+ "com.netscape.cmscore.policy.AuthInfoAccessExt");
+ c.putString(
+ prefix + ".Policy.impl.OCSPNoCheckExt.class",
+ "com.netscape.cmscore.policy.OCSPNoCheckExt");
+ c.putString(
+ prefix + ".Policy.impl.ExtendedKeyUsageExt.class",
+ "com.netscape.cmscore.policy.ExtendedKeyUsageExt");
+ if (isCA) {
+ c.putString(
+ prefix + ".Policy.impl.UniqueSubjectNameConstraints.class",
+ "com.netscape.cmscore.policy.UniqueSubjectNameConstraints");
+ }
+ c.putString(
+ prefix + ".Policy.impl.GenericASN1Ext.class",
+ "com.netscape.cmscore.policy.GenericASN1Ext");
+ c.putString(
+ prefix + ".Policy.impl.RemoveBasicConstraintsExt.class",
+ "com.netscape.cmscore.policy.RemoveBasicConstraintsExt");
+ }
+
+ /**
+ * This function is used for installation and upgrade.
+ */
+ public static void installCACRLExtensions(IConfigStore c)
+ throws EBaseException {
+ // ca crl extensions
+
+ // AuthorityKeyIdentifier
+ c.putString("ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.enable",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.critical",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.type",
+ "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.class",
+ "com.netscape.cms.crl.CMSAuthorityKeyIdentifierExtension");
+
+ // IssuerAlternativeName
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.enable",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.critical",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.type",
+ "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.class",
+ "com.netscape.cms.crl.CMSIssuerAlternativeNameExtension");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.numNames", "0");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.nameType0", "");
+ c.putString("ca.crl.MasterCRL.extension.IssuerAlternativeName.name0", "");
+
+ // CRLNumber
+ c.putString("ca.crl.MasterCRL.extension.CRLNumber.enable", "true");
+ c.putString("ca.crl.MasterCRL.extension.CRLNumber.critical", "false");
+ c.putString("ca.crl.MasterCRL.extension.CRLNumber.type", "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.CRLNumber.class",
+ "com.netscape.cms.crl.CMSCRLNumberExtension");
+
+ // DeltaCRLIndicator
+ c.putString("ca.crl.MasterCRL.extension.DeltaCRLIndicator.enable", "false");
+ c.putString("ca.crl.MasterCRL.extension.DeltaCRLIndicator.critical", "true");
+ c.putString("ca.crl.MasterCRL.extension.DeltaCRLIndicator.type", "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.DeltaCRLIndicator.class",
+ "com.netscape.cms.crl.CMSDeltaCRLIndicatorExtension");
+
+ // IssuingDistributionPoint
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.enable",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.critical",
+ "true");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.type",
+ "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.class",
+ "com.netscape.cms.crl.CMSIssuingDistributionPointExtension");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.pointType", "");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.pointName", "");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlyContainsUserCerts",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlyContainsCACerts",
+ "false");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlySomeReasons", "");
+ //"keyCompromise,cACompromise,affiliationChanged,superseded,cessationOfOperation,certificateHold");
+ c.putString("ca.crl.MasterCRL.extension.IssuingDistributionPoint.indirectCRL",
+ "false");
+
+ // CRLReason
+ c.putString("ca.crl.MasterCRL.extension.CRLReason.enable", "true");
+ c.putString("ca.crl.MasterCRL.extension.CRLReason.critical", "false");
+ c.putString("ca.crl.MasterCRL.extension.CRLReason.type", "CRLEntryExtension");
+ c.putString("ca.crl.MasterCRL.extension.CRLReason.class",
+ "com.netscape.cms.crl.CMSCRLReasonExtension");
+
+ // HoldInstruction
+ c.putString("ca.crl.MasterCRL.extension.HoldInstruction.enable", "false");
+ c.putString("ca.crl.MasterCRL.extension.HoldInstruction.critical", "false");
+ c.putString("ca.crl.MasterCRL.extension.HoldInstruction.type", "CRLEntryExtension");
+ c.putString("ca.crl.MasterCRL.extension.HoldInstruction.class",
+ "com.netscape.cms.crl.CMSHoldInstructionExtension");
+ c.putString("ca.crl.MasterCRL.extension.HoldInstruction.instruction", "none");
+
+ // InvalidityDate
+ c.putString("ca.crl.MasterCRL.extension.InvalidityDate.enable", "true");
+ c.putString("ca.crl.MasterCRL.extension.InvalidityDate.critical", "false");
+ c.putString("ca.crl.MasterCRL.extension.InvalidityDate.type", "CRLEntryExtension");
+ c.putString("ca.crl.MasterCRL.extension.InvalidityDate.class",
+ "com.netscape.cms.crl.CMSInvalidityDateExtension");
+
+ // CertificateIssuer
+ /*
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.enable", "false");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.critical", "true");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.type", "CRLEntryExtension");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.class",
+ "com.netscape.cms.crl.CMSCertificateIssuerExtension");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.numNames", "0");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.nameType0", "");
+ c.putString("ca.crl.MasterCRL.extension.CertificateIssuer.name0", "");
+ */
+
+ // FreshestCRL
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.enable", "false");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.critical", "false");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.type", "CRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.class",
+ "com.netscape.cms.crl.CMSFreshestCRLExtension");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.numPoints", "0");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.pointType0", "");
+ c.putString("ca.crl.MasterCRL.extension.FreshestCRL.pointName0", "");
+ }
+
+ public static void installCAPublishingImpls(IConfigStore c)
+ throws EBaseException {
+ for (int i = 0; i < caLdappublishImplsEntries.length; i++) {
+ c.putString(
+ caLdappublishImplsEntries[i][0], caLdappublishImplsEntries[i][1]);
+ }
+ }
+
+ private static final String[][] caLdappublishImplsEntries = new String[][] {
+ {"ca.publish.mapper.impl.LdapCaSimpleMap.class", "com.netscape.cms.publish.LdapCaSimpleMap"},
+ {"ca.publish.mapper.impl.LdapSimpleMap.class", "com.netscape.cms.publish.LdapSimpleMap"},
+ {"ca.publish.mapper.impl.LdapEnhancedMap.class", "com.netscape.cms.publish.LdapEnhancedMap"},
+ {"ca.publish.mapper.impl.LdapDNCompsMap.class", "com.netscape.cms.publish.LdapCertCompsMap"},
+ {"ca.publish.mapper.impl.LdapSubjAttrMap.class", "com.netscape.cms.publish.LdapCertSubjMap"},
+ {"ca.publish.mapper.impl.LdapDNExactMap.class", "com.netscape.cms.publish.LdapCertExactMap"},
+ //{"ca.publish.mapper.impl.LdapCrlIssuerCompsMap.class","com.netscape.cms.publish.LdapCrlIssuerCompsMap"},
+ {"ca.publish.publisher.impl.LdapUserCertPublisher.class", "com.netscape.cms.publish.LdapUserCertPublisher"},
+ {"ca.publish.publisher.impl.LdapCaCertPublisher.class", "com.netscape.cms.publish.LdapCaCertPublisher"},
+ {"ca.publish.publisher.impl.LdapCrlPublisher.class", "com.netscape.cms.publish.LdapCrlPublisher"},
+ {"ca.publish.publisher.impl.FileBasedPublisher.class", "com.netscape.cms.publish.FileBasedPublisher"},
+ {"ca.publish.publisher.impl.OCSPPublisher.class", "com.netscape.cms.publish.OCSPPublisher"},
+ {"ca.publish.rule.impl.Rule.class", "com.netscape.cmscore.ldap.LdapRule"},
+ };
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/apps/Upgrade.java b/pki/base/common/src/com/netscape/cmscore/apps/Upgrade.java
new file mode 100644
index 000000000..f04eb1869
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/apps/Upgrade.java
@@ -0,0 +1,339 @@
+// --- 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.cmscore.apps;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.cmscore.util.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import java.io.File;
+import java.lang.*;
+
+
+public final class Upgrade {
+ public static void perform422to45(IConfigStore c)
+ throws EBaseException {
+ jss3(c);
+ c.putInteger("agentGateway.https.timeout", 120);
+ IConfigStore cs = c.getSubStore("ca");
+
+ if (cs != null && cs.size() > 0) {
+ c.putString("ca.publish.mapper.impl.LdapEnhancedMap.class",
+ "com.netscape.certsrv.ldap.LdapEnhancedMap");
+ }
+ c.putString("cms.version", "4.5");
+ c.commit(false);
+ }
+
+ public static void perform42to422(IConfigStore c)
+ throws EBaseException {
+ // upgrade CMS's configuration parameters
+ c.putString("eeGateway.dynamicVariables",
+ "serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl()");
+
+ // new OCSP Publisher implemention
+ c.putString("ra.publish.publisher.impl.OCSPPublisher.class",
+ "com.netscape.certsrv.ldap.OCSPPublisher");
+ c.putString("ca.publish.publisher.impl.OCSPPublisher.class",
+ "com.netscape.certsrv.ldap.OCSPPublisher");
+
+ // new logging framework
+ c.putString("log.impl.file.class",
+ "com.netscape.certsrv.logging.RollingLogFile");
+
+ c.putString("log.instance.Audit.bufferSize",
+ c.getString("logAudit.bufferSize"));
+ c.putString("log.instance.Audit.enable",
+ c.getString("logAudit.on"));
+ // This feature doesnot work in the previous release
+ // But it works now. I don't want people to have their
+ // logs auto deleted without notice.It's dangerous.
+ c.putString("log.instance.Audit.expirationTime",
+ "0"); //Specifically turn it off.
+ // c.getString("logAudit.expirationTime"));
+ c.putString("log.instance.Audit.fileName",
+ c.getString("logAudit.fileName"));
+ c.putString("log.instance.Audit.flushInterval",
+ c.getString("logAudit.flushInterval"));
+ c.putString("log.instance.Audit.level",
+ c.getString("logAudit.level"));
+ c.putString("log.instance.Audit.maxFileSize",
+ c.getString("logAudit.maxFileSize"));
+ c.putString("log.instance.Audit.pluginName",
+ "file");
+ c.putString("log.instance.Audit.rolloverInterval",
+ c.getString("logAudit.rolloverInterval"));
+ c.putString("log.instance.Audit.type",
+ "audit");
+
+ c.putString("log.instance.Error.bufferSize",
+ c.getString("logError.bufferSize"));
+ c.putString("log.instance.Error.enable",
+ c.getString("logError.on"));
+ c.putString("log.instance.Error.expirationTime",
+ "0"); //Specifically turn it off.
+ // c.getString("logError.expirationTime"));
+ c.putString("log.instance.Error.fileName",
+ c.getString("logError.fileName"));
+ c.putString("log.instance.Error.flushInterval",
+ c.getString("logError.flushInterval"));
+ c.putString("log.instance.Error.level",
+ c.getString("logError.level"));
+ c.putString("log.instance.Error.maxFileSize",
+ c.getString("logError.maxFileSize"));
+ c.putString("log.instance.Error.pluginName",
+ "file");
+ c.putString("log.instance.Error.rolloverInterval",
+ c.getString("logError.rolloverInterval"));
+ c.putString("log.instance.Error.type",
+ "system");
+
+ c.putString("log.instance.System.bufferSize",
+ c.getString("logSystem.bufferSize"));
+ c.putString("log.instance.System.enable",
+ c.getString("logSystem.on"));
+ c.putString("log.instance.System.expirationTime",
+ "0"); //Specifically turn it off.
+ // c.getString("logSystem.expirationTime"));
+ c.putString("log.instance.System.fileName",
+ c.getString("logSystem.fileName"));
+ c.putString("log.instance.System.flushInterval",
+ c.getString("logSystem.flushInterval"));
+ c.putString("log.instance.System.level",
+ c.getString("logSystem.level"));
+ c.putString("log.instance.System.maxFileSize",
+ c.getString("logSystem.maxFileSize"));
+ c.putString("log.instance.System.pluginName",
+ "file");
+ c.putString("log.instance.System.rolloverInterval",
+ c.getString("logSystem.rolloverInterval"));
+ c.putString("log.instance.System.type",
+ "system");
+
+ if (!OsSubsystem.isUnix()) {
+ c.putString("log.impl.NTEventLog.class",
+ "com.netscape.certsrv.logging.NTEventLog");
+
+ c.putString("log.instance.NTAudit.NTEventSourceName",
+ c.getString("logNTAudit.NTEventSourceName"));
+ c.putString("log.instance.NTAudit.enable",
+ c.getString("logNTAudit.on"));
+ c.putString("log.instance.NTAudit.level",
+ c.getString("logNTAudit.level"));
+ c.putString("log.instance.NTAudit.pluginName",
+ "NTEventLog");
+ c.putString("log.instance.NTAudit.type",
+ "system");
+
+ c.putString("log.instance.NTSystem.NTEventSourceName",
+ c.getString("logNTSystem.NTEventSourceName"));
+ c.putString("log.instance.NTSystem.enable",
+ c.getString("logNTSystem.on"));
+ c.putString("log.instance.NTSystem.level",
+ c.getString("logNTSystem.level"));
+ c.putString("log.instance.NTSystem.pluginName",
+ "NTEventLog");
+ c.putString("log.instance.NTSystem.type",
+ "system");
+ }
+ c.putString("cms.version", "4.22");
+ c.commit(false);
+ }
+
+ /**
+ * This method handles pre4.2 -> 4.2 configuration
+ * upgrade.
+ */
+ public static void perform(IConfigStore c)
+ throws EBaseException {
+ boolean isCA = false;
+ boolean isRA = false;
+ boolean isKRA = false;
+
+ // determine what subsystems do we have?
+ IConfigStore cs = c.getSubStore("ca");
+
+ if (cs != null && cs.size() > 0) {
+ isCA = true;
+ }
+ cs = c.getSubStore("ra");
+ if (cs != null && cs.size() > 0) {
+ isRA = true;
+ }
+ cs = c.getSubStore("kra");
+ if (cs != null && cs.size() > 0) {
+ isKRA = true;
+ }
+
+ Setup.installAuthImpls(c);
+ Setup.installOIDMap(c);
+
+ // start upgrade processing
+ if (isCA) {
+ Setup.installPolicyImpls("ca", c);
+ Setup.installCACRLExtensions(c);
+ Setup.installCAPublishingImpls(c);
+ caPublishing(c);
+ }
+
+ if (isRA) {
+ Setup.installPolicyImpls("ra", c);
+ }
+
+ c.putString("eeGateway.dynamicVariables",
+ "serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs()");
+
+ c.putString("cms.version", "4.2");
+ // Assumed user backups (including CMS.cfg) the system before
+ // upgrading
+ c.commit(false);
+ }
+
+ /**
+ * Upgrade publishing. This function upgrades both enabled
+ * or disabled publishing configuration.
+ */
+ public static void caPublishing(IConfigStore c)
+ throws EBaseException {
+ c.putString("ca.publish.enable",
+ c.getString("ca.enableLdapPublish", "false"));
+ c.putString("ca.publish.ldappublish.enable",
+ c.getString("ca.enableLdapPublish", "false"));
+ c.putString("ca.publish.ldappublish.ldap.ldapauth.authtype",
+ c.getString("ca.ldappublish.ldap.ldapauth.authtype", "BasicAuth"));
+ c.putString("ca.publish.ldappublish.ldap.ldapauth.bindDN",
+ c.getString("ca.ldappublish.ldap.ldapauth.bindDN", ""));
+ c.putString("ca.publish.ldappublish.ldap.ldapauth.bindPWPrompt",
+ c.getString("ca.ldappublish.ldap.ldapauth.bindPWPrompt", "LDAP Publishing"));
+ c.putString("ca.publish.ldappublish.ldap.ldapconn.host",
+ c.getString("ca.ldappublish.ldap.ldapconn.host", ""));
+ c.putString("ca.publish.ldappublish.ldap.ldapconn.port",
+ c.getString("ca.ldappublish.ldap.ldapconn.port", ""));
+ c.putString("ca.publish.ldappublish.ldap.ldapconn.secureConn",
+ c.getString("ca.ldappublish.ldap.ldapconn.secureConn", "false"));
+ c.putString("ca.publish.ldappublish.ldap.ldapconn.version",
+ c.getString("ca.ldappublish.ldap.ldapconn.version", "2"));
+
+ // mappers
+ c.putString("ca.publish.mapper.instance.LdapCaCertMap.pluginName",
+ "LdapDNCompsMap");
+ c.putString("ca.publish.mapper.instance.LdapCaCertMap.dnComps",
+ c.getString("ca.ldappublish.type.ca.mapper.dnComps"));
+ c.putString("ca.publish.mapper.instance.LdapCaCertMap.filterComps",
+ c.getString("ca.ldappublish.type.ca.mapper.filterComps"));
+ c.putString("ca.publish.mapper.instance.LdapCaCertMap.baseDN",
+ c.getString("ca.ldappublish.type.ca.mapper.baseDN"));
+
+ c.putString("ca.publish.mapper.instance.LdapCrlMap.pluginName",
+ "LdapDNCompsMap");
+ c.putString("ca.publish.mapper.instance.LdapCrlMap.dnComps",
+ c.getString("ca.ldappublish.type.crl.mapper.dnComps"));
+ c.putString("ca.publish.mapper.instance.LdapCrlMap.filterComps",
+ c.getString("ca.ldappublish.type.crl.mapper.filterComps"));
+ c.putString("ca.publish.mapper.instance.LdapCrlMap.baseDN",
+ c.getString("ca.ldappublish.type.crl.mapper.baseDN"));
+ c.putString("ca.publish.mapper.instance.LdapUserCertMap.pluginName",
+ "LdapDNCompsMap");
+ c.putString("ca.publish.mapper.instance.LdapUserCertMap.dnComps",
+ c.getString("ca.ldappublish.type.client.mapper.dnComps"));
+ c.putString("ca.publish.mapper.instance.LdapUserCertMap.filterComps",
+ c.getString("ca.ldappublish.type.client.mapper.filterComps"));
+ c.putString("ca.publish.mapper.instance.LdapUserCertMap.baseDN",
+ c.getString("ca.ldappublish.type.client.mapper.baseDN"));
+
+ // publishers
+ c.putString("ca.publish.publisher.instance.LdapCaCertPublisher.caCertAttr", "caCertificate;binary");
+ c.putString("ca.publish.publisher.instance.LdapCaCertPublisher.caObjectClass", "certificationAuthority");
+ c.putString("ca.publish.publisher.instance.LdapCaCertPublisher.pluginName", "LdapCaCertPublisher");
+ c.putString("ca.publish.publisher.instance.LdapCrlPublisher.crlAttr", "certificateRevocationList;binary");
+ c.putString("ca.publish.publisher.instance.LdapCrlPublisher.pluginName", "LdapCrlPublisher");
+ c.putString("ca.publish.publisher.instance.LdapUserCertPublisher.certAttr", "userCertificate;binary");
+ c.putString("ca.publish.publisher.instance.LdapUserCertPublisher.pluginName", "LdapUserCertPublisher");
+
+ // rules
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.pluginName ",
+ "Rule");
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.predicate",
+ "");
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.publisher",
+ "LdapCaCertPublisher");
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.type",
+ "cacert");
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.enable",
+ "true");
+ c.putString("ca.publish.rule.instance.LdapCaCertRule.mapper",
+ "LdapCaCertMap");
+
+ c.putString("ca.publish.rule.instance.LdapCrlRule.pluginName",
+ "Rule");
+ c.putString("ca.publish.rule.instance.LdapCrlRule.predicate", "");
+ c.putString("ca.publish.rule.instance.LdapCrlRule.publisher",
+ "LdapCrlPublisher");
+ c.putString("ca.publish.rule.instance.LdapCrlRule.type", "crl");
+ c.putString("ca.publish.rule.instance.LdapCrlRule.enable", "true");
+ c.putString("ca.publish.rule.instance.LdapCrlRule.mapper",
+ "LdapCrlMap");
+
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.pluginName",
+ "Rule");
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.predicate", "");
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.publisher",
+ "LdapUserCertPublisher");
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.type", "certs");
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.enable", "true");
+ c.putString("ca.publish.rule.instance.LdapUserCertRule.mapper",
+ "LdapUserCertMap");
+
+ c.removeSubStore("ca.ldappublish");
+ }
+
+ /**
+ * Upgrade publishing. This function upgrades both enabled
+ * or disabled publishing configuration.
+ */
+ public static void jss3(IConfigStore c)
+ throws EBaseException {
+ String moddb = c.getString("jss.moddb");
+
+ if (moddb == null) return;
+
+ int i = moddb.lastIndexOf("/");
+ String dir = moddb.substring(0, i);
+ String secmodName = moddb.substring(i + 1);
+ String certdb = c.getString("jss.certdb");
+
+ i = certdb.indexOf("/config/cert7.db");
+ certdb = certdb.substring(0, i);
+ i = certdb.lastIndexOf("/");
+ String instID = certdb.substring(i + 1);
+ String certPrefix = ".." + File.separator + ".." + File.separator + instID +
+ File.separator + "config" + File.separator;
+ String keyPrefix = certPrefix;
+
+ c.putString("jss.certPrefix", certPrefix.replace('\\', '/'));
+ c.putString("jss.keyPrefix", keyPrefix.replace('\\', '/'));
+ c.putString("jss.configDir", dir.replace('\\', '/'));
+ c.putString("jss.secmodName", secmodName);
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java b/pki/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java
new file mode 100644
index 000000000..b6cb0e6f7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java
@@ -0,0 +1,501 @@
+// --- 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.cmscore.authentication;
+
+
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * Default authentication subsystem
+ * <P>
+ *
+ * @author cfu
+ * @author lhsiao
+ * @version $Revision$, $Date$
+ */
+public class AuthSubsystem implements IAuthSubsystem {
+ public static final String ID = "auths";
+
+ public Hashtable mAuthMgrPlugins = new Hashtable();
+ public Hashtable mAuthMgrInsts = new Hashtable();
+ private String mId = "auths";
+ private IConfigStore mConfig = null;
+
+ private ILogger mLogger = null;
+
+ // singleton enforcement
+
+ private static AuthSubsystem mInstance = new AuthSubsystem();
+
+ public static synchronized AuthSubsystem getInstance() {
+ return mInstance;
+ }
+
+ // end singleton enforcement.
+
+ private AuthSubsystem() {
+ }
+
+ /**
+ * Initializes the authentication subsystem from the config store.
+ * Load Authentication manager plugins, create and initialize
+ * initialize authentication manager instances.
+ * @param owner The owner of this module.
+ * @param config The configuration store.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ try {
+ mLogger = CMS.getLogger();
+ mConfig = config;
+
+ // hardcode admin and agent plugins required for the server to be
+ // functional.
+
+ AuthMgrPlugin newPlugin = null;
+
+ newPlugin = new AuthMgrPlugin(PASSWDUSERDB_PLUGIN_ID,
+ PasswdUserDBAuthentication.class.getName());
+ newPlugin.setVisible(false);
+ mAuthMgrPlugins.put(PASSWDUSERDB_PLUGIN_ID, newPlugin);
+
+ newPlugin = new AuthMgrPlugin(CERTUSERDB_PLUGIN_ID,
+ CertUserDBAuthentication.class.getName());
+ newPlugin.setVisible(false);
+ mAuthMgrPlugins.put(CERTUSERDB_PLUGIN_ID, newPlugin);
+
+ newPlugin = new AuthMgrPlugin(CHALLENGE_PLUGIN_ID,
+ ChallengePhraseAuthentication.class.getName());
+ newPlugin.setVisible(false);
+ mAuthMgrPlugins.put(CHALLENGE_PLUGIN_ID, newPlugin);
+
+ // Bugscape #56659
+ // Removed NullAuthMgr to harden CMS. Otherwise,
+ // any request submitted for nullAuthMgr will
+ // be approved automatically
+ //
+ // newPlugin = new AuthMgrPlugin(NULL_PLUGIN_ID,
+ // NullAuthentication.class.getName());
+ // newPlugin.setVisible(false);
+ // mAuthMgrPlugins.put(NULL_PLUGIN_ID, newPlugin);
+
+ newPlugin = new AuthMgrPlugin(SSLCLIENTCERT_PLUGIN_ID,
+ SSLClientCertAuthentication.class.getName());
+ newPlugin.setVisible(false);
+ mAuthMgrPlugins.put(SSLCLIENTCERT_PLUGIN_ID, newPlugin);
+
+ // get auth manager plugins.
+
+ IConfigStore c = config.getSubStore(PROP_IMPL);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+
+ AuthMgrPlugin plugin = new AuthMgrPlugin(id, pluginPath);
+
+ mAuthMgrPlugins.put(id, plugin);
+ }
+ if (Debug.ON) {
+ Debug.trace("loaded auth plugins");
+ }
+
+ // hardcode admin and agent auth manager instances for the server
+ // to be functional
+
+ IAuthManager passwdUserDBAuth = new PasswdUserDBAuthentication();
+
+ passwdUserDBAuth.init(PASSWDUSERDB_AUTHMGR_ID, PASSWDUSERDB_PLUGIN_ID, null);
+ mAuthMgrInsts.put(PASSWDUSERDB_AUTHMGR_ID, new
+ AuthManagerProxy(true, passwdUserDBAuth));
+ if (Debug.ON) {
+ Debug.trace("loaded password based auth manager");
+ }
+
+ IAuthManager certUserDBAuth = new CertUserDBAuthentication();
+
+ certUserDBAuth.init(CERTUSERDB_AUTHMGR_ID, CERTUSERDB_PLUGIN_ID, config);
+ mAuthMgrInsts.put(CERTUSERDB_AUTHMGR_ID, new AuthManagerProxy(true, certUserDBAuth));
+ if (Debug.ON) {
+ Debug.trace("loaded certificate based auth manager");
+ }
+
+ IAuthManager challengeAuth = new ChallengePhraseAuthentication();
+
+ challengeAuth.init(CHALLENGE_AUTHMGR_ID, CHALLENGE_PLUGIN_ID, config);
+ mAuthMgrInsts.put(CHALLENGE_AUTHMGR_ID, new AuthManagerProxy(true, challengeAuth));
+ if (Debug.ON) {
+ Debug.trace("loaded challenge phrase auth manager");
+ }
+
+ IAuthManager cmcAuth = new com.netscape.cms.authentication.CMCAuth();
+
+ cmcAuth.init(CMCAUTH_AUTHMGR_ID, CMCAUTH_PLUGIN_ID, config);
+ mAuthMgrInsts.put(CMCAUTH_AUTHMGR_ID, new AuthManagerProxy(true, cmcAuth));
+ if (Debug.ON) {
+ Debug.trace("loaded cmc auth manager");
+ }
+
+ // #56659
+ // IAuthManager nullAuth = new NullAuthentication();
+
+ // nullAuth.init(NULL_AUTHMGR_ID, NULL_PLUGIN_ID, config);
+ // mAuthMgrInsts.put(NULL_AUTHMGR_ID, new AuthManagerProxy(true, nullAuth));
+ // if (Debug.ON) {
+ // Debug.trace("loaded null auth manager");
+ // }
+
+ IAuthManager sslClientCertAuth = new SSLClientCertAuthentication();
+
+ sslClientCertAuth.init(SSLCLIENTCERT_AUTHMGR_ID, SSLCLIENTCERT_PLUGIN_ID, config);
+ mAuthMgrInsts.put(SSLCLIENTCERT_AUTHMGR_ID, new AuthManagerProxy(true, sslClientCertAuth));
+ if (Debug.ON) {
+ Debug.trace("loaded sslClientCert auth manager");
+ }
+
+ // get auth manager instances.
+ c = config.getSubStore(PROP_INSTANCE);
+ Enumeration instances = c.getSubStoreNames();
+
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." + PROP_PLUGIN);
+ AuthMgrPlugin plugin =
+ (AuthMgrPlugin) mAuthMgrPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_CANT_FIND_PLUGIN", implName));
+ throw new EAuthMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", implName));
+ }
+ String className = plugin.getClassPath();
+
+ boolean isEnable = false;
+ // Instantiate and init the authentication manager.
+ IAuthManager authMgrInst = null;
+
+ try {
+ authMgrInst = (IAuthManager)
+ Class.forName(className).newInstance();
+ IConfigStore authMgrConfig = c.getSubStore(insName);
+
+ authMgrInst.init(insName, implName, authMgrConfig);
+ isEnable = true;
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_ADD_AUTH_INSTANCE", insName));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString()));
+ // Skip the authenticaiton instance if
+ // it is mis-configurated. This give
+ // administrator another chance to
+ // fix the problem via console
+ } catch (Throwable e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString()));
+ // Skip the authenticaiton instance if
+ // it is mis-configurated. This give
+ // administrator another chance to
+ // fix the problem via console
+ }
+ // add manager instance to list.
+ mAuthMgrInsts.put(insName, new
+ AuthManagerProxy(isEnable, authMgrInst));
+ if (Debug.ON) {
+ Debug.trace("loaded auth instance " + insName + " impl " + implName);
+ }
+ }
+ log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", getId()));
+ } catch (EBaseException ee) {
+ if (CMS.isPreOpMode())
+ return;
+ throw ee;
+ }
+ }
+
+ /**
+ * Authenticate to the named authentication manager instance
+ * <p>
+ * @param authCred authentication credentials subject to the
+ * requirements of each authentication manager
+ * @param authMgrName name of the authentication manager instance
+ * @return authentication token with individualized authenticated
+ * information.
+ * @exception EMissingCredential If a required credential for the
+ * authentication manager is missing.
+ * @exception EInvalidCredentials If the credentials cannot be authenticated
+ * @exception EAuthMgrNotFound The auth manager is not found.
+ * @exception EBaseException If an internal error occurred.
+ */
+ public IAuthToken authenticate(
+ IAuthCredentials authCred, String authMgrInstName)
+ throws EMissingCredential, EInvalidCredentials,
+ EAuthMgrNotFound, EBaseException {
+ AuthManagerProxy proxy = (AuthManagerProxy)
+ mAuthMgrInsts.get(authMgrInstName);
+
+ if (proxy == null) {
+ throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName));
+ }
+ if (!proxy.isEnable()) {
+ throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName));
+ }
+ IAuthManager authMgrInst = proxy.getAuthManager();
+
+ if (authMgrInst == null) {
+ throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName));
+ }
+ return (authMgrInst.authenticate(authCred));
+ }
+
+ /**
+ * Gets a list of required authentication credential names
+ * of the specified authentication manager.
+ */
+ public String[] getRequiredCreds(String authMgrInstName)
+ throws EAuthMgrNotFound {
+ IAuthManager authMgrInst = get(authMgrInstName);
+
+ if (authMgrInst == null) {
+ throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName));
+ }
+ return authMgrInst.getRequiredCreds();
+ }
+
+ /**
+ * Gets configuration parameters for the given
+ * authentication manager plugin.
+ * @param implName Name of the authentication plugin.
+ * @return Hashtable of required parameters.
+ */
+ public String[] getConfigParams(String implName)
+ throws EAuthMgrPluginNotFound, EBaseException {
+ // is this a registered implname?
+ AuthMgrPlugin plugin = (AuthMgrPlugin) mAuthMgrPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_PLUGIN_NOT_FOUND", implName));
+ throw new EAuthMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", implName));
+ }
+
+ // a temporary instance
+ IAuthManager authMgrInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ authMgrInst = (IAuthManager)
+ Class.forName(className).newInstance();
+ return (authMgrInst.getConfigParams());
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString()));
+ throw new
+ EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className));
+ }
+ }
+
+ /**
+ * Add an authentication manager instance.
+ * @param name name of the authentication manager instance
+ * @param authMgr the authentication manager instance to be added
+ */
+ public void add(String name, IAuthManager authMgrInst) {
+ mAuthMgrInsts.put(name, new AuthManagerProxy(true, authMgrInst));
+ }
+
+ /*
+ * Removes a authentication manager instance.
+ * @param name name of the authentication manager
+ */
+ public void delete(String name) {
+ mAuthMgrInsts.remove(name);
+ }
+
+ /**
+ * Gets the authentication manager instance of the specified name.
+ * @param name name of the authentication manager instance
+ * @return the named authentication manager instance
+ */
+ public IAuthManager get(String name) {
+ AuthManagerProxy proxy = (AuthManagerProxy) mAuthMgrInsts.get(name);
+
+ if (proxy == null)
+ return null;
+ return proxy.getAuthManager();
+ }
+
+ /**
+ * Enumerate all authentication manager instances.
+ */
+ public Enumeration getAuthManagers() {
+ Vector inst = new Vector();
+ Enumeration e = mAuthMgrInsts.keys();
+
+ while (e.hasMoreElements()) {
+ IAuthManager p = get((String) e.nextElement());
+
+ if (p != null) {
+ inst.addElement(p);
+ }
+ }
+ return (inst.elements());
+ }
+
+ /**
+ * Enumerate all registered authentication manager plugins.
+ */
+ public Enumeration getAuthManagerPlugins() {
+ return (mAuthMgrPlugins.elements());
+ }
+
+ /**
+ * retrieve a single auth manager plugin by name
+ */
+ public AuthMgrPlugin getAuthManagerPluginImpl(String name) {
+ return (AuthMgrPlugin) mAuthMgrPlugins.get(name);
+ }
+
+ /**
+ * Retrieve a single auth manager instance
+ */
+
+ /* getconfigparams above should be recoded to use this func */
+ public IAuthManager getAuthManagerPlugin(String name) {
+ AuthMgrPlugin plugin = (AuthMgrPlugin) mAuthMgrPlugins.get(name);
+ String classpath = plugin.getClassPath();
+ IAuthManager authMgrInst = null;
+
+ try {
+ authMgrInst = (IAuthManager) Class.forName(classpath).newInstance();
+ return (authMgrInst);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString()));
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves id (name) of this subsystem.
+ * @return name of the authentication subsystem
+ */
+ public String getId() {
+ return (mId);
+ }
+
+ /**
+ * Sets id string to this subsystem.
+ * <p>
+ * Use with caution. Should not do it when sharing with others
+ * @param id name to be applied to an authentication sybsystem
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * registers the administration servlet with the administration subsystem.
+ */
+ public void startup() throws EBaseException {
+ //remove the log since it's already logged from S_ADMIN
+ //String infoMsg = "Auth subsystem administration Servlet registered";
+ //log(ILogger.LL_INFO, infoMsg);
+ }
+
+ /**
+ * shuts down authentication managers one by one.
+ * <P>
+ */
+ public void shutdown() {
+ for (Enumeration e = mAuthMgrInsts.keys();
+ e.hasMoreElements();) {
+
+ IAuthManager mgr = (IAuthManager) get((String) e.nextElement());
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_SHUTDOWN", mgr.getName()));
+
+ mgr.shutdown();
+ }
+
+ mAuthMgrPlugins.clear();
+ mAuthMgrPlugins = null;
+ mAuthMgrInsts.clear();
+ mAuthMgrInsts = null;
+ }
+
+ public Hashtable getPlugins() {
+ return mAuthMgrPlugins;
+ }
+
+ public Hashtable getInstances() {
+ return mAuthMgrInsts;
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the named authentication manager
+ * @param name of the authentication manager
+ * @return the named authentication manager
+ */
+ public IAuthManager getAuthManager(String name) {
+ return ((IAuthManager) get(name));
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java b/pki/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
new file mode 100644
index 000000000..b9e0ede9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
@@ -0,0 +1,266 @@
+// --- 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.cmscore.authentication;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.lang.Class;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.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.authentication.*;
+import com.netscape.certsrv.policy.*;
+
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.cmscore.request.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.cmscore.usrgrp.*;
+
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * Certificate server agent authentication.
+ * Maps a SSL client authenticate certificate to a user (agent) entry in the
+ * internal database.
+ * <P>
+ *
+ * @author lhsiao
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CertUserDBAuthentication implements IAuthManager {
+
+ /* 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 ICertUserLocator mCULocator = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ private boolean mRevocationCheckingEnabled = false;
+ private IConfigStore mRevocationChecking = null;
+ private String mRequestor = null;
+
+ public CertUserDBAuthentication() {
+ }
+
+ /**
+ * initializes the CertUserDBAuthentication auth manager
+ * <p>
+ * called by AuthSubsystem init() method, when initializing
+ * all available authentication managers.
+ * @param owner - The authentication subsystem that hosts this
+ * auth manager
+ * @param config - The configuration store used by the
+ * authentication subsystem
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ if (mConfig != null) {
+ mRevocationChecking = mConfig.getSubStore("revocationChecking");
+ }
+ if (mRevocationChecking != null) {
+ mRevocationCheckingEnabled = mRevocationChecking.getBoolean("enabled", false);
+ if (mRevocationCheckingEnabled) {
+ int size = mRevocationChecking.getInteger("bufferSize", 0);
+ long interval = (long) mRevocationChecking.getInteger("validityInterval", 28800);
+ long unknownStateInterval = (long) mRevocationChecking.getInteger("unknownStateInterval", 1800);
+
+ if (size > 0)
+ CMS.setListOfVerifiedCerts(size, interval, unknownStateInterval);
+ }
+ }
+
+ mCULocator = new ExactMatchCertUserLocator();
+ log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name));
+ }
+
+ /**
+ * Gets the name of this authentication manager.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the plugin name of authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * authenticates user(agent) by certificate
+ * <p>
+ * called by other subsystems or their servlets to authenticate
+ * users (agents)
+ * @param authCred - authentication credential that contains
+ * an usrgrp.Certificates of the user (agent)
+ * @return the authentication token that contains the following
+ *
+ * @exception com.netscape.certsrv.base.EAuthsException any
+ * authentication failure or insufficient credentials
+ * @see com.netscape.certsrv.authentication.AuthToken
+ * @see com.netscape.certsrv.usrgrp.Certificates
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ CMS.debug("CertUserDBAuth: started");
+ AuthToken authToken = new AuthToken(this);
+ CMS.debug("CertUserDBAuth: Retrieving client certificate");
+ X509Certificate[] x509Certs =
+ (X509Certificate[]) authCred.get(CRED_CERT);
+
+ if (x509Certs == null) {
+ CMS.debug("CertUserDBAuth: no client certificate found");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_CERT"));
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT));
+ }
+ CMS.debug("CertUserDBAuth: Got client certificate");
+
+ if (mRevocationCheckingEnabled) {
+ X509CertImpl cert0 = (X509CertImpl) x509Certs[0];
+ if (cert0 == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_NO_CERT"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_NO_CERT"));
+ }
+ if (CMS.isRevoked(x509Certs)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_REVOKED_CERT"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ }
+
+ CMS.debug("Authentication: client certificate found");
+
+ // map cert to user
+ User user = null;
+ Certificates certs = new Certificates(x509Certs);
+
+ try {
+ user = (User) mCULocator.locateUser(certs);
+ } catch (EUsrGrpException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_AUTH_FAILED", x509Certs[0].getSerialNumber().toString(16), x509Certs[0].getSubjectDN().toString(), e.toString()));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ } catch (netscape.ldap.LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_CANNOT_AGENT_AUTH", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ // any unexpected error occurs like internal db down,
+ // UGSubsystem only returns null for user.
+ if (user == null) {
+ CMS.debug("Authentication: cannot map certificate to user");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_USER_NOT_FOUND"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ CMS.debug("Authentication: mapped certificate to user");
+
+ authToken.set(TOKEN_USERDN, user.getUserDN());
+ authToken.set(TOKEN_USER_DN, user.getUserDN());
+ authToken.set(TOKEN_USERID, user.getUserID());
+ authToken.set(TOKEN_UID, user.getUserID());
+ authToken.set(CRED_CERT, certs);
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", user.getUserID()));
+ CMS.debug("authenticated " + user.getUserDN());
+
+ return authToken;
+ }
+
+ /**
+ * 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;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java b/pki/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java
new file mode 100644
index 000000000..518e89f53
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java
@@ -0,0 +1,408 @@
+// --- 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.cmscore.authentication;
+
+
+import java.util.*;
+import java.math.BigInteger;
+import java.security.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * Challenge phrase based authentication.
+ * Maps a certificate to the request in the
+ * internal database and further compares the challenge phrase with
+ * that from the EE input.
+ * <P>
+ *
+ * @author cfu chrisho
+ * @version $Revision$, $Date$
+ */
+public class ChallengePhraseAuthentication implements IAuthManager {
+
+ /* result auth token attributes */
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+
+ /* required credentials */
+ public static final String CRED_CERT_SERIAL = IAuthManager.CRED_CERT_SERIAL_TO_REVOKE;
+ public static final String CRED_CHALLENGE = "challengePhrase";
+ protected String[] mRequiredCreds = { CRED_CERT_SERIAL, CRED_CHALLENGE};
+
+ /* config parameters to pass to console (none) */
+ protected static String[] mConfigParams = null;
+ protected ICertificateAuthority mCA = null;
+ protected ICertificateRepository mCertDB = null;
+
+ private String mName = null;
+ private String mImplName = null;
+ private IConfigStore mConfig = null;
+
+ private ICertUserLocator mCULocator = null;
+ private ILogger mLogger = CMS.getLogger();
+ private String mRequestor = null;
+ private Vector mID = null;
+ private MessageDigest mSHADigest = null;
+
+ // request attributes hacks
+ public static final String CHALLENGE_PHRASE = CRED_CHALLENGE;
+ public static final String SUBJECTNAME = "subjectName";
+ public static final String SERIALNUMBER = "serialNumber";
+ public static final String SERIALNOARRAY = "serialNoArray";
+
+ public ChallengePhraseAuthentication() {
+ }
+
+ /**
+ * initializes the ChallengePhraseAuthentication 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;
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.getMessage()));
+ }
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name));
+ }
+
+ /**
+ * Gets the name of this authentication manager.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the plugin name of authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * authenticates revocation of a certification by a challenge phrase
+ * <p>
+ * called by other subsystems or their servlets to authenticate
+ * a revocation request
+ * @param authCred - authentication credential that contains
+ * a Certificate to revoke
+ * @return the authentication token that contains the request id
+ *
+ * @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
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ mCA = (ICertificateAuthority)
+ SubsystemRegistry.getInstance().get("ca");
+
+ if (mCA != null) {
+ mCertDB = (CertificateRepository) mCA.getCertificateRepository();
+ }
+
+ AuthToken authToken = new AuthToken(this);
+
+ /*
+ X509Certificate[] x509Certs =
+ (X509Certificate[]) authCred.get(CRED_CERT);
+ if (x509Certs == null) {
+ log(ILogger.LL_FAILURE,
+ " missing cert credential.");
+ throw new EMissingCredential(CRED_CERT_SERIAL);
+ }
+ */
+
+ String serialNumString = (String) authCred.get(CRED_CERT_SERIAL);
+
+ BigInteger serialNum = null;
+
+ if (serialNumString == null || serialNumString.equals(""))
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT_SERIAL));
+ else {
+ //serialNumString = getDecimalStr(serialNumString);
+ try {
+ serialNumString = serialNumString.trim();
+ if (serialNumString.startsWith("0x") || serialNumString.startsWith("0X")) {
+ serialNum = new
+ BigInteger(serialNumString.substring(2), 16);
+ } else {
+ serialNum = new
+ BigInteger(serialNumString);
+ }
+
+ } catch (NumberFormatException e) {
+ throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", "Invalid serial number."));
+ }
+ }
+
+ String challenge = (String) authCred.get(CRED_CHALLENGE);
+
+ if (challenge == null) {
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CHALLENGE));
+ }
+ if (challenge.equals("")) {
+ // empty challenge not allowed
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_REVO_ATTEMPT", serialNum.toString()));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ /* maybe later
+ if (mCertDB.isCertificateRevoked(cert) != null) {
+ log(ILogger.LL_FAILURE,
+ "Certificate has already been revoked.");
+ // throw something else...cfu
+ throw new EInvalidCredentials();
+ }
+ */
+
+ X509CertImpl[] certsToRevoke = null;
+ BigInteger[] bigIntArray = null;
+
+ // check challenge phrase against request
+ /*
+ * map cert to a request: a cert serial number maps to a
+ * cert record in the internal db, from the cert record,
+ * where we'll find the challenge phrase
+ */
+ if (mCertDB != null) { /* is CA */
+ CertRecord record = null;
+
+ try {
+ record = (CertRecord) mCertDB.readCertificateRecord(serialNum);
+ } catch (EBaseException ee) {
+ if (Debug.ON) {
+ Debug.trace(ee.toString());
+ }
+ }
+ if (record != null) {
+ String status = record.getStatus();
+
+ if (!status.equals("REVOKED")) {
+ boolean samepwd = compareChallengePassword(record, challenge);
+
+ if (samepwd) {
+ bigIntArray = new BigInteger[1];
+ bigIntArray[0] = record.getSerialNumber();
+ } else
+ throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", "Invalid password."));
+
+ } else {
+ bigIntArray = new BigInteger[0];
+ }
+ } else {
+ bigIntArray = new BigInteger[0];
+ }
+ } else {
+
+ /*
+ * ra, build a request and send through the connection for
+ * authentication
+ */
+ IRequestQueue queue = getReqQueue();
+
+ if (queue != null) {
+ IRequest checkChallengeReq = null;
+
+ checkChallengeReq =
+ queue.newRequest(IRequest.REVOCATION_CHECK_CHALLENGE_REQUEST);
+ checkChallengeReq.setExtData(CHALLENGE_PHRASE, challenge);
+ // pass just serial number instead of whole cert
+ if (serialNum != null)
+ checkChallengeReq.setExtData(SERIALNUMBER, serialNum);
+ queue.processRequest(checkChallengeReq);
+ // check request status...
+ RequestStatus status = checkChallengeReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ bigIntArray = checkChallengeReq.getExtDataInBigIntegerArray("serialNoArray");
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INCOMPLETE_REQUEST"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_FAILED_GET_QUEUE"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_REVOCATION_CHALLENGE_QUEUE_FAILED"));
+ }
+ } // else, ra
+ if (bigIntArray != null && bigIntArray.length > 0) {
+ if (Debug.ON) {
+ Debug.trace("challenge authentication serialno array not null");
+ for (int i = 0; i < bigIntArray.length; i++)
+ Debug.trace("challenge auth serialno " + bigIntArray[i]);
+ }
+ }
+ if (Debug.ON) {
+ Debug.trace("challenge authentication set " + TOKEN_CERT_SERIAL);
+ }
+ authToken.set(TOKEN_CERT_SERIAL, bigIntArray);
+
+ return authToken;
+ }
+
+ private String getDecimalStr(String str) {
+ String newStr = str;
+
+ if (str.startsWith("0x") || str.startsWith("0X")) {
+ newStr = "" + Integer.parseInt(str.trim().substring(2), 16);
+ }
+
+ return newStr;
+ }
+
+ private boolean compareChallengePassword(CertRecord record, String pwd)
+ throws EBaseException {
+ MetaInfo metaInfo = (MetaInfo) record.get(CertRecord.ATTR_META_INFO);
+
+ if (metaInfo == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "metaInfo"));
+ }
+
+ if (pwd == null) {
+ if (Debug.ON) {
+ Debug.trace("challenge pwd is null");
+ }
+ return false;
+ }
+ String hashpwd = hashPassword(pwd);
+
+ // got metaInfo
+ String challengeString =
+ (String) metaInfo.get(CertRecord.META_CHALLENGE_PHRASE);
+
+ if (challengeString == null) {
+ if (Debug.ON) {
+ Debug.trace("challengeString null");
+ }
+ return false;
+ }
+
+ if (!challengeString.equals(hashpwd)) {
+ return false;
+
+ /*
+ log(ILogger.LL_FAILURE,
+ "Incorrect challenge phrase password used for revocation");
+ throw new EInvalidCredentials();
+ */
+ } else
+ return true;
+ }
+
+ /**
+ * 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. ChallengePhraseAuthentication 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;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+ private IRequestQueue getReqQueue() {
+ IRequestQueue queue = null;
+
+ try {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ SubsystemRegistry.getInstance().get("ra");
+
+ if (ra != null) {
+ queue = ra.getRequestQueue();
+ mRequestor = IRequest.REQUESTOR_RA;
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ " cannot get access to the request queue.");
+ }
+
+ return queue;
+ }
+
+ private String hashPassword(String pwd) {
+ String salt = "lala123";
+ byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest);
+
+ return "{SHA}" + b64E;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java b/pki/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java
new file mode 100644
index 000000000..b2914686e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java
@@ -0,0 +1,154 @@
+// --- 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.cmscore.authentication;
+
+
+import java.util.*;
+import java.lang.Class;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * This authentication does nothing but just returns an empty authToken.
+ * <P>
+ * @author chrisho
+ * @version $Revision$, $Date$
+ */
+public class NullAuthentication implements IAuthManager {
+
+ /* configuration params to pass to console (none) */
+ protected static String[] mConfigParams = null;
+
+ protected static String[] mRequiredCred = {};
+ private String mName = null;
+ private String mImplName = null;
+ private IConfigStore mConfig = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ public NullAuthentication() {
+ }
+
+ /**
+ * initializes the NullAuthentication auth manager
+ * <p>
+ * called by AuthSubsystem init() method, when initializing
+ * all available authentication managers.
+ * @param name - Name assigned to this authentication manager instance.
+ * @param implName - Name of the authentication plugin.
+ * @param config - The configuration store used by the
+ * authentication subsystem.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName));
+ }
+
+ /**
+ * authenticates nothing
+ * <p>
+ * called by other subsystems or their servlets to authenticate administrators
+ * @param authCred Authentication credentials.
+ * "uid" and "pwd" are required.
+ * @return the authentication token (authToken) that contains the following
+ * userdn = [userdn, in case of success]<br>
+ * authMgrName = [authMgrName]<br>
+ * @exception com.netscape.certsrv.base.MissingCredential If either
+ * "uid" or "pwd" is missing from the given credentials.
+ * @exception com.netscape.certsrv.base.InvalidCredentials If the
+ * the credentials failed to authenticate.
+ * @exception com.netscape.certsrv.base.EBaseException If an internal
+ * error occurred.
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ AuthToken authToken = new AuthToken(this);
+
+ authToken.set("authType", "NOAUTH");
+
+ return authToken;
+ }
+
+ /**
+ * gets the name of this authentication manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the name of the authentication manager plugin
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * get the list of authentication credential attribute names
+ * required by this authentication manager. Generally used by
+ * servlets that use this authentication manager, to retrieve
+ * required credentials from the user (e.g. Javascript form data)
+ * @return attribute names in Vector
+ */
+ public String[] getRequiredCreds() {
+ return (mRequiredCred);
+ }
+
+ /**
+ * Get the list of configuration parameter names
+ * required by this authentication manager. In this case, an empty list.
+ * @return String array of configuration parameters.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * disconnects the member connection
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * gets the configuration substore used by this authentication
+ * manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Log a message.
+ * @param level The logging level.
+ * @param msg The message to log.
+ */
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java b/pki/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java
new file mode 100644
index 000000000..1c675b8ae
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java
@@ -0,0 +1,264 @@
+// --- 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.cmscore.authentication;
+
+
+import netscape.ldap.*;
+import netscape.ldap.LDAPEntry;
+import java.util.*;
+import java.lang.Class;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.ldap.*;
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.usrgrp.*;
+
+
+/**
+ * Certificate Server admin authentication.
+ * Used to authenticate administrators in the Certificate Server Console.
+ * Authentications by checking the uid and password against the
+ * database.
+ * <P>
+ * @author lhsiao, cfu
+ * @version $Revision$, $Date$
+ */
+public class PasswdUserDBAuthentication implements IAuthManager {
+
+ /* required credentials. uid, pwd are strings */
+ public static final String CRED_UID = "uid";
+ public static final String CRED_PWD = "pwd";
+ protected static String[] mRequiredCred = { CRED_UID, CRED_PWD };
+
+ /* attribute in returned token */
+ public static final String TOKEN_USERDN = "userdn";
+ public static final String TOKEN_USERID = "userid";
+
+ /* configuration params to pass to console (none) */
+ protected static String[] mConfigParams = null;
+
+ private String mName = null;
+ private String mImplName = null;
+ private IConfigStore mConfig;
+ private String mBaseDN = null;
+ private LdapBoundConnFactory mConnFactory = null;
+ private LdapAnonConnFactory mAnonConnFactory = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ public PasswdUserDBAuthentication() {
+ }
+
+ /**
+ * initializes the PasswdUserDBAuthentication auth manager
+ * <p>
+ * called by AuthSubsystem init() method, when initializing
+ * all available authentication managers.
+ * @param name - Name assigned to this authentication manager instance.
+ * @param implName - Name of the authentication plugin.
+ * @param config - The configuration store used by the
+ * authentication subsystem.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ /* internal database directory used */
+ DBSubsystem dbs = (DBSubsystem) DBSubsystem.getInstance();
+ LdapConnInfo ldapinfo = dbs.getLdapConnInfo();
+ if (ldapinfo == null && CMS.isPreOpMode())
+ return;
+
+ mBaseDN = dbs.getBaseDN();
+ mConnFactory = new LdapBoundConnFactory(3, 20, ldapinfo, dbs.getLdapAuthInfo());
+ mAnonConnFactory = new LdapAnonConnFactory(3, 20, ldapinfo);
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName));
+ }
+
+ /**
+ * authenticates administratrators by LDAP uid/pwd
+ * <p>
+ * called by other subsystems or their servlets to authenticate administrators
+ * @param authCred Authentication credentials.
+ * "uid" and "pwd" are required.
+ * @return the authentication token (authToken) that contains the following
+ * userdn = [userdn, in case of success]<br>
+ * authMgrName = [authMgrName]<br>
+ * @exception com.netscape.certsrv.base.MissingCredential If either
+ * "uid" or "pwd" is missing from the given credentials.
+ * @exception com.netscape.certsrv.base.InvalidCredentials If the
+ * the credentials failed to authenticate.
+ * @exception com.netscape.certsrv.base.EBaseException If an internal
+ * error occurred.
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+ AuthToken authToken = new AuthToken(this);
+
+ // make sure the required credentials are provided
+ String uid = (String) authCred.get(CRED_UID);
+ CMS.debug("Authentication: UID=" + uid);
+ if (uid == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_UID"));
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID));
+ }
+ String pwd = (String) authCred.get(CRED_PWD);
+
+ if (pwd == null) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NULL_PW", uid));
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD));
+ }
+ // don't allow anonymous binding
+ if (pwd == "") {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_EMPTY_PW", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ String userdn = null;
+ LDAPConnection conn = null;
+ LDAPConnection anonConn = null;
+
+ try {
+ conn = mConnFactory.getConn();
+ // do anonymous search for the user's dn.
+ LDAPSearchResults res = conn.search(mBaseDN,
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ userdn = entry.getDN();
+ }
+ if (userdn == null) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NOT_FOUND", uid));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ anonConn = mAnonConnFactory.getConn();
+ anonConn.authenticate(userdn, pwd);
+ } catch (LDAPException e) {
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_AUTH_FAILED", uid, e.toString()));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ } finally {
+ if (conn != null)
+ mConnFactory.returnConn(conn);
+ if (anonConn != null)
+ mAnonConnFactory.returnConn(anonConn);
+ }
+
+ UGSubsystem ug = UGSubsystem.getInstance();
+
+ authToken.set(TOKEN_USERDN, userdn);
+ authToken.set(CRED_UID, uid); // return original uid for info
+
+ IUser user = null;
+
+ try {
+ user = ug.getUser(uid);
+ } catch (EBaseException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ // not a user in our user/group database.
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_UID_NOT_FOUND", uid, e.toString()));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ authToken.set(TOKEN_USERDN, user.getUserDN());
+ authToken.set(TOKEN_USERID, user.getUserID());
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", uid));
+
+ return authToken;
+ }
+
+ /**
+ * gets the name of this authentication manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the name of the authentication manager plugin
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * get the list of authentication credential attribute names
+ * required by this authentication manager. Generally used by
+ * servlets that use this authentication manager, to retrieve
+ * required credentials from the user (e.g. Javascript form data)
+ * @return attribute names in Vector
+ */
+ public String[] getRequiredCreds() {
+ return (mRequiredCred);
+ }
+
+ /**
+ * Get the list of configuration parameter names
+ * required by this authentication manager. In this case, an empty list.
+ * @return String array of configuration parameters.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * disconnects the member connection
+ */
+ public void shutdown() {
+ try {
+ // disconnect all outstanding connections in the factory
+ mConnFactory.reset();
+ mConnFactory = null;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ }
+ }
+
+ /**
+ * gets the configuretion substore used by this authentication
+ * manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Log a message.
+ * @param level The logging level.
+ * @param msg The message to log.
+ */
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java b/pki/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java
new file mode 100644
index 000000000..7aca9ae54
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java
@@ -0,0 +1,286 @@
+// --- 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.cmscore.authentication;
+
+
+// ldap java sdk
+
+// cert server imports.
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+ import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+
+// cert server x509 imports
+import netscape.security.x509.*;
+
+import java.security.*;
+import java.security.cert.*;
+
+// java sdk imports.
+import java.math.*;
+
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * SSL client based authentication.
+ * <P>
+ * @author chrisho
+ * @version $Revision$, $Date$
+ */
+public class SSLClientCertAuthentication implements IAuthManager {
+
+ /* required credential to authenticate, client certificate */
+ public static final String CRED_CERT = IAuthManager.CRED_SSL_CLIENT_CERT;
+ public static final String SERIALNUMBER = "serialNumber";
+ public static final String ISSUERDN = "issuerDN";
+ protected static String[] mRequiredCreds = { CRED_CERT };
+
+ private ICertificateAuthority mCA = null;
+ private ICertificateRepository mCertDB = null;
+ private ILogger mLogger = CMS.getLogger();
+ private String mName = null;
+ private String mImplName = null;
+ private IConfigStore mConfig = null;
+ private String mRequestor = null;
+
+ /* Holds configuration parameters accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {};
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public SSLClientCertAuthentication() {
+ super();
+ }
+
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name));
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+
+ AuthToken authToken = new AuthToken(this);
+
+ CMS.debug("SSLCertAuth: Retrieving client certificates");
+ X509Certificate[] x509Certs =
+ (X509Certificate[]) authCred.get(CRED_CERT);
+
+ if (x509Certs == null) {
+ CMS.debug("SSLCertAuth: No client certificate found");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_AUTH_MISSING_CERT"));
+ throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT));
+ }
+ CMS.debug("SSLCertAuth: Got client certificate");
+
+ mCA = (ICertificateAuthority) CMS.getSubsystem("ca");
+
+ if (mCA != null) {
+ mCertDB = (ICertificateRepository) mCA.getCertificateRepository();
+ }
+
+ X509CertImpl clientCert = (X509CertImpl) x509Certs[0];
+
+ BigInteger serialNum = null;
+
+ try {
+ serialNum = (BigInteger) clientCert.getSerialNumber();
+ //serialNum = new BigInteger(s.substring(2), 16);
+ } catch (NumberFormatException e) {
+ throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", "Invalid serial number."));
+ }
+
+ String clientCertIssuerDN = clientCert.getIssuerDN().toString();
+ BigInteger[] bigIntArray = null;
+
+ if (mCertDB != null) { /* is CA */
+ ICertRecord record = null;
+
+ try {
+ record = (ICertRecord) mCertDB.readCertificateRecord(serialNum);
+ } catch (EBaseException ee) {
+ if (Debug.ON) {
+ Debug.trace(ee.toString());
+ }
+ }
+ if (record != null) {
+ String status = record.getStatus();
+
+ if (status.equals("VALID")) {
+
+ X509CertImpl cacert = mCA.getCACert();
+ Principal p = cacert.getSubjectDN();
+
+ if (!p.toString().equals(clientCertIssuerDN)) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ISSUER_NAME"));
+ }
+ } else {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", status));
+ }
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ }
+ } else {
+
+ /*
+ * ra, build a request and send through the connection for
+ * authentication
+ */
+ IRequestQueue queue = getReqQueue();
+
+ if (queue != null) {
+ IRequest getCertStatusReq = null;
+
+ getCertStatusReq =
+ queue.newRequest(IRequest.GETCERT_STATUS_REQUEST);
+ // pass just serial number instead of whole cert
+ if (serialNum != null) {
+ getCertStatusReq.setExtData(SERIALNUMBER, serialNum);
+ getCertStatusReq.setExtData(ISSUERDN, clientCertIssuerDN);
+ }
+ queue.processRequest(getCertStatusReq);
+ // check request status...
+ RequestStatus status = getCertStatusReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ String certStatus =
+ getCertStatusReq.getExtDataInString(IRequest.CERT_STATUS);
+
+ if (certStatus == null) {
+ String[] params = {"null status"};
+
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", params));
+ } else if (certStatus.equals("INVALIDCERTROOT")) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ISSUER_NAME"));
+ } else if (!certStatus.equals("VALID")) {
+ String[] params = {status.toString()};
+
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", params));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_AUTH_INCOMPLETE_REQUEST"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_REQUEST_IN_BAD_STATE"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_AUTH_FAILED_GET_QUEUE"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_GET_QUEUE_FAILED"));
+ }
+ } // else, ra
+
+ authToken.set(AuthToken.TOKEN_CERT, clientCert);
+
+ return authToken;
+ }
+
+ /**
+ * prepare this authentication manager for shutdown.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * Returns array of required credentials for this authentication manager.
+ * @return Array of required credentials.
+ */
+ public String[] getRequiredCreds() {
+ return mRequiredCreds;
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, msg);
+ }
+
+ private IRequestQueue getReqQueue() {
+ IRequestQueue queue = null;
+
+ try {
+ IRegistrationAuthority ra =
+ (IRegistrationAuthority) CMS.getSubsystem("ra");
+
+ if (ra != null) {
+ queue = ra.getRequestQueue();
+ mRequestor = IRequest.REQUESTOR_RA;
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ " cannot get access to the request queue.");
+ }
+
+ return queue;
+ }
+
+ /**
+ * Gets the configuration substore used by this authentication manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the name of this authentication manager instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * gets the plugin name of this authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java b/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java
new file mode 100644
index 000000000..90963e324
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.authentication;
+
+
+import java.util.*;
+import java.math.BigInteger;
+
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * class storing verified certificate.
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class VerifiedCert {
+ public static final int CHECKED = 4;
+ public static final int EXPIRED = 3;
+ public static final int NOT_REVOKED = 2;
+ public static final int REVOKED = 1;
+ public static final int UNKNOWN = 0;
+
+ private int mStatus = UNKNOWN;
+ private Date mCreated = null;
+ private BigInteger mSerialNumber = null;
+ private byte[] mCertEncoded = null;
+
+ /**
+ * Constructs verified certiificate record
+ */
+
+ public VerifiedCert(BigInteger serialNumber, byte[] certEncoded,
+ int status) {
+ mStatus = status;
+ mSerialNumber = serialNumber;
+ mCertEncoded = certEncoded;
+ mCreated = CMS.getCurrentDate();
+ }
+
+ public int check(BigInteger serialNumber, byte[] certEncoded,
+ long interval, long unknownStateInterval) {
+ int status = UNKNOWN;
+
+ if (mSerialNumber.equals(serialNumber)) {
+ if (mCertEncoded != null) {
+ if (certEncoded != null &&
+ mCertEncoded.length == certEncoded.length) {
+ int i;
+
+ for (i = 0; i < mCertEncoded.length; i++) {
+ if (mCertEncoded[i] != certEncoded[i])
+ break;
+ }
+ if (i >= mCertEncoded.length) {
+ Date expires = new Date(mCreated.getTime() + (interval * 1000));
+ Date now = CMS.getCurrentDate();
+
+ if (now.after(expires))
+ mStatus = EXPIRED;
+ status = mStatus;
+ }
+ }
+ } else if (unknownStateInterval > 0) {
+ Date expires = new Date(mCreated.getTime() + (unknownStateInterval * 1000));
+ Date now = CMS.getCurrentDate();
+
+ if (now.after(expires))
+ mStatus = EXPIRED;
+ status = mStatus; // CHECKED
+ }
+ }
+
+ return status;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java b/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java
new file mode 100644
index 000000000..9ceae4487
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java
@@ -0,0 +1,161 @@
+// --- 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.cmscore.authentication;
+
+
+import java.util.*;
+import java.math.BigInteger;
+import netscape.security.x509.*;
+
+
+/**
+ * class storing verified certificates.
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class VerifiedCerts {
+
+ /* the value type of the dn component */
+ private int mFirst = 0;
+ private int mLast = 0;
+ private int mNext = 0;
+ private VerifiedCert[] mVCerts = null;
+ private long mInterval = 0;
+ private long mUnknownStateInterval = 0;
+
+ /**
+ * Constructs verified certiificates list
+ */
+
+ public VerifiedCerts(int size, long interval) {
+ mVCerts = new VerifiedCert[size];
+ mInterval = interval;
+ mUnknownStateInterval = interval;
+ }
+
+ public VerifiedCerts(int size, long interval, long unknownStateInterval) {
+ mVCerts = new VerifiedCert[size];
+ mInterval = interval;
+ mUnknownStateInterval = unknownStateInterval;
+ }
+
+ public void update(X509CertImpl cert, int status) {
+ if (cert != null) {
+ byte[] certEncoded = null;
+
+ try {
+ certEncoded = cert.getEncoded();
+ } catch (Exception e) {
+ }
+ if ((certEncoded != null ||
+ (status == VerifiedCert.CHECKED && mUnknownStateInterval > 0))
+ && mInterval > 0) {
+ update(cert.getSerialNumber(), certEncoded, status);
+ }
+ }
+ }
+
+ public synchronized void update(BigInteger serialNumber, byte[] certEncoded, int status) {
+ if ((status == VerifiedCert.NOT_REVOKED ||
+ status == VerifiedCert.REVOKED ||
+ (status == VerifiedCert.CHECKED && mUnknownStateInterval > 0))
+ && mInterval > 0) {
+ if (mLast == mNext && mFirst == mNext) { // empty
+ mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status);
+ mNext = next(mNext);
+ } else if (mFirst == mNext) { // full
+ mFirst = next(mFirst);
+ mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status);
+ mLast = mNext;
+ mNext = next(mNext);
+ } else {
+ mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status);
+ mLast = mNext;
+ mNext = next(mNext);
+ }
+ }
+ }
+
+ public int check(X509CertImpl cert) {
+ int status = VerifiedCert.UNKNOWN;
+
+ if (mLast != mNext && mInterval > 0) { // if not empty and
+ if (cert != null) {
+ byte[] certEncoded = null;
+
+ try {
+ certEncoded = cert.getEncoded();
+ } catch (Exception e) {
+ }
+ if (certEncoded != null) {
+ status = check(cert.getSerialNumber(), certEncoded);
+ }
+ }
+ }
+
+ return status;
+ }
+
+ public synchronized int check(BigInteger serialNumber, byte[] certEncoded) {
+ int status = VerifiedCert.UNKNOWN;
+ int i = mLast;
+
+ if (mVCerts != null && mLast != mNext && mInterval > 0) { // if not empty and
+ while (status == VerifiedCert.UNKNOWN) {
+ if (mVCerts[i] == null)
+ return status;
+ status = mVCerts[i].check(serialNumber, certEncoded,
+ mInterval, mUnknownStateInterval);
+ if (status == VerifiedCert.EXPIRED) {
+ if (mFirst == mLast)
+ mNext = mLast;
+ else
+ mFirst = next(i);
+ break;
+ } else if (mFirst == i) {
+ break;
+ } else {
+ i = previous(i);
+ }
+ }
+ if (status == VerifiedCert.UNKNOWN)
+ status = mVCerts[i].check(serialNumber, certEncoded,
+ mInterval, mUnknownStateInterval);
+ }
+
+ return status;
+ }
+
+ private int next(int i) {
+ i++;
+ if (i >= mVCerts.length)
+ i = 0;
+
+ return i;
+ }
+
+ private int previous(int i) {
+ if (i <= 0)
+ i = mVCerts.length;
+ i--;
+
+ return i;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java b/pki/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java
new file mode 100644
index 000000000..9dd1ef57d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java
@@ -0,0 +1,459 @@
+// --- 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.cmscore.authorization;
+
+
+import java.util.*;
+import java.lang.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * Default authorization subsystem
+ * <P>
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class AuthzSubsystem implements IAuthzSubsystem {
+ public static final String ID = "authz";
+
+ public Hashtable mAuthzMgrPlugins = new Hashtable();
+ public Hashtable mAuthzMgrInsts = new Hashtable();
+ private String mId = "authz";
+ private IConfigStore mConfig = null;
+
+ private ILogger mLogger = null;
+
+ // singleton enforcement
+
+ private static AuthzSubsystem mInstance = new AuthzSubsystem();
+
+ public static synchronized AuthzSubsystem getInstance() {
+ return mInstance;
+ }
+
+ // end singleton enforcement.
+
+ private AuthzSubsystem() {
+ }
+
+ /**
+ * Initializes the authorization subsystem from the config store.
+ * Load Authorization manager plugins, create and initialize
+ * initialize authorization manager instances.
+ * @param owner The owner of this module.
+ * @param config The configuration store.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ try {
+ mLogger = CMS.getLogger();
+ mConfig = config;
+
+ // get authz manager plugins.
+
+ IConfigStore c = config.getSubStore(PROP_IMPL);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+
+ AuthzMgrPlugin plugin = new AuthzMgrPlugin(id, pluginPath);
+
+ mAuthzMgrPlugins.put(id, plugin);
+ }
+ if (Debug.ON) {
+ Debug.trace("loaded authz plugins");
+ }
+
+ // get authz manager instances.
+
+ c = config.getSubStore(PROP_INSTANCE);
+ Enumeration instances = c.getSubStoreNames();
+
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." + PROP_PLUGIN);
+ AuthzMgrPlugin plugin =
+ (AuthzMgrPlugin) mAuthzMgrPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_FOUND", implName));
+ throw new EAuthzMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_PLUGIN_NOT_FOUND", implName));
+ } else {
+ CMS.debug(
+ CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_FOUND", implName));
+ }
+
+ String className = plugin.getClassPath();
+
+ boolean isEnable = false;
+ // Instantiate and init the authorization manager.
+ IAuthzManager authzMgrInst = null;
+
+ try {
+ authzMgrInst = (IAuthzManager)
+ Class.forName(className).newInstance();
+ IConfigStore authzMgrConfig = c.getSubStore(insName);
+
+ authzMgrInst.init(insName, implName, authzMgrConfig);
+ isEnable = true;
+
+ log(ILogger.LL_INFO,
+ CMS.getLogMessage("CMSCORE_AUTHZ_INSTANCE_ADDED", insName));
+ } catch (ClassNotFoundException e) {
+ String errMsg = "AuthzSubsystem:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", errMsg));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ } catch (IllegalAccessException e) {
+ String errMsg = "AuthzSubsystem:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", errMsg));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ } catch (InstantiationException e) {
+ String errMsg = "AuthzSubsystem: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", errMsg));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_INIT_FAILED", insName, e.toString()));
+ // it is mis-configurated. This give
+ // administrator another chance to
+ // fix the problem via console
+ } catch (Throwable e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_INIT_FAILED", insName, e.toString()));
+ // Skip the authorization instance if
+ // it is mis-configurated. This give
+ // administrator another chance to
+ // fix the problem via console
+ }
+ // add manager instance to list.
+ mAuthzMgrInsts.put(insName, new
+ AuthzManagerProxy(isEnable, authzMgrInst));
+ if (Debug.ON) {
+ Debug.trace("loaded authz instance " + insName + " impl " + implName);
+ }
+ }
+ } catch (EBaseException ee) {
+ if (CMS.isPreOpMode())
+ return;
+ throw ee;
+ }
+
+ log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", getId()));
+ }
+
+ /**
+ * authMgrzAccessInit is for servlets who want to initialize their
+ * own authorization information before full operation. It is supposed
+ * to be called during the init() method of a servlet.
+ * @param authzMgrName The authorization manager name
+ * @param accessInfo the access information to be initialized. currently it's acl string in the format specified in the authorization manager
+ */
+ public void authzMgrAccessInit(String authzMgrInstName, String accessInfo)
+ throws EAuthzMgrNotFound, EBaseException {
+ AuthzManagerProxy proxy = (AuthzManagerProxy)
+ mAuthzMgrInsts.get(authzMgrInstName);
+
+ if (proxy == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ if (!proxy.isEnable()) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ IAuthzManager authzMgrInst = proxy.getAuthzManager();
+
+ if (authzMgrInst == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+
+ authzMgrInst.accessInit(accessInfo);
+ }
+
+ /**
+ * Authorization to the named authorization manager instance
+ * @param authzMgrName The authorization manager name
+ * @param authToken the authenticaton token associated with a user
+ * @param resource the resource protected by the authorization system
+ * @param operation the operation for resource protected by the authoriz
+ n system
+ * @exception EBaseException If an error occurs during authorization.
+ * @return a authorization token.
+ */
+ public AuthzToken authorize(
+ String authzMgrInstName, IAuthToken authToken,
+ String resource, String operation)
+ throws EAuthzMgrNotFound, EBaseException {
+
+ AuthzManagerProxy proxy = (AuthzManagerProxy)
+ mAuthzMgrInsts.get(authzMgrInstName);
+
+ if (proxy == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ if (!proxy.isEnable()) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ IAuthzManager authzMgrInst = proxy.getAuthzManager();
+
+ if (authzMgrInst == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ return (authzMgrInst.authorize(authToken, resource, operation));
+ }
+
+ public AuthzToken authorize(
+ String authzMgrInstName, IAuthToken authToken, String exp)
+ throws EAuthzMgrNotFound, EBaseException {
+
+ AuthzManagerProxy proxy = (AuthzManagerProxy)
+ mAuthzMgrInsts.get(authzMgrInstName);
+
+ if (proxy == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ if (!proxy.isEnable()) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ IAuthzManager authzMgrInst = proxy.getAuthzManager();
+
+ if (authzMgrInst == null) {
+ throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName));
+ }
+ return (authzMgrInst.authorize(authToken, exp));
+ }
+
+ /**
+ * Gets configuration parameters for the given
+ * authorization manager plugin.
+ * @param implName Name of the authorization plugin.
+ * @return Hashtable of required parameters.
+ */
+ public String[] getConfigParams(String implName)
+ throws EAuthzMgrPluginNotFound, EBaseException {
+ // is this a registered implname?
+ AuthzMgrPlugin plugin = (AuthzMgrPlugin) mAuthzMgrPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_FOUND", implName));
+ throw new EAuthzMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_PLUGIN_NOT_FOUND", implName));
+ }
+
+ // a temporary instance
+ IAuthzManager authzMgrInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ authzMgrInst = (IAuthzManager)
+ Class.forName(className).newInstance();
+ return (authzMgrInst.getConfigParams());
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_CREATED", e.toString()));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_CREATED", e.toString()));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_CREATED", e.toString()));
+ throw new
+ EAuthzException(CMS.getUserMessage("CMS_AUTHORIZATION_LOAD_CLASS_FAIL", className));
+ }
+ }
+
+ /**
+ * Add an authorization manager instance.
+ * @param name name of the authorization manager instance
+ * @param authzMgr the authorization manager instance to be added
+ */
+ public void add(String name, IAuthzManager authzMgrInst) {
+ mAuthzMgrInsts.put(name, new AuthzManagerProxy(true, authzMgrInst));
+ }
+
+ /*
+ * Removes a authorization manager instance.
+ * @param name name of the authorization manager
+ */
+ public void delete(String name) {
+ mAuthzMgrInsts.remove(name);
+ }
+
+ /**
+ * Gets the authorization manager instance of the specified name.
+ * @param name name of the authorization manager instance
+ * @return the named authorization manager instance
+ */
+ public IAuthzManager get(String name) {
+ AuthzManagerProxy proxy = (AuthzManagerProxy) mAuthzMgrInsts.get(name);
+
+ if (proxy == null)
+ return null;
+ return proxy.getAuthzManager();
+ }
+
+ /**
+ * Enumerate all authorization manager instances.
+ */
+ public Enumeration getAuthzManagers() {
+ Vector inst = new Vector();
+ Enumeration e = mAuthzMgrInsts.keys();
+
+ while (e.hasMoreElements()) {
+ IAuthzManager p = get((String) e.nextElement());
+
+ if (p != null) {
+ inst.addElement(p);
+ }
+ }
+ return (inst.elements());
+ }
+
+ /**
+ * Enumerate all registered authorization manager plugins.
+ */
+ public Enumeration getAuthzManagerPlugins() {
+ return (mAuthzMgrPlugins.elements());
+ }
+
+ /**
+ * retrieve a single authz manager plugin by name
+ */
+ public AuthzMgrPlugin getAuthzManagerPluginImpl(String name) {
+ return (AuthzMgrPlugin) mAuthzMgrPlugins.get(name);
+ }
+
+ /**
+ * Retrieve a single authz manager instance
+ */
+
+ /* getconfigparams above should be recoded to use this func */
+ public IAuthzManager getAuthzManagerPlugin(String name) {
+ AuthzMgrPlugin plugin = (AuthzMgrPlugin) mAuthzMgrPlugins.get(name);
+ String classpath = plugin.getClassPath();
+ IAuthzManager authzMgrInst = null;
+
+ try {
+ authzMgrInst = (IAuthzManager) Class.forName(classpath).newInstance();
+ return (authzMgrInst);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTHZ_PLUGIN_NOT_CREATED", e.toString()));
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves id (name) of this subsystem.
+ * @return name of the authorization subsystem
+ */
+ public String getId() {
+ return (mId);
+ }
+
+ /**
+ * Sets id string to this subsystem.
+ * <p>
+ * Use with caution. Should not do it when sharing with others
+ * @param id name to be applied to an authorization sybsystem
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * registers the administration servlet with the administration subsystem.
+ */
+ public void startup() throws EBaseException {
+ //remove the log since it's already logged from S_ADMIN
+ //String infoMsg = "Authz subsystem administration Servlet registered";
+ //log(ILogger.LL_INFO, infoMsg);
+ }
+
+ /**
+ * shuts down authorization managers one by one.
+ * <P>
+ */
+ public void shutdown() {
+ for (Enumeration e = mAuthzMgrInsts.keys();
+ e.hasMoreElements();) {
+
+ IAuthzManager mgr = (IAuthzManager) get((String) e.nextElement());
+
+ String infoMsg =
+ "Shutting down authz manager instance " + mgr.getName();
+
+ //log(ILogger.LL_INFO, infoMsg);
+
+ mgr.shutdown();
+ }
+ mAuthzMgrPlugins.clear();
+ mAuthzMgrInsts.clear();
+ mAuthzMgrPlugins = null;
+ mAuthzMgrInsts = null;
+ }
+
+ public Hashtable getPlugins() {
+ return mAuthzMgrPlugins;
+ }
+
+ public Hashtable getInstances() {
+ return mAuthzMgrInsts;
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the named authorization manager
+ * @param name of the authorization manager
+ * @return the named authorization manager
+ */
+ public IAuthzManager getAuthzManager(String name) {
+ return ((IAuthzManager) get(name));
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHORIZATION,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/ArgBlock.java b/pki/base/common/src/com/netscape/cmscore/base/ArgBlock.java
new file mode 100644
index 000000000..2e0d19201
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/ArgBlock.java
@@ -0,0 +1,712 @@
+// --- 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.cmscore.base;
+
+
+import java.util.*;
+import java.io.*;
+import netscape.security.pkcs.*;
+import java.security.*;
+import java.math.BigInteger;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * This class represents a set of indexed arguments.
+ * Each argument is indexed by a key, which can be
+ * used during the argument retrieval.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ArgBlock implements IArgBlock {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String
+ CERT_NEW_REQUEST_HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String
+ CERT_NEW_REQUEST_TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ public static final String
+ CERT_REQUEST_HEADER = "-----BEGIN CERTIFICATE REQUEST-----";
+ public static final String
+ CERT_REQUEST_TRAILER = "-----END CERTIFICATE REQUEST-----";
+ public static final String
+ CERT_RENEWAL_HEADER = "-----BEGIN RENEWAL CERTIFICATE REQUEST-----";
+ public static final String
+ CERT_RENEWAL_TRAILER = "-----END RENEWAL CERTIFICATE REQUEST-----";
+
+ private Hashtable mArgs = new Hashtable();
+
+ private String mType = "unspecified-argblock";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ /**
+ * Constructs an argument block with the given hashtable values.
+ * @param realm the type of argblock - used for debugging the values
+ */
+ public ArgBlock(String realm, Hashtable httpReq) {
+ mType = realm;
+ populate(httpReq);
+ }
+
+ /**
+ * Constructs an argument block with the given hashtable values.
+ *
+ * @param httpReq hashtable keys and values
+ */
+ public ArgBlock(Hashtable httpReq) {
+ populate(httpReq);
+ }
+
+ private void populate(Hashtable httpReq) {
+ // Add all parameters from the request
+ Enumeration e = httpReq.keys();
+
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String value = (String) httpReq.get(name);
+
+ addStringValue(name, value);
+ }
+ }
+ }
+
+ /**
+ * Constructs an empty argument block.
+ */
+ public ArgBlock() {
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Checks if this argument block contains the given key.
+ *
+ * @param n key
+ * @return true if key is present
+ */
+ public boolean isValuePresent(String n) {
+ CMS.traceHashKey(mType, n);
+ if (mArgs.get(n) != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Adds string-based value into this argument block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addStringValue(String n, String v) {
+ if (v == null) {
+ return mArgs.put(n, Character.valueOf((char) 0));
+ } else {
+ return mArgs.put(n, v);
+ }
+ }
+
+ /**
+ * Retrieves argument value as string.
+ *
+ * @param n key
+ * @return argument value as string
+ * @exception EBaseException failed to retrieve value
+ */
+ public String getValueAsString(String n) throws EBaseException {
+ String t= (String)mArgs.get(n);
+ CMS.traceHashKey(mType, n, t);
+
+ if (t != null) {
+ return t;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", n));
+ }
+ }
+
+ /**
+ * Retrieves argument value as string.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as string
+ */
+ public String getValueAsString(String n, String def) {
+ String val = (String) mArgs.get(n);
+ CMS.traceHashKey(mType, n, val, def);
+
+ if (val != null) {
+ return val;
+ } else {
+ return def;
+ }
+ }
+
+ /**
+ * Retrieves argument value as integer.
+ *
+ * @param n key
+ * @return argument value as int
+ * @exception EBaseException failed to retrieve value
+ */
+ public int getValueAsInt(String n) throws EBaseException {
+ if (mArgs.get(n) != null) {
+ CMS.traceHashKey(mType, n, (String)mArgs.get(n));
+ try {
+ return new Integer((String) mArgs.get(n)).intValue();
+ } catch (NumberFormatException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_TYPE", n, e.toString()));
+ }
+ } else {
+ CMS.traceHashKey(mType, n, "<notpresent>");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", n));
+ }
+ }
+
+ /**
+ * Retrieves argument value as integer.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as int
+ */
+ public int getValueAsInt(String n, int def) {
+ CMS.traceHashKey(mType, n, (String)mArgs.get(n), ""+def);
+ if (mArgs.get(n) != null) {
+ try {
+ return new Integer((String) mArgs.get(n)).intValue();
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ } else {
+ return def;
+ }
+ }
+
+ /**
+ * Retrieves argument value as big integer.
+ *
+ * @param n key
+ * @return argument value as big integer
+ * @exception EBaseException failed to retrieve value
+ */
+ public BigInteger getValueAsBigInteger(String n)
+ throws EBaseException {
+ String v = (String) mArgs.get(n);
+
+ if (v != null) {
+ try {
+ return new BigInteger(v, 10);
+ } catch (NumberFormatException e) {
+ try {
+ return new BigInteger(v, 16);
+ } catch (NumberFormatException ex) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_TYPE", n, ex.toString()));
+ }
+ }
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", n));
+ }
+ }
+
+ /**
+ * Retrieves argument value as big integer.
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as big integer
+ */
+ public BigInteger getValueAsBigInteger(String n, BigInteger def) {
+ try {
+ return getValueAsBigInteger(n);
+ } catch (EBaseException e) {
+ return def;
+ }
+ }
+
+ /**
+ * Retrieves argument value as object
+ *
+ * @param n key
+ * @return argument value as object
+ * @exception EBaseException failed to retrieve value
+ */
+ public Object getValue(Object n) throws EBaseException {
+ if (mArgs.get(n) != null) {
+ return mArgs.get(n);
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", (String) n));
+ }
+ }
+
+ /**
+ * Retrieves argument value as object
+ *
+ * @param n key
+ * @param def default value to be returned if key is not present
+ * @return argument value as object
+ */
+ public Object getValue(Object n, Object def) {
+ if (mArgs.get(n) != null) {
+ return mArgs.get(n);
+ } else {
+ return def;
+ }
+ }
+
+ /**
+ * Gets boolean value. They should be "true" or "false".
+ *
+ * @param name name of the input type
+ * @return boolean type: <code>true</code> or <code>false</code>
+ * @exception EBaseException failed to retrieve value
+ */
+ public boolean getValueAsBoolean(String name) throws EBaseException {
+ String val = (String) mArgs.get(name);
+ CMS.traceHashKey(mType, name, val);
+
+ if (val != null) {
+ if (val.equalsIgnoreCase("true") ||
+ val.equalsIgnoreCase("on"))
+ return true;
+ else
+ return false;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", name));
+ }
+ }
+
+ /**
+ * Gets boolean value. They should be "true" or "false".
+ *
+ * @param name name of the input type
+ * @return boolean type: <code>true</code> or <code>false</code>
+ */
+ public boolean getValueAsBoolean(String name, boolean def) {
+ boolean val;
+
+ try {
+ val = getValueAsBoolean(name);
+ return val;
+ } catch (EBaseException e) {
+ return def;
+ }
+ }
+
+ /**
+ * Gets KeyGenInfo
+ *
+ * @param name name of the input type
+ * @param verify true if signature validation is required
+ * @exception EBaseException
+ * @return KeyGenInfo object
+ */
+ public KeyGenInfo getValueAsKeyGenInfo(String name, KeyGenInfo def)
+ throws EBaseException {
+ KeyGenInfo keyGenInfo;
+
+ CMS.traceHashKey(mType, name);
+ if (mArgs.get(name) != null) {
+ try {
+ keyGenInfo = new KeyGenInfo((String) mArgs.get(name));
+ } catch (IOException e) {
+ return def;
+ }
+
+ } else {
+ return def;
+ }
+ return keyGenInfo;
+ }
+
+ /**
+ * Gets PKCS10 request. This pkcs10 attribute does not
+ * contain header information.
+ *
+ * @param name name of the input type
+ * @return pkcs10 request
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsRawPKCS10(String name) throws EBaseException {
+ PKCS10 request;
+
+ if (mArgs.get(name) != null) {
+ CMS.traceHashKey(mType, name, (String)mArgs.get(name));
+
+ String tempStr = unwrap((String) mArgs.get(name), false);
+
+ if (tempStr == null) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", name, "Empty Content"));
+ }
+ try {
+ request = decodePKCS10(tempStr);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", name, e.toString()));
+ }
+ } else {
+ CMS.traceHashKey(mType, name, "<notpresent>");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", name));
+ }
+
+ return request;
+ }
+
+ /**
+ * Gets PKCS10 request. This pkcs10 attribute does not
+ * contain header information.
+ *
+ * @param name name of the input type
+ * @param def default PKCS10
+ * @return pkcs10 request
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsRawPKCS10(String name, PKCS10 def)
+ throws EBaseException {
+ PKCS10 request;
+
+ CMS.traceHashKey(mType, name);
+ if (mArgs.get(name) != null) {
+
+ String tempStr = unwrap((String) mArgs.get(name), false);
+
+ if (tempStr == null) {
+ return def;
+ }
+ try {
+ request = decodePKCS10(tempStr);
+ } catch (Exception e) {
+ return def;
+ }
+ } else {
+ return def;
+ }
+ return request;
+ }
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param checkheader true if header must be present
+ * @return PKCS10 object
+ * @exception EBaseException failed to retrieve value
+ */
+ public PKCS10 getValueAsPKCS10(String name, boolean checkheader)
+ throws EBaseException {
+ PKCS10 request;
+
+ CMS.traceHashKey(mType, name);
+ if (mArgs.get(name) != null) {
+
+ String tempStr = unwrap((String) mArgs.get(name), checkheader);
+
+ if (tempStr == null) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", name, "Empty Content"));
+ }
+ try {
+ request = decodePKCS10(tempStr);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", name, e.toString()));
+ }
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NOT_FOUND", name));
+ }
+
+ return request;
+ }
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param checkheader true if header must be present
+ * @param def default PKCS10
+ * @return PKCS10 object
+ * @exception EBaseException
+ */
+ public PKCS10 getValueAsPKCS10(
+ String name, boolean checkheader, PKCS10 def)
+ throws EBaseException {
+ PKCS10 request;
+
+ CMS.traceHashKey(mType, name);
+
+ if (mArgs.get(name) != null) {
+
+ String tempStr = unwrap((String) mArgs.get(name), checkheader);
+
+ if (tempStr == null) {
+ return def;
+ }
+ try {
+ request = decodePKCS10(tempStr);
+ } catch (Exception e) {
+ return def;
+ }
+ } else {
+ return def;
+ }
+
+ return request;
+ }
+
+ /**
+ * Retrieves PKCS10
+ *
+ * @param name name of the input type
+ * @param def default PKCS10
+ * @return PKCS10 object
+ * @exception EBaseException
+ */
+ public PKCS10 getValuePKCS10(String name, PKCS10 def)
+ throws EBaseException {
+ PKCS10 request;
+ String p10b64 = (String) mArgs.get(name);
+ CMS.traceHashKey(mType, name);
+
+ if (p10b64 != null) {
+
+ try {
+ request = decodePKCS10(p10b64);
+ return request;
+ } catch (Exception e) {
+ return def;
+ }
+ } else {
+ return def;
+ }
+ }
+
+ /**
+ * Sets argument into this block.
+ *
+ * @param name key
+ * @param ob value
+ */
+ public void set(String name, Object ob) {
+ mArgs.put(name, ob);
+ }
+
+ /**
+ * Retrieves argument.
+ *
+ * @param name key
+ * @return object value
+ */
+ public Object get(String name) {
+ CMS.traceHashKey(mType, name);
+ return mArgs.get(name);
+ }
+
+ /**
+ * Deletes argument by the given key.
+ *
+ * @param name key
+ */
+ public void delete(String name) {
+ mArgs.remove(name);
+ }
+
+ /**
+ * Retrieves a list of argument keys.
+ *
+ * @return a list of string-based keys
+ */
+ public Enumeration getElements() {
+ return mArgs.keys();
+ }
+
+ /**
+ * Retrieves a list of argument keys.
+ *
+ * @return a list of string-based keys
+ */
+ public Enumeration elements() {
+ return mArgs.keys();
+ }
+
+ /**
+ * Adds long-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addLongValue(String n, long v) {
+ return mArgs.put(n, Long.valueOf(v));
+ }
+
+ /**
+ * Adds integer-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addIntegerValue(String n, int v) {
+ return mArgs.put(n, Integer.valueOf(v));
+ }
+
+ /**
+ * Adds boolean-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @return value
+ */
+ public Object addBooleanValue(String n, boolean v) {
+ if (v) {
+ return mArgs.put(n, new Boolean("true"));
+ } else {
+ return mArgs.put(n, new Boolean("false"));
+ }
+ }
+
+ /**
+ * Adds integer-type arguments to this block.
+ *
+ * @param n key
+ * @param v value
+ * @param radix radix
+ * @return value
+ */
+ public Object addBigIntegerValue(String n, BigInteger v, int radix) {
+ return mArgs.put(n, v.toString(radix));
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+
+ /**
+ * Unwrap PKCS10 Package
+ *
+ * @param request string formated PKCS10 request
+ * @exception EBaseException
+ * @return Base64Encoded PKCS10 request
+ */
+ private String unwrap(String request, boolean checkHeader)
+ throws EBaseException {
+ String unwrapped;
+ String header = null;
+ int head = -1;
+ int trail = -1;
+
+ // check for "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_NEW_REQUEST_HEADER);
+ trail = request.indexOf(CERT_NEW_REQUEST_TRAILER);
+
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_NEW_REQUEST_HEADER;
+ }
+ }
+
+ // check for "-----BEGIN CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_REQUEST_HEADER);
+ trail = request.indexOf(CERT_REQUEST_TRAILER);
+
+ // If this is not a request header, check if this is a renewal
+ // header.
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_REQUEST_HEADER;
+
+ }
+ }
+
+ // check for "-----BEGIN RENEWAL CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_RENEWAL_HEADER);
+ trail = request.indexOf(CERT_RENEWAL_TRAILER);
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_RENEWAL_HEADER;
+ }
+ }
+
+ // Now validate if any headers or trailers are in place
+ if (head == -1 && checkHeader) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_MISSING_PKCS10_HEADER"));
+ }
+ if (trail == -1 && checkHeader) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_MISSING_PKCS10_TRAILER"));
+ }
+
+ if (header != null) {
+ unwrapped = request.substring(head + header.length(), trail);
+ } else {
+ unwrapped = request;
+ }
+
+ // strip all the crtl-characters (i.e. \r\n)
+ StringTokenizer st = new StringTokenizer(unwrapped, "\t\r\n ");
+ StringBuffer stripped = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ stripped.append(st.nextToken());
+ }
+
+ return stripped.toString();
+ }
+
+ /**
+ * Decode Der encoded PKCS10 certifictae Request
+ *
+ * @param base64Request Base64 Encoded Certificate Request
+ * @exception Exception
+ * @return PKCS10
+ */
+ private PKCS10 decodePKCS10(String base64Request)
+ throws EBaseException {
+ PKCS10 pkcs10 = null;
+
+ try {
+ byte[] decodedBytes = com.netscape.osutil.OSUtil.AtoB(base64Request);
+
+ pkcs10 = new PKCS10(decodedBytes);
+ } catch (NoSuchProviderException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (SignatureException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ return pkcs10;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/FileConfigStore.java b/pki/base/common/src/com/netscape/cmscore/base/FileConfigStore.java
new file mode 100644
index 000000000..79bb60c67
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/FileConfigStore.java
@@ -0,0 +1,213 @@
+// --- 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.cmscore.base;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmsutil.util.Utils;
+
+
+/**
+ * FileConfigStore:
+ * Extends HashConfigStore with methods to load/save from/to file for
+ * persistent storage. This is a configuration store agent who
+ * reads data from a file.
+ * <P>
+ * Note that a LdapConfigStore can be implemented so that it reads
+ * the configuration stores from the Ldap directory.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see PropConfigStore
+ */
+public class FileConfigStore extends PropConfigStore implements
+ IConfigStore {
+
+ private File mFile = null;
+
+ /**
+ * Constructs a file configuration store.
+ * <P>
+ *
+ * @param fileName file name
+ * @exception EBaseException failed to create file configuration
+ */
+ public FileConfigStore(String fileName) throws EBaseException {
+ super(null); // top-level store without a name
+ mFile = new File(fileName);
+ if (!mFile.exists()) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NO_CONFIG_FILE",
+ mFile.getPath()));
+ }
+ load(fileName);
+ }
+
+ /**
+ * Loads property file into memory.
+ * <P>
+ *
+ * @param fileName file name
+ * @exception EBaseException failed to load configuration
+ */
+ public void load(String fileName) throws EBaseException {
+ try {
+ FileInputStream fi = new FileInputStream(fileName);
+ BufferedInputStream bis = new BufferedInputStream(fi);
+
+ super.load(bis);
+ } catch (IOException e) {
+ throw new EBaseException("input stream error " + fileName, e);
+ }
+ }
+
+ /**
+ * The original config file is copied to
+ * <filename>.<current_time_in_milliseconds>.
+ * Commits the current properties to the configuration file.
+ * <P>
+ *
+ * @param backup
+ */
+ public void commit(boolean createBackup) throws EBaseException {
+ if (createBackup) {
+ File newName = new File(mFile.getPath() + "." +
+ Long.toString(System.currentTimeMillis()));
+
+ try {
+ if( Utils.isNT() ) {
+ // NT is very picky on the path
+ Utils.exec( "copy " +
+ mFile.getAbsolutePath().replace( '/', '\\' ) +
+ " " +
+ newName.getAbsolutePath().replace( '/',
+ '\\' ) );
+ } else {
+ // Create a copy of the original file which
+ // preserves the original file permissions.
+ Utils.exec( "cp -p " + mFile.getAbsolutePath() + " " +
+ newName.getAbsolutePath() );
+ }
+
+ // Proceed only if the backup copy was successful.
+ if( !newName.exists() ) {
+ throw new EBaseException( "backup copy failed" );
+ } else {
+ // Make certain that the backup file has
+ // the correct permissions.
+ if( !Utils.isNT() ) {
+ Utils.exec( "chmod 00660 " + newName.getAbsolutePath() );
+ }
+ }
+ } catch( EBaseException e ) {
+ throw new EBaseException( "backup copy failed" );
+ }
+ }
+
+ // Overwrite the contents of the original file
+ // to preserve the original file permissions.
+ save( mFile.getPath() );
+
+ try {
+ // Make certain that the original file retains
+ // the correct permissions.
+ if( !Utils.isNT() ) {
+ Utils.exec( "chmod 00660 " + mFile.getCanonicalPath() );
+ }
+ } catch( Exception e ) {
+ }
+ }
+
+ /**
+ * Saves in-memory properties to a specified file.
+ * <P>
+ * Note that the superclass's save is synchronized. It
+ * means no properties can be altered (inserted) at
+ * the saving time.
+ * <P>
+ *
+ * @param fileName filename
+ * @exception EBaseException failed to save configuration
+ */
+ public void save(String fileName) throws EBaseException {
+ try {
+ FileOutputStream fo = new FileOutputStream(fileName);
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(fo));
+
+ printSubStore(writer, this, "");
+ writer.close();
+ fo.close();
+ } catch (IOException e) {
+ throw new EBaseException("output stream error " + fileName, e);
+ }
+ }
+
+ private void printSubStore(PrintWriter writer, IConfigStore store,
+ String name) throws EBaseException,
+ IOException {
+ // print keys
+ Enumeration e0 = store.getPropertyNames();
+ Vector v = new Vector();
+
+ while (e0.hasMoreElements()) {
+ v.addElement(e0.nextElement());
+ }
+
+ // sorting them lexicographically
+ while (v.size() > 0) {
+ String pname = (String) v.firstElement();
+ int j = 0;
+
+ for (int i = 1; i < v.size(); i++) {
+ String s = (String) v.elementAt(i);
+
+ if (pname.compareTo(s) > 0) {
+ j = i;
+ pname = (String) v.elementAt(i);
+ }
+ }
+ v.removeElementAt(j);
+ writer.println(name + pname + "=" + store.getString(pname));
+ }
+
+ // print substores
+ Enumeration e1 = store.getSubStoreNames();
+
+ while (e1.hasMoreElements()) {
+ v.addElement(e1.nextElement());
+ }
+ while (v.size() > 0) {
+ String pname = (String) v.firstElement();
+ int j = 0;
+
+ for (int i = 1; i < v.size(); i++) {
+ String s = (String) v.elementAt(i);
+
+ if (pname.compareTo(s) > 0) {
+ j = i;
+ pname = (String) v.elementAt(i);
+ }
+ }
+ v.removeElementAt(j);
+ printSubStore(writer, store.getSubStore(pname), name +
+ pname + ".");
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java b/pki/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java
new file mode 100644
index 000000000..93d88a550
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java
@@ -0,0 +1,256 @@
+// --- 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.cmscore.base;
+
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.CryptoToken;
+import javax.swing.border.EmptyBorder;
+
+
+/**
+ * A class to retrieve passwords through a modal Java dialog box
+ */
+public class JDialogPasswordCallback implements PasswordCallback {
+
+ public Password getPasswordFirstAttempt(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+ return getPW(info, false);
+ }
+
+ public Password getPasswordAgain(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+ return getPW(info, true);
+ }
+
+ // This structure holds information local to a getPW() call, for use
+ // by action listeners
+ private static class PWHolder {
+ public Password password = null;
+ public boolean cancelled = true;
+ }
+
+ private void resetGBC(GridBagConstraints gbc) {
+ gbc.gridx = gbc.RELATIVE;
+ gbc.gridy = gbc.RELATIVE;
+ gbc.gridwidth = 1;
+ gbc.gridheight = 1;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.anchor = gbc.CENTER;
+ gbc.ipadx = 0;
+ gbc.ipady = 0;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ }
+
+ /**
+ * This function can be overriden if different heading is required.
+ */
+ public String getPrompt(PasswordCallbackInfo info) {
+ return "Enter the password for \"" + info.getName() + "\": ";
+ }
+
+ /**
+ * This method does the work of displaying the dialog box,
+ * extracting the information, and returning it.
+ */
+ private Password getPW(PasswordCallbackInfo info, boolean retry)
+ throws PasswordCallback.GiveUpException {
+ // These need to final so they can be accessed from action listeners
+ final PWHolder pwHolder = new PWHolder();
+ final JFrame f = new JFrame("Password Dialog");
+ final JPasswordField pwField = new JPasswordField(15);
+
+ ///////////////////////////////////////////////////
+ // Panel
+ ///////////////////////////////////////////////////
+ JPanel contentPane = new JPanel(new GridBagLayout());
+
+ contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ GridBagConstraints c = new GridBagConstraints();
+
+ ////////////////////////////////////////////////////
+ // Labels
+ ////////////////////////////////////////////////////
+
+ if (retry) {
+ JLabel warning = new JLabel("Password incorrect.");
+
+ warning.setForeground(Color.red);
+ resetGBC(c);
+ c.anchor = c.NORTHWEST;
+ c.gridwidth = c.REMAINDER;
+ // Setting this to NULL causes nasty Exception stack traces
+ // to be printed, although the program still seems to work
+ //warning.setHighlighter(null);
+ contentPane.add(warning, c);
+ }
+
+ String prompt = getPrompt(info);
+ JLabel label = new JLabel(prompt);
+
+ label.setForeground(Color.black);
+ // Setting this to NULL causes nasty Exception stack traces
+ // to be printed, although the program still seems to work
+ //label.setHighlighter(null);
+ resetGBC(c);
+ c.anchor = c.NORTHWEST;
+ c.gridwidth = c.REMAINDER;
+ contentPane.add(label, c);
+
+ ///////////////////////////////////////////////////
+ // Password text field
+ ///////////////////////////////////////////////////
+
+ // Listener for the text field
+ ActionListener getPasswordListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ //input = (JPasswordField)e.getSource();
+
+ // XXX!!! Change to char[] in JDK 1.2
+ String pwString = pwField.getText();
+
+ pwHolder.password = new Password(pwString.toCharArray());
+ pwHolder.cancelled = false;
+ f.dispose();
+ }
+ };
+
+ // There is a bug in JPasswordField. The cursor is advanced by the
+ // width of the character you type, but a '*' is echoed, so the
+ // cursor does not stay lined up with the end of the text.
+ // We use a monospaced font to workaround this.
+
+ pwField.setFont(new Font("Monospaced", Font.PLAIN,
+ pwField.getFont().getSize()));
+ pwField.setEchoChar('*');
+ pwField.addActionListener(getPasswordListener);
+ resetGBC(c);
+ c.anchor = c.CENTER;
+ c.fill = c.NONE;
+ c.insets = new Insets(16, 0, 0, 0);
+ c.gridwidth = c.REMAINDER;
+ //c.gridy++;
+ contentPane.add(pwField, c);
+
+ ///////////////////////////////////////////////////
+ // Cancel button
+ ///////////////////////////////////////////////////
+
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+
+ JButton ok = new JButton(" OK ");
+
+ ok.addActionListener(getPasswordListener);
+ resetGBC(c);
+ c.fill = c.NONE;
+ c.anchor = c.CENTER;
+ c.gridheight = c.REMAINDER;
+ c.insets = new Insets(10, 0, 0, 4);
+ buttonPanel.add(ok, c);
+
+ JButton cancel = new JButton("Cancel");
+ ActionListener buttonListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ pwHolder.cancelled = true;
+ f.dispose();
+ }
+ };
+
+ cancel.addActionListener(buttonListener);
+ resetGBC(c);
+ c.fill = c.NONE;
+ c.anchor = c.CENTER;
+ c.insets = new Insets(10, 4, 0, 0);
+ c.gridheight = c.REMAINDER;
+ c.gridwidth = c.REMAINDER;
+ buttonPanel.add(cancel, c);
+
+ resetGBC(c);
+ c.fill = c.NONE;
+ c.anchor = c.CENTER;
+ c.gridwidth = c.REMAINDER;
+ c.gridheight = c.REMAINDER;
+ c.insets = new Insets(0, 0, 0, 0);
+ contentPane.add(buttonPanel, c);
+
+ ///////////////////////////////////////////////////
+ // Create modal dialog
+ ///////////////////////////////////////////////////
+ JDialog d = new JDialog(f, "Fedora Certificate System", true);
+
+ WindowListener windowListener = new WindowAdapter() {
+ public void windowOpened(WindowEvent e) {
+ pwField.requestFocus();
+ }
+ };
+
+ d.addWindowListener(windowListener);
+
+ d.setContentPane(contentPane);
+ d.pack();
+ Dimension screenSize = d.getToolkit().getScreenSize();
+ Dimension paneSize = d.getSize();
+
+ d.setLocation((screenSize.width - paneSize.width) / 2,
+ (screenSize.height - paneSize.height) / 2);
+ d.getRootPane().setDefaultButton(ok);
+
+ // toFront seems to cause the dialog to go blank on unix!
+ //d.toFront();
+
+ d.show();
+
+ ///////////////////////////////////////////////////
+ // Return results
+ ///////////////////////////////////////////////////
+ if (pwHolder.cancelled) {
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ return pwHolder.password;
+ }
+
+ // Test program
+ public static void main(String args[]) {
+ try {
+ CryptoManager manager;
+
+ CryptoManager.InitializationValues iv = new
+ CryptoManager.InitializationValues(args[0]);
+
+ CryptoManager.initialize(iv);
+ manager = CryptoManager.getInstance();
+
+ CryptoToken tok = manager.getInternalKeyStorageToken();
+
+ tok.login(new JDialogPasswordCallback());
+ System.out.println("Logged in!!!");
+ System.exit(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/PropConfigStore.java b/pki/base/common/src/com/netscape/cmscore/base/PropConfigStore.java
new file mode 100644
index 000000000..f8dd97aa5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/PropConfigStore.java
@@ -0,0 +1,767 @@
+// --- 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.cmscore.base;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+import org.mozilla.jss.util.Base64OutputStream;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * A class represents a in-memory configuration store.
+ * Note this class takes advantage of the recursive nature of
+ * property names. The current property prefix is kept in
+ * mStoreName and the mSource usually points back to another
+ * occurance of the same PropConfigStore, with longer mStoreName. IE
+ * <PRE>
+ * cms.ca0.http.service0 -> mSource=PropConfigStore ->
+ * cms.ca0.http -> mSource=PropConfigStore ->
+ * cms.ca0 -> mSource=PropConfigStore ->
+ * cms -> mSource=SourceConfigStore -> Properties
+ * </PRE>
+ * The chain ends when the store name is reduced down to it's original
+ * value.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PropConfigStore implements IConfigStore, Cloneable {
+
+ protected static final String PROP_SUBSTORES = "substores";
+
+ /**
+ * The name of this substore
+ */
+ protected String mStoreName = null;
+
+ /**
+ * The source data for this substore
+ */
+ protected ISourceConfigStore mSource = null;
+
+ private static String mDebugType="CS.cfg";
+
+ /**
+ * Constructs a property configuration store. This must
+ * be a brand new store without properties. The subclass
+ * must be a ISourceConfigStore.
+ * <P>
+ *
+ * @param storeName property store name
+ * @exception EBaseException failed to create configuration
+ */
+ public PropConfigStore(String storeName) {
+ mSource = new SourceConfigStore();
+ mStoreName = storeName;
+ }
+
+ /**
+ * Constructs a configuration store. The constructor is
+ * a helper class for substores. Source is the one
+ * that stores all the parameters. Each substore only
+ * store a substore name, and a reference to the source.
+ * <P>
+ *
+ * @param storeName store name
+ * @param prop list of properties
+ * @exception EBaseException failed to create configuration
+ */
+ protected PropConfigStore(String name, ISourceConfigStore source) {
+ mStoreName = name;
+ mSource = source;
+ }
+
+ /**
+ * Returns the name of this store.
+ * <P>
+ *
+ * @return store name
+ */
+ public String getName() {
+ return mStoreName;
+ }
+
+ /**
+ * Retrieves a property from the configuration file.
+ * <P>
+ *
+ * @param name property name
+ * @return property value
+ */
+ public Object get(String name) {
+ return mSource.get(getFullName(name));
+ }
+
+ /**
+ * Retrieves a property from the configuration file. Does not prepend
+ * the config store name to the property.
+ * <P>
+ *
+ * @param name property name
+ * @return property value
+ */
+ private Object nakedGet(String name) {
+ return mSource.get(name);
+ }
+
+ /**
+ * Puts a property into the configuration file. The
+ * values wont be updated to the file until save
+ * method is invoked.
+ * <P>
+ *
+ * @param name property name
+ * @param value property value
+ */
+ public void put(String name, Object value) {
+ mSource.put(getFullName(name), value);
+ }
+
+ /**
+ * Removes a property from the configuration file.
+ *
+ * @param name property name
+ */
+ public void remove(String name) {
+ ((SourceConfigStore) mSource).remove(getFullName(name));
+ }
+
+ /**
+ * Returns an enumeration of the config store's keys, hidding the store
+ * name.
+ * @see java.util.Hashtable#elements
+ * @see java.util.Enumeration
+ */
+ public Enumeration keys() {
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ return h.keys();
+ }
+
+ /**
+ * Retrieves the hashtable where all the properties are kept.
+ *
+ * @return hashtable
+ */
+ public Hashtable hashtable() {
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ return h;
+ }
+
+ /**
+ * Return the number of items in this substore
+ */
+ public int size() {
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ return h.size();
+ }
+
+ /**
+ * Fills the given hash table with all key/value pairs in the current
+ * config store, removing the config store name prefix
+ * <P>
+ *
+ * @param h the hashtable
+ */
+ private synchronized void enumerate(Hashtable h) {
+ Enumeration e = mSource.keys();
+ // We only want the keys which match the current substore name
+ // without the current substore prefix. This code works even
+ // if mStoreName is null.
+ String fullName = getFullName("");
+ int kIndex = fullName.length();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ if (key.startsWith(fullName)) {
+ h.put(key.substring(kIndex), nakedGet(key));
+ }
+ }
+ }
+
+ /**
+ * Reads a config store from an input stream.
+ *
+ * @param in input stream where properties are located
+ * @exception IOException failed to load
+ */
+ public synchronized void load(InputStream in) throws IOException {
+ mSource.load(in);
+ }
+
+ /**
+ * Stores this config store to the specified output stream.
+ *
+ * @param out outputstream where the properties are saved
+ * @param header optional header information to be saved
+ */
+ public synchronized void save(OutputStream out, String header) {
+ mSource.save(out, header);
+ }
+
+ /**
+ * Retrieves a property value.
+ *
+ * @param name property key
+ * @return property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public String getString(String name) throws EBaseException {
+ String str = (String) get(name);
+
+ if (str == null) {
+ CMS.traceHashKey(mDebugType,getFullName(name),"<notpresent>");
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", getName() + "." + name));
+ }
+ // should we check for empty string ?
+ // if (str.length() == 0) {
+ // throw new EPropertyNotDefined(getName() + "." + name);
+ // }
+ String ret = null;
+
+ try {
+ ret = new String(str.getBytes(), "UTF8").trim();
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_UTF8_NOT_SUPPORTED"));
+ }
+ CMS.traceHashKey(mDebugType,getFullName(name),ret);
+ return ret;
+ }
+
+ /**
+ * Retrieves a String from the configuration file.
+ * <P>
+ *
+ * @param name property name
+ * @param defval the default object to return if name does not exist
+ * @return property value
+ */
+ public String getString(String name, String defval) throws EBaseException {
+ String val;
+
+ try {
+ val = getString(name);
+ } catch (EPropertyNotFound e) {
+ val = defval;
+ }
+ CMS.traceHashKey(mDebugType,getFullName(name),val,defval);
+ return val;
+ }
+
+ /**
+ * Puts property value into this configuration store.
+ *
+ * @param name property key
+ * @param value property value
+ */
+ public void putString(String name, String value) {
+ put(name, value);
+ }
+
+ /**
+ * Retrieves a byte array from the configuration file.
+ * <P>
+ *
+ * @param name property name
+ * @exception IllegalArgumentException if name is not set or is null.
+ *
+ * @return property value
+ */
+ public byte[] getByteArray(String name) throws EBaseException {
+ byte[] arr = getByteArray(name, new byte[0]);
+
+ if (arr.length == 0) {
+ CMS.traceHashKey(mDebugType,getFullName(name),"<notpresent>");
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", getName() + "." + name));
+ }
+ return arr;
+ }
+
+ /**
+ * Retrieves a byte array from the configuration file.
+ * <P>
+ *
+ * @param name property name
+ * @param defval the default byte array to return if name does
+ * not exist
+ *
+ * @return property value
+ */
+ public byte[] getByteArray(String name, byte defval[])
+ throws EBaseException {
+ String str = (String) get(name);
+
+ byte returnval;
+
+ if (str == null || str.length() == 0) {
+ CMS.traceHashKey(mDebugType,getFullName(name),
+ "<notpresent>","<bytearray>");
+ return defval;
+ }
+ else {
+ CMS.traceHashKey(mDebugType,getFullName(name),
+ "<bytearray>","<bytearray>");
+ return com.netscape.osutil.OSUtil.AtoB(str);
+ }
+ }
+
+ /**
+ * Puts byte array into this configuration store.
+ *
+ * @param name property key
+ * @param value byte array
+ */
+ public void putByteArray(String name, byte value[]) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(new
+ PrintStream(new FilterOutputStream(output)));
+
+ try {
+ b64.write(value);
+ b64.flush();
+
+ // 8859 contains all the base-64 chars, so there are no
+ // internationalization problems here
+ put(name, output.toString("8859_1"));
+ } catch (IOException e) {
+ System.out.println("Warning: base-64 encoding of configuration " +
+ "information failed");
+ }
+ }
+
+ /**
+ * Retrieves boolean-based property value.
+ *
+ * @param name property key
+ * @return boolean value
+ * @exception EBaseException failed to retrieve
+ */
+ public boolean getBoolean(String name) throws EBaseException {
+ String value = (String) get(name);
+
+ if (value == null) {
+ CMS.traceHashKey(mDebugType,getFullName(name),"<notpresent>");
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", getName() + "." + name));
+ }
+ if (value.length() == 0) {
+ throw new EPropertyNotDefined(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_NOVALUE", getName() + "." + name));
+ }
+
+ if (value.equalsIgnoreCase("true")) {
+ return true;
+ } else if (value.equalsIgnoreCase("false")) {
+ return false;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY_1", getName() + "." + name, "boolean", "\"true\" or \"false\""));
+ }
+ }
+
+ /**
+ * Retrieves boolean-based property value.
+ *
+ * @param name property key
+ * @param defval default value
+ * @return boolean value
+ * @exception EBaseException failed to retrieve
+ */
+ public boolean getBoolean(String name, boolean defval)
+ throws EBaseException {
+ boolean val;
+
+ try {
+ val = getBoolean(name);
+ } catch (EPropertyNotFound e) {
+ val = defval;
+ } catch (EPropertyNotDefined e) {
+ val = defval;
+ }
+ CMS.traceHashKey(mDebugType,getFullName(name),
+ val?"true":"false", defval?"true":"false");
+ return val;
+ }
+
+ /**
+ * Puts boolean value into the configuration store.
+ *
+ * @param name property key
+ * @param value property value
+ */
+ public void putBoolean(String name, boolean value) {
+ if (value) {
+ put(name, "true");
+ } else {
+ put(name, "false");
+ }
+ }
+
+ /**
+ * Retrieves integer value.
+ *
+ * @param name property key
+ * @return property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public int getInteger(String name) throws EBaseException {
+ String value = (String) get(name);
+
+ if (value == null) {
+ CMS.traceHashKey(mDebugType,getFullName(name),"<notpresent>");
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", getName() + "." + name));
+ }
+ if (value.length() == 0) {
+ throw new EPropertyNotDefined(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_NOVALUE", getName() + "." + name));
+ }
+ try {
+ CMS.traceHashKey(mDebugType,getFullName(name), value);
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY_1", getName() + "." + name, "int", "number"));
+ }
+ }
+
+ /**
+ * Retrieves integer value.
+ *
+ * @param name property key
+ * @param defval default value
+ * @return property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public int getInteger(String name, int defval) throws EBaseException {
+ int val;
+
+ try {
+ val = getInteger(name);
+ } catch (EPropertyNotFound e) {
+ val = defval;
+ } catch (EPropertyNotDefined e) {
+ val = defval;
+ }
+ CMS.traceHashKey(mDebugType,getFullName(name),
+ ""+val,""+defval);
+ return val;
+ }
+
+ /**
+ * Puts an integer value.
+ *
+ * @param name property key
+ * @param val property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public void putInteger(String name, int val) {
+ put(name, Integer.toString(val));
+ }
+
+ /**
+ * Retrieves big integer value.
+ *
+ * @param name property key
+ * @return property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public BigInteger getBigInteger(String name) throws EBaseException {
+ String value = (String) get(name);
+
+ if (value == null) {
+ CMS.traceHashKey(mDebugType,getFullName(name),"<notpresent>");
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", getName() + "." + name));
+ }
+ if (value.length() == 0) {
+ throw new EPropertyNotDefined(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_NOVALUE", getName() + "." + name));
+ }
+ try {
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ String val = value.substring(2);
+
+ return new BigInteger(val, 16);
+ }
+ return new BigInteger(value);
+ } catch (NumberFormatException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY_1", getName() + "." + name, "BigInteger", "number"));
+ }
+ }
+
+ /**
+ * Retrieves integer value.
+ *
+ * @param name property key
+ * @param defval default value
+ * @return property value
+ * @exception EBaseException failed to retrieve value
+ */
+ public BigInteger getBigInteger(String name, BigInteger defval)
+ throws EBaseException {
+ BigInteger val;
+
+ try {
+ val = getBigInteger(name);
+ } catch (EPropertyNotFound e) {
+ val = defval;
+ } catch (EPropertyNotDefined e) {
+ val = defval;
+ }
+ return val;
+ }
+
+ /**
+ * Puts a big integer value.
+ *
+ * @param name property key
+ * @param val default value
+ */
+ public void putBigInteger(String name, BigInteger val) {
+ put(name, val.toString());
+ }
+
+ /**
+ * Creates a new sub store.
+ * <P>
+ *
+ * @param name substore name
+ * @return substore
+ */
+ public IConfigStore makeSubStore(String name) {
+
+ /*
+ String names=(String)mSource.get(getFullName(PROP_SUBSTORES));
+
+ if (names==null) {
+ names=name;
+ }
+ else {
+ names=names+","+name;
+ }
+ mSource.put(getFullName(PROP_SUBSTORES), name);
+ */
+ return new PropConfigStore(getFullName(name), mSource);
+ }
+
+ /**
+ * Removes a sub store.<p>
+ *
+ * @param name substore name
+ */
+ public void removeSubStore(String name) {
+ // this operation is expensive!!!
+
+ Enumeration e = mSource.keys();
+ // We only want the keys which match the current substore name
+ // without the current substore prefix. This code works even
+ // if mStoreName is null.
+ String fullName = getFullName(name);
+ int kIndex = fullName.length();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ if (key.startsWith(fullName + ".")) {
+ ((Hashtable) mSource).remove(key);
+ }
+ }
+ }
+
+ /**
+ * Retrieves a sub store. A substore contains a list
+ * of properties and substores. For example,
+ * <PRE>
+ * cms.ldap.host=ds.netscape.com
+ * cms.ldap.port=389
+ * </PRE>
+ * "ldap" is a substore in above example. If the
+ * substore property itself is set, this method
+ * will treat the value as a reference. For example,
+ * <PRE>
+ * cms.ldap=kms.ldap
+ * </PRE>
+ * <P>
+ *
+ * @param name substore name
+ * @return substore
+ */
+ public IConfigStore getSubStore(String name) {
+ String fullname = getFullName(name);
+ String reference = (String) mSource.get(fullname);
+
+ if (reference == null) {
+ PropConfigStore ps = new PropConfigStore(fullname, mSource);
+
+ return ps;
+ } else {
+ PropConfigStore ps = new PropConfigStore(reference, mSource);
+
+ return ps;
+ }
+ }
+
+ /**
+ * Retrieves a list of property names.
+ *
+ * @return a list of string-based property names
+ */
+ public Enumeration getPropertyNames() {
+ // XXX - this operation is expensive!!!
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ Enumeration e = h.keys();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ String pname = (String) e.nextElement();
+ int i = pname.indexOf('.'); // substores have "."
+
+ if (i == -1) {
+ String n = pname;
+
+ if (!v.contains(n)) {
+ v.addElement(n);
+ }
+ }
+ }
+ return v.elements();
+ }
+
+ /**
+ * Returns a list of sub store names.
+ * <P>
+ *
+ * @return list of substore names
+ */
+ public Enumeration getSubStoreNames() {
+ // XXX - this operation is expensive!!!
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ Enumeration e = h.keys();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ String pname = (String) e.nextElement();
+ int i = pname.indexOf('.'); // substores have "."
+
+ if (i != -1) {
+ String n = pname.substring(0, i);
+
+ if (!v.contains(n)) {
+ v.addElement(n);
+ }
+ }
+ }
+ return v.elements();
+ }
+
+ /**
+ * Retrieves the source configuration store where
+ * the properties are stored.
+ * <P>
+ *
+ * @return source configuration store
+ */
+ public ISourceConfigStore getSourceConfigStore() {
+ return mSource;
+ }
+
+ /**
+ * For debugging purposes. Prints properties of this
+ * substore.
+ */
+ public void printProperties() {
+ Enumeration keys = mSource.keys();
+
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+
+ if (mStoreName == null) {
+ System.out.println(key);
+ } else {
+ if (key.startsWith(mStoreName))
+ System.out.println(key);
+ }
+ }
+ }
+
+ /**
+ * Converts the substore parameters.
+ *
+ * @param name property name
+ * @return fill property name
+ */
+ private String getFullName(String name) {
+ if (mStoreName == null)
+ return name;
+ else
+ return mStoreName + "." + name;
+ }
+
+ /**
+ * Cloning of property configuration store.
+ *
+ * @return a new configuration store
+ */
+ public Object clone() {
+ try {
+ PropConfigStore that = (PropConfigStore) super.clone();
+
+ mStoreName = getName();
+ mSource = new SourceConfigStore();
+ Enumeration subs = getSubStoreNames();
+
+ while (subs.hasMoreElements()) {
+ IConfigStore sub = (IConfigStore)
+ subs.nextElement();
+ IConfigStore newSub = that.makeSubStore(
+ sub.getName());
+ Enumeration props = sub.getPropertyNames();
+
+ while (props.hasMoreElements()) {
+ String n = (String) props.nextElement();
+
+ try {
+ newSub.putString(n,
+ sub.getString(n));
+ } catch (EBaseException ex) {
+ }
+ }
+ }
+ return that;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+
+ }
+
+ /**
+ * Commits properties into the file.
+ *
+ * @param createBackup true if create backup
+ * @exception EBaseException failed to commit properties
+ */
+ public void commit(boolean createBackup) throws EBaseException {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/SimpleProperties.java b/pki/base/common/src/com/netscape/cmscore/base/SimpleProperties.java
new file mode 100644
index 000000000..e2584accf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/SimpleProperties.java
@@ -0,0 +1,610 @@
+// --- 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.cmscore.base;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.Date;
+import java.util.Enumeration;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.BufferedWriter;
+import java.util.Hashtable;
+
+
+/**
+ * The <code>Properties</code> class represents a persistent set of
+ * properties. The <code>Properties</code> can be saved to a stream
+ * or loaded from a stream. Each key and its corresponding value in
+ * the property list is a string.
+ * <p>
+ * A property list can contain another property list as its
+ * "defaults"; this second property list is searched if
+ * the property key is not found in the original property list.
+ *
+ * Because <code>Properties</code> inherits from <code>Hashtable</code>, the
+ * <code>put</code> and <code>putAll</code> methods can be applied to a
+ * <code>Properties</code> object. Their use is strongly discouraged as they
+ * allow the caller to insert entries whose keys or values are not
+ * <code>Strings</code>. The <code>setProperty</code> method should be used
+ * instead. If the <code>store</code> or <code>save</code> method is called
+ * on a "compromised" <code>Properties</code> object that contains a
+ * non-<code>String</code> key or value, the call will fail.
+ *
+ */
+public class SimpleProperties extends Hashtable {
+
+ /**
+ * A property list that contains default values for any keys not
+ * found in this property list.
+ *
+ * @serial
+ */
+ protected SimpleProperties defaults;
+
+ /**
+ * Creates an empty property list with no default values.
+ */
+ public SimpleProperties() {
+ this(null);
+ }
+
+ /**
+ * Creates an empty property list with the specified defaults.
+ *
+ * @param defaults the defaults.
+ */
+ public SimpleProperties(SimpleProperties defaults) {
+ this.defaults = defaults;
+ }
+
+ /**
+ * Calls the hashtable method <code>put</code>. Provided for
+ * parallelism with the getProperties method. Enforces use of
+ * strings for property keys and values.
+ * @since JDK1.2
+ */
+ public synchronized Object setProperty(String key, String value) {
+ return put(key, value);
+ }
+
+ private static final String keyValueSeparators = "=: \t\r\n\f";
+
+ private static final String strictKeyValueSeparators = "=:";
+
+ private static final String specialSaveChars = "=: \t\r\n\f#!";
+
+ private static final String whiteSpaceChars = " \t\r\n\f";
+
+ /**
+ * Reads a property list (key and element pairs) from the input stream.
+ * <p>
+ * Every property occupies one line of the input stream. Each line
+ * is terminated by a line terminator (<code>\n</code> or <code>\r</code>
+ * or <code>\r\n</code>). Lines from the input stream are processed until
+ * end of file is reached on the input stream.
+ * <p>
+ * A line that contains only whitespace or whose first non-whitespace
+ * character is an ASCII <code>#</code> or <code>!</code> is ignored
+ * (thus, <code>#</code> or <code>!</code> indicate comment lines).
+ * <p>
+ * Every line other than a blank line or a comment line describes one
+ * property to be added to the table (except that if a line ends with \,
+ * then the following line, if it exists, is treated as a continuation
+ * line, as described
+ * below). The key consists of all the characters in the line starting
+ * with the first non-whitespace character and up to, but not including,
+ * the first ASCII <code>=</code>, <code>:</code>, or whitespace
+ * character. All of the key termination characters may be included in
+ * the key by preceding them with a \.
+ * Any whitespace after the key is skipped; if the first non-whitespace
+ * character after the key is <code>=</code> or <code>:</code>, then it
+ * is ignored and any whitespace characters after it are also skipped.
+ * All remaining characters on the line become part of the associated
+ * element string. Within the element string, the ASCII
+ * escape sequences <code>\t</code>, <code>\n</code>,
+ * <code>\r</code>, <code>\\</code>, <code>\"</code>, <code>\'</code>,
+ * <code>\ &#32;</code> &#32;(a backslash and a space), and
+ * <code>\\u</code><i>xxxx</i> are recognized and converted to single
+ * characters. Moreover, if the last character on the line is
+ * <code>\</code>, then the next line is treated as a continuation of the
+ * current line; the <code>\</code> and line terminator are simply
+ * discarded, and any leading whitespace characters on the continuation
+ * line are also discarded and are not part of the element string.
+ * <p>
+ * As an example, each of the following four lines specifies the key
+ * <code>"Truth"</code> and the associated element value
+ * <code>"Beauty"</code>:
+ * <p>
+ * <pre>
+ * Truth = Beauty
+ * Truth:Beauty
+ * Truth :Beauty
+ * </pre>
+ * As another example, the following three lines specify a single
+ * property:
+ * <p>
+ * <pre>
+ * fruits apple, banana, pear, \
+ * cantaloupe, watermelon, \
+ * kiwi, mango
+ * </pre>
+ * The key is <code>"fruits"</code> and the associated element is:
+ * <p>
+ * <pre>"apple, banana, pear, cantaloupe, watermelon,kiwi, mango"</pre>
+ * Note that a space appears before each <code>\</code> so that a space
+ * will appear after each comma in the final result; the <code>\</code>,
+ * line terminator, and leading whitespace on the continuation line are
+ * merely discarded and are <i>not</i> replaced by one or more other
+ * characters.
+ * <p>
+ * As a third example, the line:
+ * <p>
+ * <pre>cheeses
+ * </pre>
+ * specifies that the key is <code>"cheeses"</code> and the associated
+ * element is the empty string.<p>
+ *
+ * @param in the input stream.
+ * @exception IOException if an error occurred when reading from the
+ * input stream.
+ */
+ public synchronized void load(InputStream inStream) throws IOException {
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(inStream, "8859_1"));
+
+ while (true) {
+ // Get next line
+ String line = in.readLine();
+
+ if (line == null)
+ return;
+
+ if (line.length() > 0) {
+ // Continue lines that end in slashes if they are not comments
+ char firstChar = line.charAt(0);
+
+ if ((firstChar != '#') && (firstChar != '!')) {
+ while (continueLine(line)) {
+ String nextLine = in.readLine();
+
+ if (nextLine == null)
+ nextLine = "";
+ String loppedLine = line.substring(0, line.length() - 1);
+ // Advance beyond whitespace on new line
+ int startIndex = 0;
+
+ for (startIndex = 0; startIndex < nextLine.length(); startIndex++)
+ if (whiteSpaceChars.indexOf(nextLine.charAt(startIndex)) == -1)
+ break;
+ nextLine = nextLine.substring(startIndex, nextLine.length());
+ line = new String(loppedLine + nextLine);
+ }
+ // Find start of key
+ int len = line.length();
+ int keyStart;
+
+ for (keyStart = 0; keyStart < len; keyStart++) {
+ if (whiteSpaceChars.indexOf(line.charAt(keyStart)) == -1)
+ break;
+ }
+ // Find separation between key and value
+ int separatorIndex;
+
+ for (separatorIndex = keyStart; separatorIndex < len; separatorIndex++) {
+ char currentChar = line.charAt(separatorIndex);
+
+ if (currentChar == '\\')
+ separatorIndex++;
+ else if (keyValueSeparators.indexOf(currentChar) != -1)
+ break;
+ }
+
+ // Skip over whitespace after key if any
+ int valueIndex;
+
+ for (valueIndex = separatorIndex; valueIndex < len; valueIndex++)
+ if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1)
+ break;
+
+ // Skip over one non whitespace key value separators if any
+ if (valueIndex < len)
+ if (strictKeyValueSeparators.indexOf(line.charAt(valueIndex)) != -1)
+ valueIndex++;
+
+ // Skip over white space after other separators if any
+ while (valueIndex < len) {
+ if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1)
+ break;
+ valueIndex++;
+ }
+ String key = line.substring(keyStart, separatorIndex);
+ String value = (separatorIndex < len) ? line.substring(valueIndex, len) : "";
+
+ // Convert then store key and value
+ // NETSCAPE: no need to convert escape characters
+ // key = loadConvert(key);
+ // value = loadConvert(value);
+ put(key, value);
+ }
+ }
+ }
+ }
+
+ /*
+ * Returns true if the given line is a line that must
+ * be appended to the next line
+ */
+ private boolean continueLine(String line) {
+ int slashCount = 0;
+ int index = line.length() - 1;
+
+ while ((index >= 0) && (line.charAt(index--) == '\\'))
+ slashCount++;
+ return (slashCount % 2 == 1);
+ }
+
+ /*
+ * Converts encoded \\uxxxx to unicode chars
+ * and changes special saved chars to their original forms
+ */
+ private String loadConvert(String theString) {
+ char aChar;
+ int len = theString.length();
+ StringBuffer outBuffer = new StringBuffer(len);
+
+ for (int x = 0; x < len;) {
+ aChar = theString.charAt(x++);
+ if (aChar == '\\') {
+ aChar = theString.charAt(x++);
+ if (aChar == 'u') {
+ // Read the xxxx
+ int value = 0;
+
+ for (int i = 0; i < 4; i++) {
+ aChar = theString.charAt(x++);
+ switch (aChar) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ value = (value << 4) + aChar - '0';
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ value = (value << 4) + 10 + aChar - 'a';
+ break;
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ value = (value << 4) + 10 + aChar - 'A';
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ "Malformed \\uxxxx encoding.");
+ }
+ }
+ outBuffer.append((char) value);
+ } else {
+ if (aChar == 't') aChar = '\t';
+ else if (aChar == 'r') aChar = '\r';
+ else if (aChar == 'n') aChar = '\n';
+ else if (aChar == 'f') aChar = '\f';
+ outBuffer.append(aChar);
+ }
+ } else
+ outBuffer.append(aChar);
+ }
+ return outBuffer.toString();
+ }
+
+ /*
+ * Converts unicodes to encoded \\uxxxx
+ * and writes out any of the characters in specialSaveChars
+ * with a preceding slash
+ */
+ private String saveConvert(String theString) {
+ char aChar;
+ int len = theString.length();
+ StringBuffer outBuffer = new StringBuffer(len * 2);
+
+ for (int x = 0; x < len;) {
+ aChar = theString.charAt(x++);
+ switch (aChar) {
+ case '\\':
+ outBuffer.append('\\');
+ outBuffer.append('\\');
+ continue;
+
+ case '\t':
+ outBuffer.append('\\');
+ outBuffer.append('t');
+ continue;
+
+ case '\n':
+ outBuffer.append('\\');
+ outBuffer.append('n');
+ continue;
+
+ case '\r':
+ outBuffer.append('\\');
+ outBuffer.append('r');
+ continue;
+
+ case '\f':
+ outBuffer.append('\\');
+ outBuffer.append('f');
+ continue;
+
+ default:
+ if ((aChar < 20) || (aChar > 127)) {
+ outBuffer.append('\\');
+ outBuffer.append('u');
+ outBuffer.append(toHex((aChar >> 12) & 0xF));
+ outBuffer.append(toHex((aChar >> 8) & 0xF));
+ outBuffer.append(toHex((aChar >> 4) & 0xF));
+ outBuffer.append(toHex((aChar >> 0) & 0xF));
+ } else {
+ if (specialSaveChars.indexOf(aChar) != -1)
+ outBuffer.append('\\');
+ outBuffer.append(aChar);
+ }
+ }
+ }
+ return outBuffer.toString();
+ }
+
+ /**
+ * Calls the <code>store(OutputStream out, String header)</code> method
+ * and suppresses IOExceptions that were thrown.
+ *
+ * @deprecated This method does not throw an IOException if an I/O error
+ * occurs while saving the property list. As of JDK 1.2, the preferred
+ * way to save a properties list is via the <code>store(OutputStream out,
+ * String header)</code> method.
+ *
+ * @param out an output stream.
+ * @param header a description of the property list.
+ * @exception ClassCastException if this <code>Properties</code> object
+ * contains any keys or values that are not <code>Strings</code>.
+ */
+ public synchronized void save(OutputStream out, String header) {
+ try {
+ store(out, header);
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Writes this property list (key and element pairs) in this
+ * <code>Properties</code> table to the output stream in a format suitable
+ * for loading into a <code>Properties</code> table using the
+ * <code>load</code> method.
+ * <p>
+ * Properties from the defaults table of this <code>Properties</code>
+ * table (if any) are <i>not</i> written out by this method.
+ * <p>
+ * If the header argument is not null, then an ASCII <code>#</code>
+ * character, the header string, and a line separator are first written
+ * to the output stream. Thus, the <code>header</code> can serve as an
+ * identifying comment.
+ * <p>
+ * Next, a comment line is always written, consisting of an ASCII
+ * <code>#</code> character, the current date and time (as if produced
+ * by the <code>toString</code> method of <code>Date</code> for the
+ * current time), and a line separator as generated by the Writer.
+ * <p>
+ * Then every entry in this <code>Properties</code> table is written out,
+ * one per line. For each entry the key string is written, then an ASCII
+ * <code>=</code>, then the associated element string. Each character of
+ * the element string is examined to see whether it should be rendered as
+ * an escape sequence. The ASCII characters <code>\</code>, tab, newline,
+ * and carriage return are written as <code>\\</code>, <code>\t</code>,
+ * <code>\n</code>, and <code>\r</code>, respectively. Characters less
+ * than <code>\u0020</code> and characters greater than
+ * <code>\u007E</code> are written as <code>\\u</code><i>xxxx</i> for
+ * the appropriate hexadecimal value <i>xxxx</i>. Space characters, but
+ * not embedded or trailing space characters, are written with a preceding
+ * <code>\</code>. The key and value characters <code>#</code>,
+ * <code>!</code>, <code>=</code>, and <code>:</code> are written with a
+ * preceding slash to ensure that they are properly loaded.
+ * <p>
+ * After the entries have been written, the output stream is flushed. The
+ * output stream remains open after this method returns.
+ *
+ * @param out an output stream.
+ * @param header a description of the property list.
+ * @exception ClassCastException if this <code>Properties</code> object
+ * contains any keys or values that are not <code>Strings</code>.
+ */
+ public synchronized void store(OutputStream out, String header)
+ throws IOException {
+ BufferedWriter awriter;
+
+ awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
+ if (header != null)
+ writeln(awriter, "#" + header);
+ writeln(awriter, "#" + new Date().toString());
+ for (Enumeration e = keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String val = (String) get(key);
+
+ // key = saveConvert(key);
+ // val = saveConvert(val);
+ writeln(awriter, key + "=" + val);
+ }
+ awriter.flush();
+ }
+
+ private static void writeln(BufferedWriter bw, String s) throws IOException {
+ bw.write(s);
+ bw.newLine();
+ }
+
+ /**
+ * Searches for the property with the specified key in this property list.
+ * If the key is not found in this property list, the default property list,
+ * and its defaults, recursively, are then checked. The method returns
+ * <code>null</code> if the property is not found.
+ *
+ * @param key the property key.
+ * @return the value in this property list with the specified key value.
+ * @see java.util.Properties#defaults
+ */
+ public String getProperty(String key) {
+ Object oval = super.get(key);
+ String sval = (oval instanceof String) ? (String) oval : null;
+
+ return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
+ }
+
+ /**
+ * Searches for the property with the specified key in this property list.
+ * If the key is not found in this property list, the default property list,
+ * and its defaults, recursively, are then checked. The method returns the
+ * default value argument if the property is not found.
+ *
+ * @param key the hashtable key.
+ * @param defaultValue a default value.
+ *
+ * @return the value in this property list with the specified key value.
+ * @see java.util.Properties#defaults
+ */
+ public String getProperty(String key, String defaultValue) {
+ String val = getProperty(key);
+
+ return (val == null) ? defaultValue : val;
+ }
+
+ /**
+ * Returns an enumeration of all the keys in this property list, including
+ * the keys in the default property list.
+ *
+ * @return an enumeration of all the keys in this property list, including
+ * the keys in the default property list.
+ * @see java.util.Enumeration
+ * @see java.util.Properties#defaults
+ */
+ public Enumeration propertyNames() {
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ return h.keys();
+ }
+
+ /**
+ * Prints this property list out to the specified output stream.
+ * This method is useful for debugging.
+ *
+ * @param out an output stream.
+ */
+ public void list(PrintStream out) {
+ out.println("-- listing properties --");
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ for (Enumeration e = h.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String val = (String) h.get(key);
+
+ if (val.length() > 40) {
+ val = val.substring(0, 37) + "...";
+ }
+ out.println(key + "=" + val);
+ }
+ }
+
+ /**
+ * Prints this property list out to the specified output stream.
+ * This method is useful for debugging.
+ *
+ * @param out an output stream.
+ * @since JDK1.1
+ */
+
+ /*
+ * Rather than use an anonymous inner class to share common code, this
+ * method is duplicated in order to ensure that a non-1.1 compiler can
+ * compile this file.
+ */
+ public void list(PrintWriter out) {
+ out.println("-- listing properties --");
+ Hashtable h = new Hashtable();
+
+ enumerate(h);
+ for (Enumeration e = h.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String val = (String) h.get(key);
+
+ if (val.length() > 40) {
+ val = val.substring(0, 37) + "...";
+ }
+ out.println(key + "=" + val);
+ }
+ }
+
+ /**
+ * Enumerates all key/value pairs in the specified hastable.
+ * @param h the hashtable
+ */
+ private synchronized void enumerate(Hashtable h) {
+ if (defaults != null) {
+ defaults.enumerate(h);
+ }
+ for (Enumeration e = keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+
+ h.put(key, get(key));
+ }
+ }
+
+ /**
+ * Convert a nibble to a hex character
+ * @param nibble the nibble to convert.
+ */
+ private static char toHex(int nibble) {
+ return hexDigit[(nibble & 0xF)];
+ }
+
+ /** A table of hex digits */
+ private static final char[] hexDigit = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java b/pki/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java
new file mode 100644
index 000000000..9b192905f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java
@@ -0,0 +1,55 @@
+// --- 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.cmscore.base;
+
+
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This class is is a wrapper to hide the Properties methods from
+ * the PropConfigStore. Lucky for us, Properties already implements
+ * almost every thing ISourceConfigStore requires.
+ *
+ * @version $Revision$, $Date$
+ * @see java.util.Properties
+ */
+public class SourceConfigStore extends SimpleProperties implements ISourceConfigStore {
+
+ /**
+ * Retrieves a property from the config store
+ * <P>
+ *
+ * @param name property name
+ * @return property value
+ */
+ public Object get(String name) {
+ return super.get(name); // from Properties->Hashtable
+ }
+
+ /**
+ * Puts a property into the config store.
+ * <P>
+ *
+ * @param name property name
+ * @param value property value
+ */
+ public void put(String name, Object value) {
+ super.put(name, value); // from Properties->Hashtable
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java b/pki/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java
new file mode 100644
index 000000000..442a93671
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java
@@ -0,0 +1,74 @@
+// --- 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.cmscore.base;
+
+
+import com.netscape.certsrv.apps.CMS;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a subsystem loader.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class SubsystemLoader {
+
+ private static final String PROP_SUBSYSTEM = "subsystem";
+ private static final String PROP_CLASSNAME = "class";
+ private static final String PROP_ID = "id";
+
+ public static Vector load(IConfigStore config) throws EBaseException {
+ Vector v = new Vector();
+
+ // load a list of installable subsystems (services)
+ for (int i = 0;; i++) {
+ IConfigStore c = config.getSubStore(PROP_SUBSYSTEM + i);
+
+ if (c == null)
+ break;
+ String id = null;
+
+ try {
+ id = c.getString(PROP_ID, null);
+ if (id == null)
+ break;
+ } catch (EBaseException e) {
+ break;
+ }
+ String className = c.getString(PROP_CLASSNAME, null);
+
+ if (className == null)
+ break;
+ try {
+ ISubsystem sub = (ISubsystem) Class.forName(
+ className).newInstance();
+
+ sub.setId(id);
+ v.addElement(sub);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_LOAD_FAILED", className));
+ }
+ }
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java b/pki/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java
new file mode 100644
index 000000000..f95a61610
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java
@@ -0,0 +1,43 @@
+// --- 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.cmscore.base;
+
+
+import java.util.Hashtable;
+import com.netscape.certsrv.base.*;
+
+
+public class SubsystemRegistry extends Hashtable {
+ private static SubsystemRegistry mInstance = null;
+
+ public static SubsystemRegistry getInstance() {
+ if (mInstance == null) {
+ mInstance = new SubsystemRegistry();
+ }
+ return mInstance;
+ }
+
+ private SubsystemRegistry() {
+ super();
+ }
+
+ public ISubsystem get(String key) {
+ return (ISubsystem) super.get(key);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java b/pki/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java
new file mode 100644
index 000000000..9b6c3dfe0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java
@@ -0,0 +1,52 @@
+// --- 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.cmscore.cert;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+
+
+/**
+ * Compares validity dates for use in sorting.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class CertDateCompare implements Comparator {
+ public CertDateCompare() {
+ }
+
+ public int compare(Object cert1, Object cert2) {
+ Date d1 = null;
+ Date d2 = null;
+
+ try {
+ d1 = ((X509CertImpl) cert1).getNotAfter();
+ d2 = ((X509CertImpl) cert2).getNotAfter();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (d1 == d2) return 0;
+ if (d1.after(d2))
+ return 1;
+ else
+ return -1;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java b/pki/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java
new file mode 100644
index 000000000..882a38c0c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java
@@ -0,0 +1,44 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.security.PublicKey;
+import java.security.cert.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CertPrettyPrint extends netscape.security.util.CertPrettyPrint implements ICertPrettyPrint {
+
+ public CertPrettyPrint(Certificate cert) {
+ super(cert);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CertUtils.java b/pki/base/common/src/com/netscape/cmscore/cert/CertUtils.java
new file mode 100644
index 000000000..6731ae35d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CertUtils.java
@@ -0,0 +1,1072 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.osutil.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import netscape.security.pkcs.*;
+import java.net.SocketException;
+
+import javax.servlet.http.HttpServletRequest;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+
+/**
+ * Utility class with assorted methods to check for
+ * smime pairs, determining the type of cert - signature
+ * or encryption ..etc.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class CertUtils {
+ public static final String CERT_NEW_REQUEST_HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String CERT_NEW_REQUEST_TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ public static final String CERT_REQUEST_HEADER = "-----BEGIN CERTIFICATE REQUEST-----";
+ public static final String CERT_REQUEST_TRAILER = "-----END CERTIFICATE REQUEST-----";
+ public static final String CERT_RENEWAL_HEADER = "-----BEGIN RENEWAL CERTIFICATE REQUEST-----";
+ public static final String CERT_RENEWAL_TRAILER = "-----END RENEWAL CERTIFICATE REQUEST-----";
+ public static final String BEGIN_CRL_HEADER =
+ "-----BEGIN CERTIFICATE REVOCATION LIST-----";
+ public static final String END_CRL_HEADER =
+ "-----END CERTIFICATE REVOCATION LIST-----";
+
+ protected static ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION =
+ "LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION_3";
+
+ /**
+ * Remove the header and footer in the PKCS10 request.
+ */
+ public static String unwrapPKCS10(String request, boolean checkHeader)
+ throws EBaseException {
+ String unwrapped;
+ String header = null;
+ int head = -1;
+ int trail = -1;
+
+ // check for "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_NEW_REQUEST_HEADER);
+ trail = request.indexOf(CERT_NEW_REQUEST_TRAILER);
+
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_NEW_REQUEST_HEADER;
+ }
+ }
+
+ // check for "-----BEGIN CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_REQUEST_HEADER);
+ trail = request.indexOf(CERT_REQUEST_TRAILER);
+
+ // If this is not a request header, check if this is a renewal header.
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_REQUEST_HEADER;
+
+ }
+ }
+
+ // check for "-----BEGIN RENEWAL CERTIFICATE REQUEST-----";
+ if (header == null) {
+ head = request.indexOf(CERT_RENEWAL_HEADER);
+ trail = request.indexOf(CERT_RENEWAL_TRAILER);
+ if (!(head == -1 && trail == -1)) {
+ header = CERT_RENEWAL_HEADER;
+ }
+ }
+
+ // Now validate if any headers or trailers are in place
+ if (head == -1 && checkHeader) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_MISSING_PKCS10_HEADER"));
+ }
+ if (trail == -1 && checkHeader) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_MISSING_PKCS10_TRAILER"));
+ }
+
+ if (header != null) {
+ unwrapped = request.substring(head + header.length(), trail);
+ } else {
+ unwrapped = request;
+ }
+
+ // strip all the crtl-characters (i.e. \r\n)
+ StringTokenizer st = new StringTokenizer(unwrapped, "\t\r\n ");
+ StringBuffer stripped = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ stripped.append(st.nextToken());
+ }
+
+ return stripped.toString();
+ }
+
+ public static PKCS10 decodePKCS10(String req) throws EBaseException {
+ String normalized = unwrapPKCS10(req, true);
+ PKCS10 pkcs10 = null;
+
+ try {
+ byte[] decodedBytes = com.netscape.osutil.OSUtil.AtoB(normalized);
+
+ pkcs10 = new PKCS10(decodedBytes);
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ return pkcs10;
+ }
+
+ public static void setRSAKeyToCertInfo(X509CertInfo info,
+ byte encoded[]) throws EBaseException {
+ try {
+ if (info == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+ X509Key key = new X509Key(AlgorithmId.getAlgorithmId(
+ "RSAEncryption"), encoded);
+
+ info.set(X509CertInfo.KEY, key);
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+ }
+
+ public static X509CertInfo createCertInfo(int ver,
+ BigInteger serialno, String alg, String issuerName,
+ Date notBefore, Date notAfter) throws EBaseException {
+ try {
+ X509CertInfo info = new X509CertInfo();
+
+ info.set(X509CertInfo.VERSION, new CertificateVersion(ver));
+ info.set(X509CertInfo.SERIAL_NUMBER, new
+ CertificateSerialNumber(serialno));
+ info.set(X509CertInfo.ALGORITHM_ID, new
+ CertificateAlgorithmId(AlgorithmId.getAlgorithmId(alg)));
+ info.set(X509CertInfo.ISSUER, new
+ CertificateIssuerName(new X500Name(issuerName)));
+ info.set(X509CertInfo.VALIDITY, new
+ CertificateValidity(notBefore, notAfter));
+ return info;
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ return null;
+ }
+ }
+
+ public static void sortCerts(X509CertImpl[] arr) {
+ Arrays.sort(arr, new CertDateCompare());
+ }
+
+ public static boolean isSigningCert(X509CertImpl cert) {
+ boolean[] keyUsage = null;
+
+ try {
+ keyUsage = cert.getKeyUsage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return (keyUsage == null) ? false : keyUsage[0];
+ }
+
+ public static boolean isEncryptionCert(X509CertImpl cert) {
+ boolean[] keyUsage = null;
+
+ try {
+ keyUsage = cert.getKeyUsage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (keyUsage == null)
+ return false;
+ if (keyUsage.length < 3)
+ return false;
+ else if (keyUsage.length == 3)
+ return keyUsage[2];
+ else return keyUsage[2] || keyUsage[3];
+ }
+
+ public static boolean haveSameValidityPeriod(X509CertImpl cert1,
+ X509CertImpl cert2) {
+ long notBefDiff = 0;
+ long notAfterDiff = 0;
+
+ try {
+ notBefDiff = Math.abs(cert1.getNotBefore().getTime() -
+ cert2.getNotBefore().getTime());
+ notAfterDiff = Math.abs(cert1.getNotAfter().getTime() -
+ cert2.getNotAfter().getTime());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (notBefDiff > 1000 || notAfterDiff > 1000)
+ return false;
+ else
+ return true;
+ }
+
+ public static boolean isSmimePair(X509CertImpl cert1, X509CertImpl cert2, boolean matchSubjectDN) {
+ // Check for subjectDN equality.
+ if (matchSubjectDN) {
+ String dn1 = cert1.getSubjectDN().toString();
+ String dn2 = cert2.getSubjectDN().toString();
+
+ if (!sameSubjectDN(dn1, dn2))
+ return false;
+ }
+
+ // Check for the presence of signing and encryption certs.
+ boolean hasSigningCert = isSigningCert(cert1) || isSigningCert(cert2);
+
+ if (!hasSigningCert)
+ return false;
+
+ boolean hasEncryptionCert = isEncryptionCert(cert1) || isEncryptionCert(cert2);
+
+ if (!hasEncryptionCert)
+ return false;
+
+ // If both certs have signing & encryption usage set, they are
+ // not really pairs.
+ if ((isSigningCert(cert1) && isEncryptionCert(cert1)) ||
+ (isSigningCert(cert2) && isEncryptionCert(cert2)))
+ return false;
+
+ // See if the certs have the same validity.
+ boolean haveSameValidity =
+ haveSameValidityPeriod(cert1, cert2);
+
+ return haveSameValidity;
+ }
+
+ public static boolean isNotYetValidCert(X509CertImpl cert) {
+ boolean ret = false;
+
+ try {
+ cert.checkValidity();
+ } catch (CertificateExpiredException e) {
+ } catch (CertificateNotYetValidException e) {
+ ret = true;
+ } catch (Exception e) {
+ }
+ return ret;
+ }
+
+ public static boolean isValidCert(X509CertImpl cert) {
+ boolean ret = true;
+
+ try {
+ cert.checkValidity();
+ } catch (Exception e) {
+ ret = false;
+ }
+ return ret;
+ }
+
+ public static boolean isExpiredCert(X509CertImpl cert) {
+ boolean ret = false;
+
+ try {
+ cert.checkValidity();
+ } catch (CertificateExpiredException e) {
+ ret = true;
+ } catch (Exception e) {
+ }
+ return ret;
+ }
+
+ public static boolean sameSubjectDN(String dn1, String dn2) {
+ boolean ret = false;
+
+ // The dn cannot be null.
+ if (dn1 == null || dn2 == null)
+ return false;
+ try {
+ X500Name n1 = new X500Name(dn1);
+ X500Name n2 = new X500Name(dn2);
+
+ ret = n1.equals(n2);
+ } catch (Exception e) {
+ }
+ return ret;
+ }
+
+ public static String getValidCertsDisplayInfo(String cn, X509CertImpl[] validCerts) {
+ StringBuffer sb = new StringBuffer(1024);
+
+ sb.append(cn + "'s Currently Valid Certificates\n\n");
+ sb.append(getCertsDisplayInfo(validCerts));
+ return new String(sb);
+ }
+
+ public static String getExpiredCertsDisplayInfo(String cn, X509CertImpl[] expiredCerts) {
+ StringBuffer sb = new StringBuffer(1024);
+
+ sb.append(cn + "'s Expired Certificates\n\n");
+ sb.append(getCertsDisplayInfo(expiredCerts));
+ return new String(sb);
+ }
+
+ public static String getRenewedCertsDisplayInfo(String cn,
+ X509CertImpl[] validCerts, X509CertImpl[] renewedCerts) {
+ StringBuffer sb = new StringBuffer(1024);
+
+ if (validCerts != null) {
+ sb.append(cn + "'s Currently Valid Certificates\n\n");
+ sb.append(getCertsDisplayInfo(validCerts));
+ sb.append("\n\nRenewed Certificates\n\n\n");
+ } else
+ sb.append(cn + "'s Renewed Certificates\n\n");
+ sb.append(getCertsDisplayInfo(renewedCerts));
+ return new String(sb);
+ }
+
+ public static String getCertsDisplayInfo(X509CertImpl[] validCerts) {
+ // We assume that the given pair is a valid S/MIME pair.
+ StringBuffer sb = new StringBuffer(1024);
+
+ sb.append("Subject DN: " + validCerts[0].getSubjectDN().toString());
+ sb.append("\n");
+ X509CertImpl signingCert, encryptionCert;
+
+ if (isSigningCert(validCerts[0])) {
+ signingCert = validCerts[0];
+ encryptionCert = validCerts[1];
+ } else {
+ signingCert = validCerts[1];
+ encryptionCert = validCerts[0];
+ }
+ sb.append("Signing Certificate Serial No: " + signingCert.getSerialNumber().toString(16).toUpperCase());
+ sb.append("\n");
+ sb.append("Encryption Certificate Serial No: " + encryptionCert.getSerialNumber().toString(16).toUpperCase());
+ sb.append("\n");
+ sb.append("Validity: From: " + signingCert.getNotBefore().toString() + " To: " + signingCert.getNotAfter().toString());
+ sb.append("\n");
+ return new String(sb);
+ }
+
+ /**
+ * Returns the index of the given cert in an array of certs.
+ *
+ * Assumptions: The certs are issued by the same CA
+ *
+ * @param certArray The array of certs.
+ * @param givenCert The certificate we are lokking for in the array.
+ * @return -1 if not found or the index of the given cert in the array.
+ */
+ public static int getCertIndex(X509CertImpl[] certArray, X509CertImpl givenCert) {
+ int i = 0;
+
+ for (; i < certArray.length; i++) {
+ if (certArray[i].getSerialNumber().equals(
+ givenCert.getSerialNumber())) {
+ break;
+ }
+ }
+
+ return ((i == certArray.length) ? -1 : i);
+ }
+
+ /**
+ * Returns the most recently issued signing certificate from an
+ * an array of certs.
+ *
+ * Assumptions: The certs are issued by the same CA
+ *
+ * @param certArray The array of certs.
+ * @param givenCert The certificate we are lokking for in the array.
+ * @return null if there is no recent cert or the most recent cert.
+ */
+ public static X509CertImpl getRecentSigningCert(X509CertImpl[] certArray,
+ X509CertImpl currentCert) {
+ if (certArray == null || currentCert == null)
+ return null;
+
+ // Sort the certificate array.
+ Arrays.sort(certArray, new CertDateCompare());
+
+ // Get the index of the current cert in the array.
+ int i = getCertIndex(certArray, currentCert);
+
+ if (i < 0)
+ return null;
+
+ X509CertImpl recentCert = currentCert;
+
+ for (; i < certArray.length; i++) {
+ // Check if it is a signing cert and has its
+ // NotAfter later than the current cert.
+ if (isSigningCert(certArray[i]) &&
+ certArray[i].getNotAfter().after(recentCert.getNotAfter()))
+ recentCert = certArray[i];
+ }
+ return ((recentCert == currentCert) ? null : recentCert);
+ }
+
+ public static String getCertType(X509CertImpl cert) {
+ StringBuffer sb = new StringBuffer();
+
+ if (isSigningCert(cert))
+ sb.append("signing");
+ if (isEncryptionCert(cert)) {
+ if (sb.length() > 0)
+ sb.append(" ");
+ sb.append("encryption");
+ }
+
+ // Is is object signing cert?
+ try {
+ CertificateExtensions extns = (CertificateExtensions)
+ cert.get(X509CertImpl.NAME + "." +
+ X509CertImpl.INFO + "." +
+ X509CertInfo.EXTENSIONS);
+
+ if (extns != null) {
+ NSCertTypeExtension nsExtn = (NSCertTypeExtension)
+ extns.get(NSCertTypeExtension.NAME);
+
+ if (nsExtn != null) {
+ String nsType = getNSExtensionInfo(nsExtn);
+
+ if (nsType != null) {
+ if (sb.length() > 0)
+ sb.append(" ");
+ sb.append(nsType);
+ }
+ }
+ }
+ }catch (Exception e) {
+ }
+ return (sb.length() > 0) ? sb.toString() : null;
+ }
+
+ public static String getNSExtensionInfo(NSCertTypeExtension nsExtn) {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ Boolean res;
+
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.SSL_CLIENT);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" ssl_client");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.SSL_SERVER);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" ssl_server");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.EMAIL);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" email");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.OBJECT_SIGNING);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" object_signing");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.SSL_CA);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" ssl_CA");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.EMAIL_CA);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" email_CA");
+ res = (Boolean) nsExtn.get(NSCertTypeExtension.OBJECT_SIGNING_CA);
+ if (res.equals(Boolean.TRUE))
+ sb.append(" object_signing_CA");
+ }catch (Exception e) {
+ }
+
+ return (sb.length() > 0) ? sb.toString() : null;
+ }
+
+ public static byte[] readFromFile(String fileName)
+ throws IOException {
+ FileInputStream fin = new FileInputStream(fileName);
+ int available = fin.available();
+ byte[] ba = new byte[available];
+ int nRead = fin.read(ba);
+
+ if (nRead != available)
+ throw new IOException("Error reading data from file: " + fileName);
+ fin.close();
+ return ba;
+ }
+
+ public static void storeInFile(String fileName, byte[] ba)
+ throws IOException {
+ FileOutputStream fout = new FileOutputStream(fileName);
+
+ fout.write(ba);
+ fout.close();
+ }
+
+ public static String toMIME64(X509CertImpl cert) {
+ try {
+ return
+ "-----BEGIN CERTIFICATE-----\n" +
+ com.netscape.osutil.OSUtil.BtoA(cert.getEncoded()) +
+ "-----END CERTIFICATE-----\n";
+ } catch (CertificateException e) {
+ }
+ return null;
+ }
+
+ public static X509Certificate mapCert(String mime64)
+ throws IOException {
+ mime64 = stripCertBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ byte rawPub[] = com.netscape.osutil.OSUtil.AtoB(newval);
+ X509Certificate cert = null;
+
+ try {
+ cert = new X509CertImpl(rawPub);
+ } catch (CertificateException e) {
+ }
+ return cert;
+ }
+
+ public static X509Certificate[] mapCertFromPKCS7(String mime64)
+ throws IOException {
+ mime64 = stripCertBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ byte rawPub[] = com.netscape.osutil.OSUtil.AtoB(newval);
+ PKCS7 p7 = null;
+
+ try {
+ p7 = new PKCS7(rawPub);
+ return p7.getCertificates();
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ public static X509CRL mapCRL(String mime64)
+ throws IOException {
+ mime64 = stripCRLBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ byte rawPub[] = com.netscape.osutil.OSUtil.AtoB(newval);
+ X509CRL crl = null;
+
+ try {
+ crl = new X509CRLImpl(rawPub);
+ } catch (Exception e) {
+ }
+ return crl;
+ }
+
+ public static X509CRL mapCRL1(String mime64)
+ throws IOException {
+ mime64 = stripCRLBrackets(mime64.trim());
+ byte rawPub[] = OSUtil.AtoB(mime64);
+ X509CRL crl = null;
+
+ try {
+ crl = new X509CRLImpl(rawPub);
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ return crl;
+ }
+
+ public static String normalizeCertStr(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ public static String stripCRLBrackets(String s) {
+ if (s == null) {
+ return s;
+ }
+ if ((s.startsWith("-----BEGIN CERTIFICATE REVOCATION LIST-----")) &&
+ (s.endsWith("-----END CERTIFICATE REVOCATION LIST-----"))) {
+ return (s.substring(43, (s.length() - 41)));
+ }
+ return s;
+ }
+
+ /**
+ * strips out the begin and end certificate brackets
+ * @param s the string potentially bracketed with
+ * "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"
+ * @return string without the brackets
+ */
+ public static String stripCertBrackets(String s) {
+ if (s == null) {
+ return s;
+ }
+
+ if ((s.startsWith("-----BEGIN CERTIFICATE-----")) &&
+ (s.endsWith("-----END CERTIFICATE-----"))) {
+ return (s.substring(27, (s.length() - 25)));
+ }
+
+ // To support Thawte's header and footer
+ if ((s.startsWith("-----BEGIN PKCS #7 SIGNED DATA-----")) &&
+ (s.endsWith("-----END PKCS #7 SIGNED DATA-----"))) {
+ return (s.substring(35, (s.length() - 33)));
+ }
+
+ return s;
+ }
+
+ /**
+ * Returns a string that represents a cert's fingerprint.
+ * The fingerprint is a MD5 digest of the DER encoded certificate.
+ * @param cert Certificate to get the fingerprint of.
+ * @return a String that represents the cert's fingerprint.
+ */
+ public static String getFingerPrint(Certificate cert)
+ throws CertificateEncodingException, NoSuchAlgorithmException {
+ byte certDer[] = cert.getEncoded();
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ md.update(certDer);
+ byte digestedCert[] = md.digest();
+ PrettyPrintFormat pp = new PrettyPrintFormat(":");
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(pp.toHexString(digestedCert, 4, 20));
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string that has the certificate's fingerprint using
+ * MD5, MD2 and SHA1 hashes.
+ * A certificate's fingerprint is a hash digest of the DER encoded
+ * certificate.
+ * @param cert Certificate to get the fingerprints of.
+ * @return a String with fingerprints using the MD5, MD2 and SHA1 hashes.
+ * For example,
+ * <pre>
+ * MD2: 78:7E:D1:F9:3E:AF:50:18:68:A7:29:50:C3:21:1F:71
+ *
+ * MD5: 0E:89:91:AC:40:50:F7:BE:6E:7B:39:4F:56:73:75:75
+ *
+ * SHA1: DC:D9:F7:AF:E2:83:10:B2:F7:0A:77:E8:50:E2:F7:D1:15:9A:9D:00
+ * </pre>
+ */
+ public static String getFingerPrints(Certificate cert)
+ throws NoSuchAlgorithmException, CertificateEncodingException {
+ byte certDer[] = cert.getEncoded();
+ /*
+ String[] hashes = new String[] {"MD2", "MD5", "SHA1"};
+ String certFingerprints = "";
+ PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ for (int i = 0; i < hashes.length; i++) {
+ MessageDigest md = MessageDigest.getInstance(hashes[i]);
+
+ md.update(certDer);
+ certFingerprints += " " + hashes[i] + ":" +
+ pp.toHexString(md.digest(), 6 - hashes[i].length());
+ }
+ return certFingerprints;
+ */
+ return getFingerPrints(certDer);
+ }
+
+ /**
+ * Returns a string that has the certificate's fingerprint using
+ * MD5, MD2 and SHA1 hashes.
+ * A certificate's fingerprint is a hash digest of the DER encoded
+ * certificate.
+ * @param cert Certificate to get the fingerprints of.
+ * @return a String with fingerprints using the MD5, MD2 and SHA1 hashes.
+ * For example,
+ * <pre>
+ * MD2: 78:7E:D1:F9:3E:AF:50:18:68:A7:29:50:C3:21:1F:71
+ *
+ * MD5: 0E:89:91:AC:40:50:F7:BE:6E:7B:39:4F:56:73:75:75
+ *
+ * SHA1: DC:D9:F7:AF:E2:83:10:B2:F7:0A:77:E8:50:E2:F7:D1:15:9A:9D:00
+ * </pre>
+ */
+ public static String getFingerPrints(byte[] certDer)
+ throws NoSuchAlgorithmException/*, CertificateEncodingException*/ {
+ // byte certDer[] = cert.getEncoded();
+ String[] hashes = new String[] {"MD2", "MD5", "SHA1", "SHA256", "SHA512"};
+ String certFingerprints = "";
+ PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ for (int i = 0; i < hashes.length; i++) {
+ MessageDigest md = MessageDigest.getInstance(hashes[i]);
+
+ md.update(certDer);
+ certFingerprints += hashes[i] + ":\n" +
+ pp.toHexString(md.digest(), 8, 16);
+ }
+ return certFingerprints;
+ }
+
+ /**
+ * Check if a object identifier in string form is valid,
+ * that is a string in the form n.n.n.n and der encode and decode-able.
+ * @param attrName attribute name (from the configuration file)
+ * @param value object identifier string.
+ */
+ public static ObjectIdentifier checkOID(String attrName, String value)
+ throws EBaseException {
+ String msg = "value must be a object identifier in the form n.n.n.n";
+ String msg1 = "not a valid object identifier.";
+ ObjectIdentifier oid;
+
+ try {
+ oid = ObjectIdentifier.getObjectIdentifier(value);
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ attrName, msg));
+ }
+
+ // if the OID isn't valid (ex. n.n) the error isn't caught til
+ // encoding time leaving a bad request in the request queue.
+ try {
+ DerOutputStream derOut = new DerOutputStream();
+
+ derOut.putOID(oid);
+ new ObjectIdentifier(new DerInputStream(derOut.toByteArray()));
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ attrName, msg1));
+ }
+ return oid;
+ }
+
+ public static String trimB64E(String b64e) {
+ StringBuffer tmp = new StringBuffer("");
+ String line = null;
+ StringTokenizer tokens = new StringTokenizer(b64e, "\n");
+
+ while (tokens.hasMoreTokens()) {
+ line = tokens.nextToken();
+ line = line.trim();
+ tmp.append(line.trim());
+ if (tokens.hasMoreTokens())
+ tmp.append("\n");
+ }
+
+ return tmp.toString();
+ }
+
+ /*
+ * verify a certificate by its nickname
+ * returns true if it verifies; false if any not
+ */
+ public static boolean verifySystemCertByNickname(String nickname, String certusage) {
+ boolean r = true;
+ CertificateUsage cu = null;
+ cu = getCertificateUsage(certusage);
+ int ccu = 0;
+
+ if (cu == null) {
+ CMS.debug("CertUtils: verifySystemCertByNickname() failed: "+
+ nickname + " with unsupported certusage ="+ certusage);
+ return false;
+ }
+
+ if (certusage == "")
+ CMS.debug("CertUtils: verifySystemCertByNickname(): required certusage not defined, getting current certusage");
+ CMS.debug("CertUtils: verifySystemCertByNickname(): calling isCertValid()");
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ if (cu.getUsage() != CryptoManager.CertificateUsage.CheckAllUsages.getUsage()) {
+ if (cm.isCertValid(nickname, true, cu)) {
+ r = true;
+ CMS.debug("CertUtils: verifySystemCertByNickname() passed:" + nickname);
+ } else {
+ CMS.debug("CertUtils: verifySystemCertByNickname() failed:" + nickname);
+ r = false;
+ }
+ } else {
+ // find out about current cert usage
+ ccu = cm.isCertValid(nickname, true);
+ if (ccu == CertificateUsage.basicCertificateUsages) {
+ /* cert is good for nothing */
+ r = false;
+ CMS.debug("CertUtils: verifySystemCertByNickname() failed: cert is good for nothing:"+ nickname);
+ } else {
+ r = true;
+ CMS.debug("CertUtils: verifySystemCertByNickname() passed:" + nickname);
+
+ if ((ccu & CryptoManager.CertificateUsage.SSLServer.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is SSLServer");
+ if ((ccu & CryptoManager.CertificateUsage.SSLClient.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is SSLClient");
+ if ((ccu & CryptoManager.CertificateUsage.SSLServerWithStepUp.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is SSLServerWithStepUp");
+ if ((ccu & CryptoManager.CertificateUsage.SSLCA.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is SSLCA");
+ if ((ccu & CryptoManager.CertificateUsage.EmailSigner.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is EmailSigner");
+ if ((ccu & CryptoManager.CertificateUsage.EmailRecipient.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is EmailRecipient");
+ if ((ccu & CryptoManager.CertificateUsage.ObjectSigner.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is ObjectSigner");
+ if ((ccu & CryptoManager.CertificateUsage.UserCertImport.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is UserCertImport");
+ if ((ccu & CryptoManager.CertificateUsage.VerifyCA.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is VerifyCA");
+ if ((ccu & CryptoManager.CertificateUsage.ProtectedObjectSigner.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is ProtectedObjectSigner");
+ if ((ccu & CryptoManager.CertificateUsage.StatusResponder.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is StatusResponder");
+ if ((ccu & CryptoManager.CertificateUsage.AnyCA.getUsage()) != 0)
+ CMS.debug("CertUtils: verifySystemCertByNickname(): cert is AnyCA");
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("CertUtils: verifySystemCertByNickname() failed: "+
+ e.toString());
+ r = false;
+ }
+ return r;
+ }
+
+ /*
+ * verify a certificate by its tag name
+ * returns true if it verifies; false if any not
+ */
+ public static boolean verifySystemCertByTag(String tag) {
+ String auditMessage = null;
+ IConfigStore config = CMS.getConfigStore();
+ boolean r = true;
+ try {
+ String subsysType = config.getString("cs.type", "");
+ if (subsysType.equals("")) {
+ CMS.debug("CertUtils: verifySystemCertByTag() cs.type not defined in CS.cfg. System certificates verification not done");
+ r = false;
+ }
+ subsysType = toLowerCaseSubsystemType(subsysType);
+ if (subsysType == null) {
+ CMS.debug("CertUtils: verifySystemCerts() invalid cs.type in CS.cfg. System certificates verification not done");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ return r;
+ }
+ String nickname = config.getString(subsysType+".cert."+tag+".nickname", "");
+ if (nickname.equals("")) {
+ CMS.debug("CertUtils: verifySystemCertByTag() nickname for cert tag " + tag + " undefined in CS.cfg");
+ r = false;
+ }
+ String certusage = config.getString(subsysType+".cert."+tag+".certusage", "");
+ if (certusage.equals("")) {
+ CMS.debug("CertUtils: verifySystemCertByTag() certusage for cert tag " + tag + " undefined in CS.cfg, getting current certificate usage");
+ }
+ r = verifySystemCertByNickname(nickname, certusage);
+ if (r == true) {
+ // audit here
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS,
+ nickname);
+
+ audit(auditMessage);
+ } else {
+ // audit here
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ nickname);
+
+ audit(auditMessage);
+ }
+ } catch (Exception e) {
+ CMS.debug("CertUtils: verifySystemCertsByTag() failed: "+
+ e.toString());
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ }
+
+ return r;
+ }
+
+ /*
+ * returns CertificateUsage mapping to JSS
+ */
+ public static CertificateUsage getCertificateUsage(String certusage) {
+ CertificateUsage cu = null;
+ if ((certusage == null) || certusage.equals(""))
+ cu = CryptoManager.CertificateUsage.CheckAllUsages;
+ else if (certusage.equalsIgnoreCase("CheckAllUsages"))
+ cu = CryptoManager.CertificateUsage.CheckAllUsages;
+ else if (certusage.equalsIgnoreCase("SSLServer"))
+ cu = CryptoManager.CertificateUsage.SSLServer;
+ else if (certusage.equalsIgnoreCase("SSLServerWithStepUp"))
+ cu = CryptoManager.CertificateUsage.SSLServerWithStepUp;
+ else if (certusage.equalsIgnoreCase("SSLClient"))
+ cu = CryptoManager.CertificateUsage.SSLClient;
+ else if (certusage.equalsIgnoreCase("SSLCA"))
+ cu = CryptoManager.CertificateUsage.SSLCA;
+ else if (certusage.equalsIgnoreCase("AnyCA"))
+ cu = CryptoManager.CertificateUsage.AnyCA;
+ else if (certusage.equalsIgnoreCase("StatusResponder"))
+ cu = CryptoManager.CertificateUsage.StatusResponder;
+ else if (certusage.equalsIgnoreCase("ObjectSigner"))
+ cu = CryptoManager.CertificateUsage.ObjectSigner;
+ else if (certusage.equalsIgnoreCase("UserCertImport"))
+ cu = CryptoManager.CertificateUsage.UserCertImport;
+ else if (certusage.equalsIgnoreCase("ProtectedObjectSigner"))
+ cu = CryptoManager.CertificateUsage.ProtectedObjectSigner;
+ else if (certusage.equalsIgnoreCase("VerifyCA"))
+ cu = CryptoManager.CertificateUsage.VerifyCA;
+ else if (certusage.equalsIgnoreCase("EmailSigner"))
+ cu = CryptoManager.CertificateUsage.EmailSigner;
+
+ return cu;
+ }
+
+ /*
+ * goes through all system certs and check to see if they are good
+ * and audit the result
+ * returns true if all verifies; false if any not
+ */
+ public static boolean verifySystemCerts() {
+ String auditMessage = null;
+ IConfigStore config = CMS.getConfigStore();
+ String certlsit = "";
+ boolean r = true;
+ try {
+ String subsysType = config.getString("cs.type", "");
+ if (subsysType.equals("")) {
+ CMS.debug("CertUtils: verifySystemCerts() cs.type not defined in CS.cfg. System certificates verification not done");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ return r;
+ }
+ subsysType = toLowerCaseSubsystemType(subsysType);
+ if (subsysType == null) {
+ CMS.debug("CertUtils: verifySystemCerts() invalid cs.type in CS.cfg. System certificates verification not done");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ return r;
+ }
+ String certlist = config.getString(subsysType+".cert.list", "");
+ if (certlist.equals("")) {
+ CMS.debug("CertUtils: verifySystemCerts() "+subsysType+ ".cert.list not defined in CS.cfg. System certificates verification not done");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ return r;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(certlist, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String tag = tokenizer.nextToken();
+ tag = tag.trim();
+ CMS.debug("CertUtils: verifySystemCerts() cert tag=" + tag);
+ r = verifySystemCertByTag(tag);
+ }
+ } catch (Exception e) {
+ // audit here
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CIMC_CERT_VERIFICATION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE,
+ "");
+
+ audit(auditMessage);
+ r = false;
+ CMS.debug("CertUtils: verifySystemCerts():" + e.toString());
+ }
+ return r;
+ }
+
+ public static String toLowerCaseSubsystemType(String s) {
+ String x = null;
+ if (s.equalsIgnoreCase("CA")) {
+ x = "ca";
+ } else if (s.equalsIgnoreCase("KRA")) {
+ x = "kra";
+ } else if (s.equalsIgnoreCase("OCSP")) {
+ x = "ocsp";
+ } else if (s.equalsIgnoreCase("TKS")) {
+ x = "tks";
+ }
+
+ return x;
+ }
+
+ /**
+ * Signed Audit Log
+ * This method is called to store messages to the signed audit log.
+ * @param msg signed audit log message
+ */
+ private static void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CertificatePair.java b/pki/base/common/src/com/netscape/cmscore/cert/CertificatePair.java
new file mode 100644
index 000000000..979e0fdd8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CertificatePair.java
@@ -0,0 +1,271 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.security.cert.*;
+import org.mozilla.jss.asn1.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.cert.ICrossCertPairSubsystem;
+
+
+/**
+ * This class implements CertificatePair used for Cross Certification
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CertificatePair implements ASN1Value {
+ private byte[] mForward; // cert cross-siged by another CA
+ private byte[] mReverse; // subordinate cert signed by this CA
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ /**
+ * construct a CertificatePair. It doesn't matter which is
+ * forward and which is reverse in the parameters. It will figure
+ * it out
+ * @param cert1 one X509Certificate
+ * @param cert2 one X509Certificate
+ */
+ public CertificatePair (X509Certificate cert1, X509Certificate cert2)
+ throws EBaseException {
+ if ((cert1 == null) || (cert2 == null))
+ throw new EBaseException("CertificatePair: both certs can not be null");
+ debug("in CertificatePair()");
+ boolean rightOrder = certOrders(cert1, cert2);
+
+ try {
+ if (rightOrder == false) {
+ mForward = cert2.getEncoded();
+ mReverse = cert1.getEncoded();
+ } else {
+ mForward = cert1.getEncoded();
+ mReverse = cert2.getEncoded();
+ }
+ } catch (CertificateException e) {
+ throw new EBaseException("CertificatePair: constructor failed:" + e.toString());
+ }
+ }
+
+ /**
+ * construct a CertificatePair. It doesn't matter which is
+ * forward and which is reverse in the parameters. It will figure
+ * it out
+ * @param cert1 one certificate byte array
+ * @param cert2 one certificate byte array
+ */
+ public CertificatePair (byte[] cert1, byte[] cert2)
+ throws EBaseException {
+ if ((cert1 == null) || (cert2 == null))
+ throw new EBaseException("CertificatePair: both certs can not be null");
+ boolean rightOrder = certOrders(cert1, cert2);
+
+ if (rightOrder == false) {
+ mForward = cert2;
+ mReverse = cert1;
+ } else {
+ mForward = cert1;
+ mReverse = cert2;
+ }
+ }
+
+ /*
+ * returns true if c1 is forward and cert2 is reverse
+ * returns false if c2 is forward and cert1 is reverse
+ */
+ private boolean certOrders(X509Certificate c1, X509Certificate c2)
+ throws EBaseException {
+ debug("in certOrders() with X509Cert");
+
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca");
+ X509Certificate caCert = (X509Certificate) ca.getCACert();
+
+ debug("got this caCert");
+ // reverse cert is the one signed by this ca
+ // more check really should be done here regarding the
+ // validity of the two certs...later
+
+ /* It looks the DN's returned are not normalized and fail
+ * comparison
+
+ if ((c1.getIssuerDN().equals((Object) caCert.getSubjectDN())))
+ debug("myCA signed c1");
+ else {
+ debug("c1 issuerDN="+c1.getIssuerDN().toString());
+ debug("myCA subjectDN="+caCert.getSubjectDN().toString());
+ }
+
+ if(caCert.getSubjectDN().equals((Object) c2.getSubjectDN()))
+ debug("myCA subject == c2 subject");
+ else {
+ debug("caCert subjectDN="+caCert.getSubjectDN().toString());
+ debug("c2 subjectDN="+c2.getSubjectDN().toString());
+ }
+
+ if ((c2.getIssuerDN().equals((Object) caCert.getSubjectDN())))
+ debug("myCA signed c2");
+ else {
+ debug("c2 issuerDN="+c1.getIssuerDN().toString());
+ debug("myCA subjectDN="+caCert.getSubjectDN().toString());
+ }
+
+ if(caCert.getSubjectDN().equals((Object) c1.getSubjectDN()))
+ debug("myCA subject == c1 subject");
+ else {
+ debug("caCert subjectDN="+caCert.getSubjectDN().toString());
+ debug("c1 subjectDN="+c1.getSubjectDN().toString());
+ }
+
+ if ((c1.getIssuerDN().equals((Object) caCert.getSubjectDN()))
+ && (caCert.getSubjectDN().equals((Object) c2.getSubjectDN())))
+
+ {
+ return false;
+ } else if ((c2.getIssuerDN().equals((Object) caCert.getSubjectDN()))
+ && (caCert.getSubjectDN().equals((Object) c1.getSubjectDN())))
+ {
+ return true;
+ } else {
+ throw new EBaseException("CertificatePair: need correct forward and reverse relationship to construct CertificatePair");
+ }
+ */
+
+ /*
+ * my other attempt:
+ * one of the certs has to share the same public key as this
+ * CA, and that will be the "forward" cert; the other one is
+ * assumed to be the "reverse" cert
+ */
+ byte[] caCertBytes = caCert.getPublicKey().getEncoded();
+
+ if (caCertBytes != null)
+ debug("got cacert public key bytes length=" + caCertBytes.length);
+ else {
+ debug("cacert public key bytes null");
+ throw new EBaseException("CertificatePair: certOrders() fails to get this CA's signing certificate public key encoded");
+ }
+
+ byte[] c1Bytes = c1.getPublicKey().getEncoded();
+
+ if (c1Bytes != null)
+ debug("got c1 public key bytes length=" + c1Bytes.length);
+ else {
+ debug("c1 cert public key bytes length null");
+ throw new EBaseException("CertificatePair::certOrders() public key bytes are of length null");
+ }
+
+ byte[] c2Bytes = c2.getPublicKey().getEncoded();
+
+ if (c2Bytes != null)
+ debug("got c2 public key bytes length=" + c2Bytes.length);
+ else
+ debug("c2 cert public key bytes length null");
+
+ if (byteArraysAreEqual(c1Bytes, caCertBytes)) {
+ debug("c1 has same public key as this ca");
+ return true;
+ } else if (byteArraysAreEqual(c2Bytes, caCertBytes)) {
+ debug("c2 has same public key as this ca");
+
+ return false;
+ } else {
+ debug("neither c1 nor c2 public key matches with this ca");
+ throw new EBaseException("CertificatePair: need correct forward and reverse relationship to construct CertificatePair");
+ }
+ }
+
+ /**
+ * compares contents two byte arrays returning true if exactly same.
+ */
+ public boolean byteArraysAreEqual(byte[] a, byte[] b) {
+ debug("in byteArraysAreEqual()");
+ if (a.length != b.length) {
+ debug("exiting byteArraysAreEqual(): false");
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ debug("exiting byteArraysAreEqual(): false");
+ return false;
+ }
+ }
+ debug("exiting byteArraysAreEqual(): true");
+ return true;
+ }
+
+ /*
+ * returns true if cert1 is forward and cert2 is reverse
+ * returns false if cert2 is forward and cert1 is reverse
+ */
+ private boolean certOrders(byte[] cert1, byte[] cert2)
+ throws EBaseException {
+ debug("in certOrders() with byte[]");
+ ICrossCertPairSubsystem ccps =
+ (ICrossCertPairSubsystem) CMS.getSubsystem("CrossCertPair");
+ X509Certificate c1 = null;
+ X509Certificate c2 = null;
+
+ try {
+ c1 = ccps.byteArray2X509Cert(cert1);
+ c2 = ccps.byteArray2X509Cert(cert2);
+ } catch (CertificateException e) {
+ throw new EBaseException("CertificatePair: certOrders() failed:" + e.toString());
+ }
+ return certOrders(c1, c2);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(TAG, os);
+ }
+
+ public void encode(Tag implicitTag, OutputStream os) throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+
+ if (mForward != null) {
+ try {
+ ANY any = new ANY(mForward);
+
+ seq.addElement(any);
+ } catch (InvalidBERException e) {
+ debug("encode error:" + e.toString());
+ }
+ }
+ if (mReverse != null) {
+ try {
+ ANY any = new ANY(mReverse);
+
+ seq.addElement(any);
+ } catch (InvalidBERException e) {
+ debug("encode error:" + e.toString());
+ }
+ }
+
+ seq.encode(implicitTag, os);
+ }
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ private void debug(String msg) {
+ CMS.debug("CertifiatePair: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java b/pki/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java
new file mode 100644
index 000000000..693d881c5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java
@@ -0,0 +1,257 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.certsrv.apps.*;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class CrlCachePrettyPrint implements ICRLPrettyPrint
+{
+
+ /*==========================================================
+ * constants
+ *==========================================================*/
+ private final static String CUSTOM_LOCALE = "Custom";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private ICRLIssuingPoint mIP = null;
+ private PrettyPrintFormat pp = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CrlCachePrettyPrint(ICRLIssuingPoint ip) {
+ mIP = ip;
+ pp = new PrettyPrintFormat(":");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * This method return string representation of the certificate
+ * revocation list in predefined format using specified client
+ * local. I18N Support.
+ *
+ * @param clientLocale Locale to be used for localization
+ * @return string representation of the certificate
+ */
+ public String toString(Locale clientLocale) {
+ return toString(clientLocale, 0, 0, 0);
+ }
+
+ public String toString(Locale clientLocale, long crlSize, long pageStart, long pageSize) {
+
+ //get I18N resources
+ ResourceBundle resource = ResourceBundle.getBundle(
+ PrettyPrintResources.class.getName());
+ DateFormat dateFormater = DateFormat.getDateTimeInstance(
+ DateFormat.FULL, DateFormat.FULL, clientLocale);
+ //get timezone and timezone ID
+ String tz = " ";
+ String tzid = " ";
+
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(4) + resource.getString(
+ PrettyPrintResources.TOKEN_CRL) + "\n");
+ sb.append(pp.indent(8) + resource.getString(
+ PrettyPrintResources.TOKEN_DATA) + "\n");
+
+ String signingAlgorithm = mIP.getLastSigningAlgorithm();
+ if (signingAlgorithm != null) {
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGALG) +
+ signingAlgorithm + "\n");
+ }
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_ISSUER) +
+ ((ICertificateAuthority)(mIP.getCertificateAuthority()))
+ .getCRLX500Name().toString() + "\n");
+ // Format thisUpdate
+ String thisUpdate = dateFormater.format(mIP.getLastUpdate());
+
+ // get timezone and timezone ID
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(mIP.getLastUpdate()),
+ TimeZone.SHORT,
+ clientLocale);
+ tzid = TimeZone.getDefault().getID();
+ }
+ // Specify ThisUpdate
+ if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) {
+ // Do NOT append timezone ID
+ sb.append(pp.indent(12)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_THIS_UPDATE)
+ + thisUpdate
+ + "\n");
+ } else {
+ // Append timezone ID
+ sb.append(pp.indent(12)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_THIS_UPDATE)
+ + thisUpdate
+ + " " + tzid + "\n");
+ }
+ // Check for presence of NextUpdate
+ if (mIP.getNextUpdate() != null) {
+ // Format nextUpdate
+ String nextUpdate = dateFormater.format(mIP.getNextUpdate());
+
+ // re-get timezone (just in case it is different . . .)
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(mIP.getNextUpdate()),
+ TimeZone.SHORT,
+ clientLocale);
+ }
+ // Specify NextUpdate
+ if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) {
+ // Do NOT append timezone ID
+ sb.append(pp.indent(12)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NEXT_UPDATE)
+ + nextUpdate
+ + "\n");
+ } else {
+ // Append timezone ID
+ sb.append(pp.indent(12)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NEXT_UPDATE)
+ + nextUpdate
+ + " " + tzid + "\n");
+ }
+ }
+
+ if (crlSize > 0 && pageStart == 0 && pageSize == 0) {
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_REVOKED_CERTIFICATES) + crlSize + "\n");
+ } else if ((crlSize == 0 && pageStart == 0 && pageSize == 0) ||
+ (crlSize > 0 && pageStart > 0 && pageSize > 0)) {
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_REVOKED_CERTIFICATES));
+ long upperLimit = crlSize;
+ if (crlSize > 0 && pageStart > 0 && pageSize > 0) {
+ upperLimit = (pageStart + pageSize - 1 > crlSize) ? crlSize : pageStart + pageSize - 1;
+ sb.append("" + pageStart + "-" + upperLimit + " of " + crlSize);
+ } else {
+ pageStart = 1;
+ sb.append("" + crlSize);
+ }
+ sb.append("\n");
+
+ Set revokedCerts = mIP.getRevokedCertificates((int)(pageStart-1), (int)upperLimit);
+
+ if (revokedCerts != null) {
+ Iterator i = revokedCerts.iterator();
+ long l = 1;
+
+ while ((i.hasNext()) && ((crlSize == 0) || (upperLimit - pageStart + 1 >= l))) {
+ RevokedCertImpl revokedCert = (RevokedCertImpl)i.next();
+
+ if ((crlSize == 0) || (upperLimit - pageStart + 1 >= l)) {
+ sb.append(pp.indent(16) + resource.getString(
+ PrettyPrintResources.TOKEN_SERIAL) + "0x" +
+ revokedCert.getSerialNumber().toString(16).toUpperCase() + "\n");
+ String revocationDate =
+ dateFormater.format(revokedCert.getRevocationDate());
+
+ // re-get timezone
+ // (just in case it is different . . .)
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(
+ revokedCert.getRevocationDate()),
+ TimeZone.SHORT,
+ clientLocale);
+ }
+ // Specify revocationDate
+ if (tz.equals(tzid) ||
+ tzid.equals(CUSTOM_LOCALE)) {
+ // Do NOT append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_REVOCATION_DATE)
+ + revocationDate
+ + "\n");
+ } else {
+ // Append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_REVOCATION_DATE)
+ + revocationDate
+ + " " + tzid + "\n");
+ }
+ if (revokedCert.hasExtensions()) {
+ sb.append(pp.indent(16) + resource.getString(
+ PrettyPrintResources.TOKEN_EXTENSIONS) + "\n");
+ CRLExtensions crlExtensions = revokedCert.getExtensions();
+
+ if (crlExtensions != null) {
+ for (int k = 0; k < crlExtensions.size(); k++) {
+ Extension ext = (Extension) crlExtensions.elementAt(k);
+ ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 20);
+
+ sb.append(extpp.toString());
+ }
+ }
+ }
+ }
+ l++;
+ }
+ } else if (mIP.isCRLCacheEnabled() && mIP.isCRLCacheEmpty()) {
+ sb.append("\n" + pp.indent(16) + resource.getString(
+ PrettyPrintResources.TOKEN_CACHE_IS_EMPTY) + "\n\n");
+ } else {
+ sb.append("\n" + pp.indent(16) + resource.getString(
+ PrettyPrintResources.TOKEN_CACHE_NOT_AVAILABLE) + "\n\n");
+ }
+ }
+
+ } catch (Exception e) {
+ sb.append("\n\n" + pp.indent(4) + resource.getString(
+ PrettyPrintResources.TOKEN_DECODING_ERROR) + "\n\n");
+ CMS.debug("Exception="+e.toString());
+ CMS.debugStackTrace();
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java b/pki/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java
new file mode 100644
index 000000000..2f7c08dee
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java
@@ -0,0 +1,44 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.security.cert.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.util.*;
+import java.security.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class CrlPrettyPrint extends netscape.security.util.CrlPrettyPrint implements ICRLPrettyPrint {
+
+ public CrlPrettyPrint(X509CRLImpl crl) {
+ super(crl);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java b/pki/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java
new file mode 100644
index 000000000..41020abd1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java
@@ -0,0 +1,491 @@
+// --- 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.cmscore.cert;
+
+
+import netscape.ldap.*;
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.security.util.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.cert.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.ldapconn.*;
+
+
+/**
+ * Subsystem for handling cross certificate pairing and publishing
+ * Intended use:
+ * <ul>
+ * <li> when signing a subordinate CA cert which is intended to be
+ * part of the crossCertificatePair
+ * <li> when this ca submits a request (with existing CA signing key
+ * material to another ca for cross-signing
+ *</ul>
+ * In both cases, administrator needs to "import" the crossSigned
+ * certificates via the admin console. When importCert() is called,
+ * the imported cert will be stored in the internal db
+ * first until it's pairing cert shows up.
+ * If it happens that the above two cases finds its pairing
+ * cert already there, then a CertifiatePair is created and put
+ * in the internal db "crosscertificatepair;binary" attribute
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CrossCertPairSubsystem implements ICrossCertPairSubsystem {
+
+ public static final String ID = "CrossCertPair";
+ public static final String DN_XCERTS = "cn=crossCerts";
+ public static final String LDAP_ATTR_CA_CERT = "caCertificate;binary";
+ public static final String LDAP_ATTR_XCERT_PAIR = "crossCertificatePair;binary";
+ protected static final String PROP_LDAP = "ldap";
+ protected static final String PROP_BASEDN = "basedn";
+
+ protected IConfigStore mConfig = null;
+ protected LdapBoundConnFactory mLdapConnFactory = null;
+ protected String mBaseDN = null;
+ protected ICertificateAuthority mCa = null;
+ protected IPublisherProcessor mPublisherProcessor = null;
+
+ private String mId = ID;
+ private ILogger mLogger = null;
+
+ public CrossCertPairSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ try {
+ mConfig = config;
+ mLogger = CMS.getLogger();
+ mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+ mPublisherProcessor = mCa.getPublisherProcessor();
+
+ // initialize LDAP connection factory
+ IConfigStore ldapConfig = mConfig.getSubStore(PROP_LDAP);
+
+ if (ldapConfig == null) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("CMSCORE_DBS_CONF_ERROR",
+ PROP_LDAP));
+ return;
+ }
+
+ mBaseDN = ldapConfig.getString(PROP_BASEDN, null);
+
+ mLdapConnFactory = new LdapBoundConnFactory();
+
+ if (mLdapConnFactory != null)
+ mLdapConnFactory.init(ldapConfig);
+ else {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("CMSCORE_DBS_CONF_ERROR",
+ PROP_LDAP));
+ return;
+ }
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+ }
+
+ /**
+ * "import" the CA cert cross-signed by another CA (potentially a
+ * bridge CA) into internal ldap db.
+ * the imported cert will be stored in the internal db
+ * first until it's pairing cert shows up.
+ * If it happens that it finds its pairing
+ * cert already there, then a CertifiatePair is created and put
+ * in the internal db "crosscertificatepair;binary" attribute
+ *
+ * @param certBytes cert in byte array to be imported
+ */
+ public void importCert(byte[] certBytes) throws EBaseException {
+ debug("importCert(byte[])");
+ X509Certificate cert = null;
+
+ try {
+ cert = byteArray2X509Cert(certBytes);
+ } catch (CertificateException e) {
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+
+ }
+
+ importCert((Object) cert);
+ }
+
+ /**
+ * "import" the CA cert cross-signed by another CA (potentially a
+ * bridge CA) into internal ldap db.
+ * the imported cert will be stored in the internal db
+ * first until it's pairing cert shows up.
+ * If it happens that it finds its pairing
+ * cert already there, then a CertifiatePair is created and put
+ * in the internal db "crosscertificatepair;binary" attribute
+ *
+ * @param certBytes cert in byte array to be imported
+ */
+ public synchronized void importCert(Object certObj) throws EBaseException {
+ if (!(certObj instanceof X509Certificate))
+ throw new IllegalArgumentException("Illegal arg to publish");
+
+ debug("in importCert(Object)");
+ X509Certificate cert = (X509Certificate) certObj;
+ // check to see if this is a valid cross-signed ca cert:
+ // 1. does cert2 share the same key pair as this CA's signing
+ // cert
+ // 2. does cert2's subject match this CA's subject?
+ // 3. other valididity checks: is this a ca cert? Is this
+ // cert still valid? If the issuer is not yet trusted, let it
+ // be.
+
+ // get certs from internal db to see if we find a pair
+ LDAPConnection conn = null;
+
+ try {
+ conn = getConn();
+ LDAPSearchResults res = conn.search(mBaseDN, LDAPv2.SCOPE_SUB,
+ DN_XCERTS, null, false);
+
+ if (res.hasMoreElements()) {
+ log(ILogger.LL_INFO, "ldap search found " + DN_XCERTS);
+
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ LDAPAttribute caCerts = entry.getAttribute(LDAP_ATTR_CA_CERT);
+ LDAPAttribute certPairs = entry.getAttribute(LDAP_ATTR_XCERT_PAIR);
+
+ if (caCerts == null) {
+ debug("no existing ca certs, just import");
+ addCAcert(conn, cert.getEncoded());
+ return;
+ }
+
+ Enumeration en = caCerts.getByteValues();
+
+ if ((en == null) || (en.hasMoreElements() == false)) {
+ debug("1st potential xcert");
+ addCAcert(conn, cert.getEncoded());
+ debug("potential cross ca cert added to crossCerts entry successfully");
+ return;
+ }
+ byte[] val = null;
+ boolean match = false;
+
+ while (en.hasMoreElements()) {
+ val = (byte[]) en.nextElement();
+ debug("val =" + val.length);
+ if (val.length == 0) {
+ continue;
+ } else {
+ X509Certificate inCert = byteArray2X509Cert(val);
+
+ if (arePair(inCert, cert)) {
+ // found a pair,form xcert, write to
+ // crossCertificatePair attr, remove from
+ // caCertificate attr, and publish if so configured
+ debug("found a pair!");
+ CertificatePair cp = new
+ // CertificatePair(inCert.getEncoded(), cert.getEncoded());
+ CertificatePair(inCert, cert);
+
+ addXCertPair(conn, certPairs, cp);
+ deleteCAcert(conn, inCert.getEncoded());
+ // found a match, get out
+ match = true;
+ break;
+ }
+ }
+ } //while
+ if (match == false) {
+ // don't find a pair, add it into
+ // caCertificate attr for later pairing
+ // opportunities
+ debug("didn't find a pair!");
+ addCAcert(conn, cert.getEncoded());
+ debug("potential cross ca cert added to crossCerts entry successfully");
+ }
+
+ } else {
+ log(ILogger.LL_INFO, "ldap search found no " + DN_XCERTS);
+ }
+ } catch (IOException e) {
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, "exception: " + e.toString());
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, "exception: " + e.toString());
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, "exception: " + e.toString());
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+ } finally {
+ try {
+ returnConn(conn);
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, "exception: " + e.toString());
+ throw new EBaseException("CrossCertPairSubsystem: importCert() failed:" + e.toString());
+ }
+ }
+ debug("importCert(Object) completed");
+ }
+
+ /**
+ * are cert1 and cert2 cross-signed certs?
+ * @param cert1 the cert for comparison in our internal db
+ * @param cert2 the cert that's being considered
+ */
+ protected boolean arePair(X509Certificate cert1, X509Certificate cert2) {
+ // 1. does cert1's issuer match cert2's subject?
+ // 2. does cert2's issuer match cert1's subject?
+ if ((cert1.getIssuerDN().equals((Object) cert2.getSubjectDN()))
+ && (cert2.getIssuerDN().equals((Object) cert1.getSubjectDN())))
+ return true;
+ else
+ return false;
+ }
+
+ public X509Certificate byteArray2X509Cert(byte[] certBytes)
+ throws CertificateException {
+ debug("in bytearray2X509Cert()");
+ ByteArrayInputStream inStream = new
+ ByteArrayInputStream(certBytes);
+
+ CertificateFactory cf =
+ CertificateFactory.getInstance("X.509");
+
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
+
+ debug("done bytearray2X509Cert()");
+ return cert;
+ }
+
+ public synchronized void addXCertPair(LDAPConnection conn,
+ LDAPAttribute certPairs, CertificatePair pair)
+ throws LDAPException, IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ pair.encode(bos);
+
+ if (ByteValueExists(certPairs, bos.toByteArray()) == true) {
+ debug("cross cert pair exists in internal db, don't add again");
+ return;
+ }
+
+ // add certificatePair
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ATTR_XCERT_PAIR, bos.toByteArray()));
+ conn.modify(DN_XCERTS + "," + mBaseDN, modSet);
+ }
+
+ /**
+ * checks if a byte attribute has a certain value.
+ */
+ public static boolean ByteValueExists(LDAPAttribute attr, byte[] bval) {
+ if (attr == null) {
+ return false;
+ }
+ Enumeration vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ if (val.length == 0)
+ continue;
+ if (byteArraysAreEqual(val, bval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * compares contents two byte arrays returning true if exactly same.
+ */
+ static public boolean byteArraysAreEqual(byte[] a, byte[] b) {
+ debug("in byteArraysAreEqual()");
+ if (a.length != b.length) {
+ debug("exiting byteArraysAreEqual(): false");
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ debug("exiting byteArraysAreEqual(): false");
+ return false;
+ }
+ }
+ debug("exiting byteArraysAreEqual(): true");
+ return true;
+ }
+
+ public synchronized void addCAcert(LDAPConnection conn, byte[] certEnc)
+ throws LDAPException {
+ LDAPModificationSet modSet = new
+ LDAPModificationSet();
+
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ATTR_CA_CERT, certEnc));
+ conn.modify(DN_XCERTS + "," + mBaseDN, modSet);
+ }
+
+ public synchronized void deleteCAcert(LDAPConnection conn, byte[] certEnc)
+ throws LDAPException {
+ LDAPModificationSet modSet = new
+ LDAPModificationSet();
+
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(LDAP_ATTR_CA_CERT, certEnc));
+ conn.modify(DN_XCERTS + "," + mBaseDN, modSet);
+ }
+
+ /**
+ * publish all cert pairs, if publisher is on
+ */
+ public synchronized void publishCertPairs() throws EBaseException {
+ LDAPConnection conn = null;
+
+ if ((mPublisherProcessor == null) ||
+ !mPublisherProcessor.enabled())
+ return;
+
+ try {
+ conn = getConn();
+ // search in internal db for xcerts
+ LDAPSearchResults res = conn.search(mBaseDN, LDAPv2.SCOPE_SUB,
+ DN_XCERTS, null, false);
+
+ debug("trying to publish cert pairs, if any");
+ if ((res == null) || (res.hasMoreElements() == false)) {
+ debug("no cross cert pairs to publish");
+ return;
+ }
+
+ if (res.hasMoreElements()) {
+ log(ILogger.LL_INFO, "ldap search found " + DN_XCERTS);
+
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ LDAPAttribute xcerts = entry.getAttribute(LDAP_ATTR_XCERT_PAIR);
+
+ if (xcerts == null) {
+ debug("no cross cert pairs to publish");
+ return;
+ }
+
+ Enumeration en = xcerts.getByteValues();
+
+ if ((en == null) || (en.hasMoreElements() == false)) {
+ debug("publishCertPair found no pairs in internal db");
+ return;
+ }
+ byte[] val = null;
+
+ while (en.hasMoreElements()) {
+ val = (byte[]) en.nextElement();
+ debug("val =" + val.length);
+ if (val.length == 0) {
+ continue;
+ } else {
+ try {
+ //found a cross cert pair, publish if we could
+ IXcertPublisherProcessor xp = null;
+
+ xp = (IXcertPublisherProcessor) mPublisherProcessor;
+ xp.publishXCertPair(val);
+ } catch (Exception e) {
+ throw new EBaseException("CrossCertPairSubsystem: publishCertPairs() failed:" + e.toString());
+ }
+ }
+ }// while
+ }//if
+ } catch (Exception e) {
+ throw new EBaseException("CrossCertPairSubsystem: publishCertPairs() failed:" + e.toString());
+ }
+ }
+
+ protected LDAPConnection getConn() throws ELdapException {
+ if (mLdapConnFactory != null)
+ return mLdapConnFactory.getConn();
+
+ return null;
+ }
+
+ protected void returnConn(LDAPConnection conn) throws ELdapException {
+ if (mLdapConnFactory != null)
+ mLdapConnFactory.returnConn(conn);
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Stops this system.
+ */
+ public synchronized void shutdown() {
+ mCa = null;
+ mPublisherProcessor = null;
+ if (mLdapConnFactory != null) {
+ try {
+ mLdapConnFactory.reset();
+ } catch (ELdapException e) {
+ CMS.debug("CrossCertPairSubsystem shutdown exception: "+e.toString());
+ }
+ }
+ mLdapConnFactory = null;
+ }
+
+ /*
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_XCERT, level, msg);
+ }
+
+ private static void debug(String msg) {
+ CMS.debug("CrossCertPairSubsystem: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java b/pki/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java
new file mode 100644
index 000000000..09aea0aca
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java
@@ -0,0 +1,47 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.math.BigInteger;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+import netscape.security.x509.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.base.*;
+import java.security.*;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class ExtPrettyPrint extends netscape.security.util.ExtPrettyPrint implements IExtPrettyPrint {
+
+ public ExtPrettyPrint(Extension ext, int indentSize) {
+ super(ext, indentSize);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java b/pki/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java
new file mode 100644
index 000000000..7fd33f95f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java
@@ -0,0 +1,183 @@
+// --- 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.cmscore.cert;
+
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.ObjectIdentifier;
+import java.security.cert.CertificateException;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ *
+ * @author stevep
+ * @version $Revision
+ */
+public class OidLoaderSubsystem implements ISubsystem {
+
+ private IConfigStore mConfig = null;
+ public static final String ID = "oidmap";
+ private String mId = ID;
+
+ private static final String PROP_OID = "oid";
+ private static final String PROP_CLASS = "class";
+
+ /**
+ *
+ */
+ private OidLoaderSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ // singleton enforcement
+
+ private static OidLoaderSubsystem mInstance = new OidLoaderSubsystem();
+
+ public static OidLoaderSubsystem getInstance() {
+ return mInstance;
+ }
+
+ private static final int CertType_data[] = { 2, 16, 840, 1, 113730, 1, 1 };
+
+ /**
+ * Identifies the particular public key used to sign the certificate.
+ */
+ public static final ObjectIdentifier CertType_Id = new
+ ObjectIdentifier(CertType_data);
+
+ private static final String[][] oidMapEntries = new String[][] {
+ {NSCertTypeExtension.class.getName(),
+ CertType_Id.toString(),
+ NSCertTypeExtension.NAME},
+ {CertificateRenewalWindowExtension.class.getName(),
+ CertificateRenewalWindowExtension.ID.toString(),
+ CertificateRenewalWindowExtension.NAME},
+ {CertificateScopeOfUseExtension.class.getName(),
+ CertificateScopeOfUseExtension.ID.toString(),
+ CertificateScopeOfUseExtension.NAME},
+ {DeltaCRLIndicatorExtension.class.getName(),
+ DeltaCRLIndicatorExtension.OID,
+ DeltaCRLIndicatorExtension.NAME},
+ {HoldInstructionExtension.class.getName(),
+ HoldInstructionExtension.OID,
+ HoldInstructionExtension.NAME},
+ {InvalidityDateExtension.class.getName(),
+ InvalidityDateExtension.OID,
+ InvalidityDateExtension.NAME},
+ {IssuingDistributionPointExtension.class.getName(),
+ IssuingDistributionPointExtension.OID,
+ IssuingDistributionPointExtension.NAME},
+ {FreshestCRLExtension.class.getName(),
+ FreshestCRLExtension.OID,
+ FreshestCRLExtension.NAME},
+ };
+
+ /**
+ * Initializes this subsystem with the given
+ * configuration store.
+ * It first initializes resident subsystems,
+ * and it loads and initializes loadable
+ * subsystem specified in the configuration
+ * store.
+ * <P>
+ * Note that individual subsystem should be
+ * initialized in a separated thread if
+ * it has dependency on the initialization
+ * of other subsystems.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ */
+ public synchronized void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ if (Debug.ON) {
+ Debug.trace("OIDLoaderSubsystem started");
+ }
+ mConfig = config;
+
+ Enumeration names = mConfig.getSubStoreNames();
+
+ // load static (build-in) extensions
+
+ for (int i = 0; i < oidMapEntries.length; i++) {
+ try {
+ OIDMap.addAttribute(oidMapEntries[i][0],
+ oidMapEntries[i][1],
+ oidMapEntries[i][2]);
+ } catch (Exception e) {
+ }
+ }
+
+ // load dynamic extensions
+
+ while (names.hasMoreElements()) {
+ String substorename = (String) names.nextElement();
+ IConfigStore substore = mConfig.getSubStore(substorename);
+
+ try {
+ String oidname = substore.getString(PROP_OID);
+ String classname = substore.getString(PROP_CLASS);
+
+ OIDMap.addAttribute(classname,
+ oidname,
+ substorename);
+ } catch (EPropertyNotFound e) {
+ // Log error
+ } catch (CertificateException e) {
+ // log error
+ }
+ }
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Stops this system.
+ */
+ public synchronized void shutdown() {
+ }
+
+ /*
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java b/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java
new file mode 100644
index 000000000..550756f31
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java
@@ -0,0 +1,166 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class PrettyPrintFormat implements IPrettyPrintFormat {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String mSeparator = "";
+ private int mIndentSize = 0;
+ private int mLineLen = 0;
+
+ /*==========================================================
+ * constants
+ *
+ *==========================================================*/
+ private final static String spaces =
+ " " +
+ " " +
+ " " +
+ " " +
+ " ";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public PrettyPrintFormat(String separator) {
+ mSeparator = separator;
+ }
+
+ public PrettyPrintFormat(String separator, int lineLen) {
+ mSeparator = separator;
+ mLineLen = lineLen;
+ }
+
+ public PrettyPrintFormat(String separator, int lineLen, int indentSize) {
+ mSeparator = separator;
+ mLineLen = lineLen;
+ mIndentSize = indentSize;
+ }
+
+ /*==========================================================
+ * Private methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Provide white space indention
+ * stevep - speed improvements. Factor of 10 improvement
+ * @param numSpace number of white space to be returned
+ * @return white spaces
+ */
+ public String indent(int size) {
+ return spaces.substring(0, size);
+ }
+
+ private static final char[] hexdigits = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ /**
+ * Convert Byte Array to Hex String Format
+ * stevep - speedup by factor of 8
+ * @param byte array of data to hexify
+ * @param indentSize number of spaces to prepend before each line
+ * @param lineLen number of bytes to output on each line (0
+ means: put everything on one line
+ * @param separator the first character of this string will be used as
+ the separator between bytes.
+ * @return string representation
+ */
+
+ public String toHexString(byte[] in, int indentSize,
+ int lineLen, String separator) {
+ StringBuffer sb = new StringBuffer();
+ int hexCount = 0;
+ char c[];
+ int j = 0;
+
+ if (lineLen == 0) {
+ c = new char[in.length * 3 + 1];
+ } else {
+ c = new char[lineLen * 3 + 1];
+ }
+
+ char sep = separator.charAt(0);
+
+ sb.append(indent(indentSize));
+ for (int i = 0; i < in.length; i++) {
+ if (lineLen > 0 && hexCount == lineLen) {
+ c[j++] = '\n';
+ sb.append(c, 0, j);
+ sb.append(indent(indentSize));
+ hexCount = 0;
+ j = 0;
+ }
+ byte x = in[i];
+
+ // output hex digits to buffer
+ c[j++] = hexdigits[(char) ((x >> 4) & 0xf)];
+ c[j++] = hexdigits[(char) (x & 0xf)];
+
+ // if not last char, output separator
+ if (i != in.length - 1) {
+ c[j++] = sep;
+ }
+
+ hexCount++;
+ }
+ if (j > 0) {
+ c[j++] = '\n';
+ sb.append(c, 0, j);
+ }
+ // sb.append("\n");
+
+ return sb.toString();
+ }
+
+ public String toHexString(byte[] in, int indentSize, int lineLen) {
+ return toHexString(in, indentSize, lineLen, mSeparator);
+ }
+
+ public String toHexString(byte[] in, int indentSize) {
+ return toHexString(in, indentSize, mLineLen);
+ }
+
+ public String toHexString(byte[] in) {
+ return toHexString(in, mIndentSize);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java b/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java
new file mode 100644
index 000000000..026dbfcbc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java
@@ -0,0 +1,294 @@
+// --- 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.cmscore.cert;
+
+
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * Resource Boundle for the Pretty Print
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+
+public class PrettyPrintResources extends ListResourceBundle {
+
+ /**
+ * Returns content
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+
+ //certificate pretty print
+ public final static String TOKEN_CERTIFICATE = "tokenCertificate";
+ public final static String TOKEN_DATA = "tokenData";
+ public final static String TOKEN_VERSION = "tokenVersion";
+ public final static String TOKEN_SERIAL = "tokenSerial";
+ public final static String TOKEN_SIGALG = "tokenSignatureAlgorithm";
+ public final static String TOKEN_ISSUER = "tokenIssuer";
+ public final static String TOKEN_VALIDITY = "tokenValidity";
+ public final static String TOKEN_NOT_BEFORE = "tokenNotBefore";
+ public final static String TOKEN_NOT_AFTER = "tokenNotAfter";
+ public final static String TOKEN_SUBJECT = "tokenSubject";
+ public final static String TOKEN_SPKI = "tokenSPKI";
+ public final static String TOKEN_ALGORITHM = "tokenAlgorithm";
+ public final static String TOKEN_PUBLIC_KEY = "tokenPublicKey";
+ public final static String TOKEN_PUBLIC_KEY_MODULUS = "tokenPublicKeyModulus";
+ public final static String TOKEN_PUBLIC_KEY_EXPONENT = "tokenPublicKeyExponent";
+ public final static String TOKEN_EXTENSIONS = "tokenExtensions";
+ public final static String TOKEN_SIGNATURE = "tokenSignature";
+
+ //extension pretty print
+ public final static String TOKEN_YES = "tokenYes";
+ public final static String TOKEN_NO = "tokenNo";
+ public final static String TOKEN_IDENTIFIER = "tokenIdentifier";
+ public final static String TOKEN_CRITICAL = "tokenCritical";
+ public final static String TOKEN_VALUE = "tokenValue";
+
+ //specific extension token
+ public final static String TOKEN_KEY_TYPE = "tokenKeyType";
+ public final static String TOKEN_CERT_TYPE = "tokenCertType";
+ public final static String TOKEN_SKI = "tokenSKI";
+ public final static String TOKEN_AKI = "tokenAKI";
+ public final static String TOKEN_ACCESS_DESC = "tokenAccessDesc";
+ public final static String TOKEN_OCSP_NOCHECK = "tokenOcspNoCheck";
+ public final static String TOKEN_EXTENDED_KEY_USAGE = "tokenExtendedKeyUsage";
+ public final static String TOKEN_PRIVATE_KEY_USAGE = "tokenPrivateKeyUsage";
+ public final static String TOKEN_PRESENCE_SERVER = "tokenPresenceServer";
+ public final static String TOKEN_AIA = "tokenAIA";
+ public final static String TOKEN_KEY_USAGE = "tokenKeyUsage";
+ public final static String TOKEN_CERT_USAGE = "tokenCertUsage";
+ public final static String TOKEN_KEY_ID = "tokenKeyId";
+ public final static String TOKEN_AUTH_NAME = "tokenAuthName";
+
+ public final static String TOKEN_CRL = "tokenCRL";
+ public final static String TOKEN_THIS_UPDATE = "tokenThisUpdate";
+ public final static String TOKEN_NEXT_UPDATE = "tokenNextUpdate";
+ public final static String TOKEN_REVOKED_CERTIFICATES = "revokedCerts";
+ public final static String TOKEN_REVOCATION_DATE = "revocationDate";
+
+ public final static String TOKEN_REVOCATION_REASON = "revocationReason";
+ public final static String TOKEN_REASON = "reason";
+
+ public final static String TOKEN_BASIC_CONSTRAINTS = "basicConstraints";
+ public final static String TOKEN_NAME_CONSTRAINTS = "tokenNameConstraints";
+ public final static String TOKEN_NSC_COMMENT = "tokenNSCComment";
+ public final static String TOKEN_IS_CA = "isCA";
+ public final static String TOKEN_PATH_LEN = "pathLen";
+ public final static String TOKEN_PATH_LEN_UNLIMITED = "pathLenUnlimited";
+ public final static String TOKEN_PATH_LEN_UNDEFINED = "pathLenUndefined";
+ public final static String TOKEN_PATH_LEN_INVALID = "pathLenInvalid";
+
+ public final static String TOKEN_CRL_NUMBER = "CRLNumber";
+ public final static String TOKEN_NUMBER = "Number";
+
+ public final static String TOKEN_DELTA_CRL_INDICATOR = "DeltaCRLIndicator";
+ public final static String TOKEN_BASE_CRL_NUMBER = "BaseCRLNumber";
+
+ public final static String TOKEN_CERT_SCOPE_OF_USE = "CertificateScopeOfUse";
+ public final static String TOKEN_SCOPE_OF_USE = "ScopeOfUse";
+ public final static String TOKEN_PORT = "Port";
+
+ public final static String TOKEN_ISSUER_ALT_NAME = "IssuerAlternativeName";
+ public final static String TOKEN_ISSUER_NAMES = "IssuerNames";
+
+ public final static String TOKEN_SUBJECT_ALT_NAME = "SubjectAlternativeName";
+ public final static String TOKEN_SUBJECT_NAME = "SubjectName";
+
+ public final static String TOKEN_DECODING_ERROR = "decodingError";
+
+ public final static String TOKEN_FRESHEST_CRL_EXT = "FreshestCRL";
+
+ public final static String TOKEN_CRL_DP_EXT = "CRLDistributionPoints";
+ public final static String TOKEN_CRLDP_NUMPOINTS = "CRLDP_NUMPOINTS";
+ public final static String TOKEN_CRLDP_POINTN = "CRLDP_POINTN";
+ public final static String TOKEN_CRLDP_DISTPOINT = "CRLDP_DISTPOINT";
+ public final static String TOKEN_CRLDP_REASONS = "CRLDP_REASONS";
+ public final static String TOKEN_CRLDP_CRLISSUER = "CRLDP_CRLISSUER";
+
+ public final static String TOKEN_ISSUING_DIST_POINT = "IssuingDistributionPoint";
+ public final static String TOKEN_DIST_POINT_NAME = "DistributionPointName";
+ public final static String TOKEN_FULL_NAME = "FullName";
+ public final static String TOKEN_RELATIVE_NAME = "NameRelativeToCRLIssuer";
+ public final static String TOKEN_ONLY_USER_CERTS = "OnlyContainsUserCerts";
+ public final static String TOKEN_ONLY_CA_CERTS = "OnlyContainsCACerts";
+ public final static String TOKEN_ONLY_SOME_REASONS = "OnlySomeReasons";
+ public final static String TOKEN_INDIRECT_CRL = "IndirectCRL";
+
+ public final static String TOKEN_INVALIDITY_DATE = "invalidityDate";
+ public final static String TOKEN_DATE_OF_INVALIDITY = "dateOfInvalidity";
+
+ public final static String TOKEN_CERTIFICATE_ISSUER = "CertificateIssuer";
+
+ public final static String TOKEN_HOLD_INSTRUCTION = "HoldInstruction";
+ public final static String TOKEN_HOLD_INSTRUCTION_CODE = "HoldInstructionCode";
+ public final static String TOKEN_POLICY_CONSTRAINTS = "PolicyConstraints";
+ public final static String TOKEN_POLICY_MAPPINGS = "PolicyMappings";
+ public final static String TOKEN_SUBJECT_DIR_ATTR = "SubjectDirectoryAttributes";
+
+ // policy constriants extension fields
+ public final static String TOKEN_INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping";
+ public final static String TOKEN_REQUIRE_EXPLICIT_POLICY = "requireExplicitPolicy";
+
+ // policy mappings extension fields
+ public final static String TOKEN_MAPPINGS = "mappings";
+ public final static String TOKEN_MAP = "map";
+ public final static String TOKEN_ISSUER_DOMAIN_POLICY = "issuerDomainPolicy";
+ public final static String TOKEN_SUBJECT_DOMAIN_POLICY = "subjectDomainPolicy";
+
+ // subject directory attribute fields
+ public final static String TOKEN_ATTRIBUTES = "Attributes";
+ public final static String TOKEN_ATTRIBUTE = "Attribute";
+ public final static String TOKEN_VALUES = "Values";
+
+ // field values
+ public final static String TOKEN_NOT_SET = "notSet";
+ public final static String TOKEN_NONE = "none";
+
+ public final static String TOKEN_CACHE_NOT_AVAILABLE = "cacheNotAvailable";
+ public final static String TOKEN_CACHE_IS_EMPTY = "cacheIsEmpty";
+
+ //Tokens should have blank_space as trailer
+ static final Object[][] contents = {
+ {TOKEN_CERTIFICATE, "Certificate: "},
+ {TOKEN_DATA, "Data: "},
+ {TOKEN_VERSION, "Version: "},
+ {TOKEN_SERIAL, "Serial Number: "},
+ {TOKEN_SIGALG, "Signature Algorithm: "},
+ {TOKEN_ISSUER, "Issuer: "},
+ {TOKEN_VALIDITY, "Validity: "},
+ {TOKEN_NOT_BEFORE, "Not Before: "},
+ {TOKEN_NOT_AFTER, "Not After: "},
+ {TOKEN_SUBJECT, "Subject: "},
+ {TOKEN_SPKI, "Subject Public Key Info: "},
+ {TOKEN_ALGORITHM, "Algorithm: "},
+ {TOKEN_PUBLIC_KEY, "Public Key: "},
+ {TOKEN_PUBLIC_KEY_MODULUS, "Public Key Modulus: "},
+ {TOKEN_PUBLIC_KEY_EXPONENT, "Exponent: "},
+ {TOKEN_EXTENSIONS, "Extensions: "},
+ {TOKEN_SIGNATURE, "Signature: "},
+ {TOKEN_YES, "yes "},
+ {TOKEN_NO, "no "},
+ {TOKEN_IDENTIFIER, "Identifier: "},
+ {TOKEN_CRITICAL, "Critical: "},
+ {TOKEN_VALUE, "Value: "},
+ {TOKEN_KEY_TYPE, "Key Type "},
+ {TOKEN_CERT_TYPE, "Netscape Certificate Type "},
+ {TOKEN_SKI, "Subject Key Identifier "},
+ {TOKEN_AKI, "Authority Key Identifier "},
+ {TOKEN_ACCESS_DESC, "Access Description: "},
+ {TOKEN_OCSP_NOCHECK, "OCSP NoCheck: "},
+ {TOKEN_EXTENDED_KEY_USAGE, "Extended Key Usage: "},
+ {TOKEN_PRIVATE_KEY_USAGE, "Private Key Usage: "},
+ {TOKEN_PRESENCE_SERVER, "Presence Server: "},
+ {TOKEN_AIA, "Authority Info Access: "},
+ {TOKEN_KEY_USAGE, "Key Usage: "},
+ {KeyUsageExtension.DIGITAL_SIGNATURE, "Digital Signature "},
+ {KeyUsageExtension.NON_REPUDIATION, "Non Repudiation "},
+ {KeyUsageExtension.KEY_ENCIPHERMENT, "Key Encipherment "},
+ {KeyUsageExtension.DATA_ENCIPHERMENT, "Data Encipherment "},
+ {KeyUsageExtension.KEY_AGREEMENT, "Key Agreement "},
+ {KeyUsageExtension.KEY_CERTSIGN, "Key CertSign "},
+ {KeyUsageExtension.CRL_SIGN, "Crl Sign "},
+ {KeyUsageExtension.ENCIPHER_ONLY, "Encipher Only "},
+ {KeyUsageExtension.DECIPHER_ONLY, "Decipher Only "},
+ {TOKEN_CERT_USAGE, "Certificate Usage: "},
+ {NSCertTypeExtension.SSL_CLIENT, "SSL Client "},
+ {NSCertTypeExtension.SSL_SERVER, "SSL Server "},
+ {NSCertTypeExtension.EMAIL, "Secure Email "},
+ {NSCertTypeExtension.OBJECT_SIGNING, "Object Signing "},
+ {NSCertTypeExtension.SSL_CA, "SSL CA "},
+ {NSCertTypeExtension.EMAIL_CA, "Secure Email CA "},
+ {NSCertTypeExtension.OBJECT_SIGNING_CA, "ObjectSigning CA "},
+ {TOKEN_KEY_ID, "Key Identifier: "},
+ {TOKEN_AUTH_NAME, "Authority Name: "},
+ {TOKEN_CRL, "Certificate Revocation List: "},
+ {TOKEN_THIS_UPDATE, "This Update: "},
+ {TOKEN_NEXT_UPDATE, "Next Update: "},
+ {TOKEN_REVOKED_CERTIFICATES, "Revoked Certificates: "},
+ {TOKEN_REVOCATION_DATE, "Revocation Date: "},
+ {TOKEN_REVOCATION_REASON, "Revocation Reason "},
+ {TOKEN_REASON, "Reason: "},
+ {TOKEN_BASIC_CONSTRAINTS, "Basic Constraints "},
+ {TOKEN_NAME_CONSTRAINTS, "Name Constraints "},
+ {TOKEN_NSC_COMMENT, "Netscape Comment "},
+ {TOKEN_IS_CA, "Is CA: "},
+ {TOKEN_PATH_LEN, "Path Length Constraint: "},
+ {TOKEN_PATH_LEN_UNLIMITED, "UNLIMITED"},
+ {TOKEN_PATH_LEN_UNDEFINED, "UNDEFINED"},
+ {TOKEN_PATH_LEN_INVALID, "INVALID"},
+ {TOKEN_CRL_NUMBER, "CRL Number "},
+ {TOKEN_NUMBER, "Number: "},
+ {TOKEN_DELTA_CRL_INDICATOR, "Delta CRL Indicator "},
+ {TOKEN_BASE_CRL_NUMBER, "Base CRL Number: "},
+ {TOKEN_CERT_SCOPE_OF_USE, "Certificate Scope of Use "},
+ {TOKEN_SCOPE_OF_USE, "Scope of Use: "},
+ {TOKEN_PORT, "Port: "},
+ {TOKEN_ISSUER_ALT_NAME, "Issuer Alternative Name "},
+ {TOKEN_ISSUER_NAMES, "Issuer Names: "},
+ {TOKEN_SUBJECT_ALT_NAME, "Subject Alternative Name "},
+ {TOKEN_DECODING_ERROR, "Decoding Error"},
+ {TOKEN_FRESHEST_CRL_EXT, "Freshest CRL "},
+ {TOKEN_CRL_DP_EXT, "CRL Distribution Points "},
+ {TOKEN_CRLDP_NUMPOINTS, "Number of Points: "},
+ {TOKEN_CRLDP_POINTN, "Point "},
+ {TOKEN_CRLDP_DISTPOINT, "Distribution Point: "},
+ {TOKEN_CRLDP_REASONS, "Reason Flags: "},
+ {TOKEN_CRLDP_CRLISSUER, "CRL Issuer: "},
+ {TOKEN_ISSUING_DIST_POINT, "Issuing Distribution Point "},
+ {TOKEN_DIST_POINT_NAME, "Distribution Point: "},
+ {TOKEN_FULL_NAME, "Full Name: "},
+ {TOKEN_RELATIVE_NAME, "Name Relative To CRL Issuer: "},
+ {TOKEN_ONLY_USER_CERTS, "Only Contains User Certificates: "},
+ {TOKEN_ONLY_CA_CERTS, "Only Contains CA Certificates: "},
+ {TOKEN_ONLY_SOME_REASONS, "Only Some Reasons: "},
+ {TOKEN_INDIRECT_CRL, "Indirect CRL: "},
+ {TOKEN_INVALIDITY_DATE, "Invalidity Date "},
+ {TOKEN_DATE_OF_INVALIDITY, "Invalidity Date: "},
+ {TOKEN_CERTIFICATE_ISSUER, "Certificate Issuer "},
+ {TOKEN_HOLD_INSTRUCTION, "Hold Instruction Code "},
+ {TOKEN_HOLD_INSTRUCTION_CODE, "Hold Instruction Code: "},
+ {TOKEN_POLICY_CONSTRAINTS, "Policy Constraints "},
+ {TOKEN_INHIBIT_POLICY_MAPPING, "Inhibit Policy Mapping: "},
+ {TOKEN_REQUIRE_EXPLICIT_POLICY, "Require Explicit Policy: "},
+ {TOKEN_POLICY_MAPPINGS, "Policy Mappings "},
+ {TOKEN_MAPPINGS, "Mappings: "},
+ {TOKEN_MAP, "Map "},
+ {TOKEN_ISSUER_DOMAIN_POLICY, "Issuer Domain Policy: "},
+ {TOKEN_SUBJECT_DOMAIN_POLICY, "Subject Domain Policy: "},
+ {TOKEN_SUBJECT_DIR_ATTR, "Subject Directory Attributes "},
+ {TOKEN_ATTRIBUTES, "Attributes:" },
+ {TOKEN_ATTRIBUTE, "Attribute "},
+ {TOKEN_VALUES, "Values: "},
+ {TOKEN_NOT_SET, "not set"},
+ {TOKEN_NONE, "none"},
+ {TOKEN_CACHE_NOT_AVAILABLE, "CRL cache is not available. "},
+ {TOKEN_CACHE_IS_EMPTY, "CRL cache is empty. "},
+ };
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java b/pki/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java
new file mode 100644
index 000000000..1f2d16136
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java
@@ -0,0 +1,45 @@
+// --- 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.cmscore.cert;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.security.cert.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.cmscore.util.*;
+import java.security.*;
+
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Jack Pan-Chen
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class PubKeyPrettyPrint extends netscape.security.util.PubKeyPrettyPrint {
+
+ public PubKeyPrettyPrint(PublicKey key) {
+ super(key);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java b/pki/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java
new file mode 100644
index 000000000..0efc09d33
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java
@@ -0,0 +1,277 @@
+// --- 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.cmscore.cert;
+
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Subsystem for configuring X500Name related things.
+ * It is used for the following.
+ * <ul>
+ * <li>Add X500Name (string to oid) maps for attributes that
+ * are not supported by default.
+ * <li>Specify an order for encoding Directory Strings other than the default.
+ * </ul>
+ *
+ * @author lhsiao
+ * @version $Revision$
+ */
+public class X500NameSubsystem implements ISubsystem {
+
+ private IConfigStore mConfig = null;
+ public static final String ID = "X500Name";
+ private String mId = ID;
+
+ private static final String
+ PROP_DIR_STR_ENCODING_ORDER = "directoryStringEncodingOrder";
+
+ private static final String PROP_ATTR = "attr";
+ private static final String PROP_OID = "oid";
+ private static final String PROP_CLASS = "class";
+
+ private X500NameSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ // singleton enforcement
+
+ private static X500NameSubsystem mInstance = new X500NameSubsystem();
+
+ public static X500NameSubsystem getInstance() {
+ return mInstance;
+ }
+
+ /**
+ * Initializes this subsystem with the given configuration store.
+ * All paramters are optional.
+ * <ul>
+ * <li>Change encoding order of Directory Strings:
+ * <pre>
+ * X500Name.directoryStringEncodingOrder=order seperated by commas
+ * For example: Printable,BMPString,UniversalString.
+ * </pre>
+ * Possible values are:
+ * <ul>
+ * <li>Printable
+ * <li>IA5String
+ * <li>UniversalString
+ * <li>BMPString
+ * <li>UTF8String
+ * </ul>
+ * <p>
+ * <li>Add X500Name attributes:
+ * <pre>
+ * X500Name.attr.attribute-name.oid=n.n.n.n
+ * X500Name.attr.attribute-name.class=value converter class
+ * </pre>
+ *
+ * The value converter class converts a string to a ASN.1 value.
+ * It must implement netscape.security.x509.AVAValueConverter interface.
+ * Converter classes provided in CMS are:
+ * <pre>
+ * netscape.security.x509.PrintableConverter -
+ * Converts to a Printable String value. String must have only
+ * printable characters.
+ * netscape.security.x509.IA5StringConverter -
+ * Converts to a IA5String value. String must have only IA5String
+ * characters.
+ * netscape.security.x509.DirStrConverter -
+ * Converts to a Directory (v3) String. String is expected to
+ * be in Directory String format according to rfc2253.
+ * netscape.security.x509.GenericValueConverter -
+ * Converts string character by character in the following order
+ * from smaller character sets to broadest character set.
+ * Printable, IA5String, BMPString, Universal String.
+ * </pre>
+ * </ul>
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ */
+ public synchronized void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mLogger = CMS.getLogger();
+ if (Debug.ON) {
+ Debug.trace(ID + " started");
+ }
+ mConfig = config;
+
+ // get order for encoding directory strings if any.
+ setDirStrEncodingOrder();
+
+ // load x500 name maps
+ loadX500NameAttrMaps();
+ }
+
+ /**
+ * Loads X500Name String to attribute maps.
+ * Called from init.
+ */
+ private void loadX500NameAttrMaps()
+ throws EBaseException {
+ X500NameAttrMap globalMap = X500NameAttrMap.getDefault();
+ IConfigStore attrSubStore = mConfig.getSubStore(PROP_ATTR);
+ Enumeration attrNames = attrSubStore.getSubStoreNames();
+
+ while (attrNames.hasMoreElements()) {
+ String name = (String) attrNames.nextElement();
+ IConfigStore substore = attrSubStore.getSubStore(name);
+ String oidString = substore.getString(PROP_OID);
+ ObjectIdentifier oid = CertUtils.checkOID(name, oidString);
+ String className = substore.getString(PROP_CLASS);
+
+ AVAValueConverter convClass = null;
+
+ try {
+ convClass = (AVAValueConverter)
+ Class.forName(className).newInstance();
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_LOAD_CLASS_FAILED", className, e.toString()));
+ }
+ globalMap.addNameOID(name, oid, convClass);
+ if (Debug.ON) {
+ Debug.trace(ID + ": Loaded " + name + " " + oid + " " + className);
+ }
+ }
+ }
+
+ /**
+ * Set directory string encoding order.
+ * Called from init().
+ */
+ private void setDirStrEncodingOrder()
+ throws EBaseException {
+ String order = mConfig.getString(PROP_DIR_STR_ENCODING_ORDER, null);
+
+ if (order == null || order.length() == 0) // nothing.
+ return;
+ StringTokenizer toker = new StringTokenizer(order, ", \t");
+ int numTokens = toker.countTokens();
+
+ if (numTokens == 0) {
+ String msg = "must be a list of DER tag names seperated by commas.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CERT_DIR_STRING", PROP_DIR_STR_ENCODING_ORDER));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_DIR_STR_ENCODING_ORDER, msg));
+ }
+
+ byte[] tags = new byte[numTokens];
+
+ for (int i = 0; toker.hasMoreTokens(); i++) {
+ String nextTag = (String) toker.nextToken();
+
+ try {
+ tags[i] = derStr2Tag(nextTag);
+ } catch (IllegalArgumentException e) {
+ String msg = "unknown DER tag '" + nextTag + "'.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CERT_UNKNOWN_TAG", PROP_DIR_STR_ENCODING_ORDER, nextTag));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_DIR_STR_ENCODING_ORDER, msg));
+ }
+ }
+
+ DirStrConverter.setDefEncodingOrder(tags);
+ }
+
+ private static String PRINTABLESTRING = "PrintableString";
+ private static String IA5STRING = "IA5String";
+ private static String VISIBLESTRING = "VisibleString";
+ private static String T61STRING = "T61String";
+ private static String BMPSTRING = "BMPString";
+ private static String UNIVERSALSTRING = "UniversalString";
+ private static String UFT8STRING = "UTF8String";
+ private static Hashtable mDerStr2TagHash = new Hashtable();
+
+ static {
+ mDerStr2TagHash.put(
+ PRINTABLESTRING, Byte.valueOf(DerValue.tag_PrintableString));
+ mDerStr2TagHash.put(
+ IA5STRING, Byte.valueOf(DerValue.tag_IA5String));
+ mDerStr2TagHash.put(
+ VISIBLESTRING, Byte.valueOf(DerValue.tag_VisibleString));
+ mDerStr2TagHash.put(
+ T61STRING, Byte.valueOf(DerValue.tag_T61String));
+ mDerStr2TagHash.put(
+ BMPSTRING, Byte.valueOf(DerValue.tag_BMPString));
+ mDerStr2TagHash.put(
+ UNIVERSALSTRING, Byte.valueOf(DerValue.tag_UniversalString));
+ mDerStr2TagHash.put(
+ UFT8STRING, Byte.valueOf(DerValue.tag_UTF8String));
+ }
+
+ private byte derStr2Tag(String s) {
+ if (s == null || s.length() == 0)
+ throw new IllegalArgumentException();
+ Byte tag = (Byte) mDerStr2TagHash.get(s);
+
+ if (tag == null)
+ throw new IllegalArgumentException();
+ return tag.byteValue();
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Stops this system.
+ */
+ public synchronized void shutdown() {
+ }
+
+ /*
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ protected ILogger mLogger = null;
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_ADMIN, level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java
new file mode 100644
index 000000000..208fc5e7f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java
@@ -0,0 +1,315 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.cmscore.connector.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import com.netscape.certsrv.authority.*;
+import java.util.*;
+import java.io.*;
+
+
+/**
+ * Factory for getting HTTP Connections to a HTTPO server
+ */
+public class HttpConnFactory {
+ protected int mMinConns = 1;
+ protected int mMaxConns = 30;
+
+ private ILogger mLogger = CMS.getLogger();
+
+ private int mNumConns = 0; // number of available conns in array
+ private int mTotal = 0; // total num conns
+ private IHttpConnection mMasterConn = null; // master connection object.
+ private IHttpConnection mConns[];
+ private IAuthority mSource = null;
+ private IRemoteAuthority mDest = null;
+ private String mNickname = "";
+ private int mTimeout = 0;
+
+ /**
+ * default value for the above at init time.
+ */
+ private boolean mDefErrorIfDown = false;
+
+ /**
+ * Constructor for initializing from the config store.
+ * must be followed by init(IConfigStore)
+ */
+ public HttpConnFactory() {
+ }
+
+ /**
+ * Constructor for HttpConnFactory
+ * @param minConns minimum number of connections to have available
+ * @param maxConns max number of connections to have available. This is
+ * @param serverInfo server connection info - host, port, etc.
+ */
+ public HttpConnFactory(int minConns, int maxConns, IAuthority source, IRemoteAuthority dest, String nickname, int timeout
+ ) throws EBaseException {
+
+ CMS.debug("In HttpConnFactory constructor mTimeout " + timeout);
+ mSource = source;
+ mDest = dest;
+ mNickname = nickname;
+ mTimeout = timeout;
+
+ init(minConns, maxConns);
+ }
+
+ /**
+ * initialize parameters obtained from either constructor or
+ * config store
+ * @param minConns minimum number of connection handls to have available.
+ * @param maxConns maximum total number of connections to ever have.
+ * @param connInfo ldap connection info.
+ * @param authInfo ldap authentication info.
+ * @exception ELdapException if any error occurs.
+ */
+ private void init(int minConns, int maxConns
+ )
+ throws EBaseException {
+
+ CMS.debug("min conns " + minConns + " maxConns " + maxConns);
+ if (minConns <= 0 || maxConns <= 0 || minConns > maxConns) {
+ CMS.debug("bad values from CMS.cfg");
+
+ } else {
+
+ mMinConns = minConns;
+ mMaxConns = maxConns;
+ }
+
+ CMS.debug("before creating httpconn array");
+
+ mConns = new IHttpConnection[mMaxConns];
+
+ // Create connection handle and make initial connection
+
+ CMS.debug("before makeConnection");
+
+ CMS.debug(
+ "initializing HttpConnFactory with mininum " + mMinConns + " and maximum " + mMaxConns +
+ " connections to ");
+
+ // initalize minimum number of connection handles available.
+ //makeMinimum();
+
+ CMS.debug("leaving HttpConnFactory init.");
+ }
+
+ private IHttpConnection createConnection() throws EBaseException {
+
+ IHttpConnection retConn = null;
+
+ CMS.debug("In HttpConnFactory.createConnection.");
+
+ try {
+ ISocketFactory tFactory = new JssSSLSocketFactory(mNickname);
+
+ if (mTimeout == 0) {
+ retConn = CMS.getHttpConnection(mDest, tFactory);
+ } else {
+ retConn = CMS.getHttpConnection(mDest, tFactory, mTimeout);
+ }
+
+ } catch (Exception e) {
+
+ CMS.debug("can't make new Htpp Connection");
+
+ throw new EBaseException(
+ "Can't create new Http Connection");
+ }
+
+ return retConn;
+ }
+
+ /**
+ * makes the minumum number of connections
+ */
+ private void makeMinimum() throws EBaseException {
+
+ CMS.debug("In HttpConnFactory.makeMinimum.");
+ int increment;
+
+ if (mNumConns < mMinConns && mTotal <= mMaxConns) {
+
+ increment = Math.min(mMinConns - mNumConns, mMaxConns - mTotal);
+
+ if (increment == 0)
+ return;
+
+ CMS.debug(
+ "increasing minimum connections by " + increment);
+ for (int i = increment - 1; i >= 0; i--) {
+ mConns[i] = (IHttpConnection) createConnection();
+ }
+ mTotal += increment;
+ mNumConns += increment;
+ CMS.debug("new total available http connections " + mTotal);
+ CMS.debug("new number of http connections " + mNumConns);
+ }
+ }
+
+ /**
+ * gets a conenction from this factory.
+ * All connections obtained from the factory must be returned by
+ * returnConn() method.
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * IHttpConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (EBaseException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public IHttpConnection getConn()
+ throws EBaseException {
+ return getConn(true);
+ }
+
+ /**
+ * Returns a Http connection - a clone of the master connection.
+ * All connections should be returned to the factory using returnConn()
+ * to recycle connection objects.
+ * If not returned the limited max number is affected but if that
+ * number is large not much harm is done.
+ * Returns null if maximum number of connections reached.
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * IHttpConnnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (EBaseException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized IHttpConnection getConn(boolean waitForConn)
+ throws EBaseException {
+ boolean waited = false;
+
+ CMS.debug("In HttpConnFactory.getConn");
+ if (mNumConns == 0)
+ makeMinimum();
+ if (mNumConns == 0) {
+ if (!waitForConn)
+ return null;
+ try {
+ CMS.debug("getConn: out of http connections");
+ log(ILogger.LL_WARN,
+ "Ran out of http connections available "
+ );
+ waited = true;
+ CMS.debug("HttpConn:about to wait for a new http connection");
+ while (mNumConns == 0)
+ wait();
+
+ CMS.debug("HttpConn:done waiting for new http connection");
+ } catch (InterruptedException e) {
+ }
+ }
+ mNumConns--;
+ IHttpConnection conn = mConns[mNumConns];
+
+ mConns[mNumConns] = null;
+
+ if (waited) {
+ CMS.debug("HttpConn:had to wait for an available connection from pool");
+ log(ILogger.LL_WARN,
+ "Http connections are available again in http connection pool "
+ );
+ }
+ CMS.debug("HttpgetConn: mNumConns now " + mNumConns);
+
+ return conn;
+ }
+
+ /**
+ * Teturn connection to the factory.
+ * This is mandatory after a getConn().
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * IHttpConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (EBaseException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized void returnConn(IHttpConnection conn) {
+
+ CMS.debug("In HttpConnFactory.returnConn");
+ if (conn == null) {
+ return;
+ }
+ IHttpConnection boundconn = (IHttpConnection) conn;
+
+ for (int i = 0; i < mNumConns; i++) {
+ if (mConns[i] == conn) {
+ CMS.debug(
+ "returnConn: previously returned connection. " + conn);
+
+ }
+ }
+ mConns[mNumConns++] = boundconn;
+ CMS.debug("HttpreturnConn: mNumConns now " + mNumConns);
+ notify();
+ }
+
+ /**
+ * handy routine for logging in this class.
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "In Http (bound) connection pool to" +
+ msg);
+ }
+
+ protected void finalize()
+ throws Exception {
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/HttpConnection.java b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnection.java
new file mode 100644
index 000000000..7db508fb6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnection.java
@@ -0,0 +1,238 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.certsrv.apps.*;
+import java.io.*;
+import java.util.*;
+
+
+public class HttpConnection implements IHttpConnection {
+ protected IRemoteAuthority mDest = null;
+ protected HttpRequest mHttpreq = new HttpRequest();
+ protected IRequestEncoder mReqEncoder = null;
+ protected HttpClient mHttpClient = null;
+
+ protected boolean Connect(String host, HttpClient client)
+ {
+ StringTokenizer st = new StringTokenizer(host, " ");
+ while (st.hasMoreTokens()) {
+ String hp = st.nextToken(); // host:port
+ StringTokenizer st1 = new StringTokenizer(hp, ":");
+ try {
+ String h = st1.nextToken();
+ int p = Integer.parseInt(st1.nextToken());
+ client.connect(h, p);
+ return true;
+ } catch (Exception e) {
+ // may want to log the failure
+ }
+ try {
+ Thread.sleep(5000); // 5 seconds
+ } catch (Exception e) {
+ }
+
+ }
+ return false;
+ }
+
+ public HttpConnection(IRemoteAuthority dest, ISocketFactory factory) {
+ mDest = dest;
+ mReqEncoder = new HttpRequestEncoder();
+ mHttpClient = new HttpClient(factory);
+ if (Debug.ON)
+ Debug.trace("Created HttpClient");
+ try {
+ mHttpreq.setMethod("POST");
+ mHttpreq.setURI(mDest.getURI());
+ mHttpreq.setHeader("Connection", "Keep-Alive");
+ CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort());
+ String host = dest.getHost();
+ // we could have a list of host names in the host parameters
+ // the format is, for example,
+ // "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
+ if (host != null && host.indexOf(' ') != -1) {
+ // try to do client-side failover
+ boolean connected = false;
+ do {
+ connected = Connect(host, mHttpClient);
+ } while (!connected);
+ } else {
+ mHttpClient.connect(host, dest.getPort());
+ }
+ CMS.debug("HttpConnection: connected to " + dest.getHost() + ":" + dest.getPort());
+ } catch (IOException e) {
+ // server's probably down. that's fine. try later.
+ //System.out.println(
+ //"Can't connect to server in connection creation");
+ }
+ }
+
+ // Inserted by beomsuk
+ public HttpConnection(IRemoteAuthority dest, ISocketFactory factory, int timeout) {
+ mDest = dest;
+ mReqEncoder = new HttpRequestEncoder();
+ mHttpClient = new HttpClient(factory);
+ CMS.debug("HttpConn:Created HttpConnection: factory " + factory + "client " + mHttpClient);
+ try {
+ mHttpreq.setMethod("POST");
+ mHttpreq.setURI(mDest.getURI());
+ mHttpreq.setHeader("Connection", "Keep-Alive");
+ CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort() + " timeout:" + timeout);
+ mHttpClient.connect(dest.getHost(), dest.getPort(), timeout);
+ CMS.debug("HttpConnection: connected to " + dest.getHost() + ":" + dest.getPort() + " timeout:" + timeout);
+ } catch (IOException e) {
+ // server's probably down. that's fine. try later.
+ //System.out.println(
+ //"Can't connect to server in connection creation");
+ CMS.debug("CMSConn:IOException in creating HttpConnection " + e.toString());
+ }
+ }
+
+ // Insert end
+ /**
+ * sends a request to remote RA/CA, returning the result.
+ * @throws EBaseException if request could not be encoded
+ */
+ public IPKIMessage send(IPKIMessage tomsg)
+ throws EBaseException {
+ IPKIMessage replymsg = null;
+
+ CMS.debug("in HttpConnection.send " + this);
+ if (Debug.ON)
+ Debug.trace("encoding request ");
+ String content = null;
+
+ try {
+ content = mReqEncoder.encode(tomsg);
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "Could not encode request"));
+ }
+ if (Debug.ON) {
+ Debug.trace("encoded request");
+ Debug.trace("------ " + content.length() + "-----");
+ Debug.trace(content);
+ Debug.trace("--------------------------");
+ }
+ boolean reconnect = false;
+
+ mHttpreq.setHeader("Content-Length",
+ Integer.toString(content.length()));
+ if (Debug.ON)
+ Debug.trace("request encoded length " + content.length());
+ mHttpreq.setContent(content);
+
+ HttpResponse p = null;
+
+ try {
+ if (!mHttpClient.connected()) {
+ mHttpClient.connect(mDest.getHost(), mDest.getPort());
+ CMS.debug("HttpConn:reconnected to " + mDest.getHost() + ":" + mDest.getPort());
+ reconnect = true;
+ }
+ } catch (IOException e) {
+ if (e.getMessage().indexOf("Peer's certificate issuer has been marked as not trusted") != -1) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "(This local authority cannot connect to the remote authority. The local authority's signing certificate must chain to a CA certificate trusted for client authentication in the certificate database. Use the certificate manager, or command line tool such as certutil to verify that the trust permissions of the local authority's issuer cert have 'CT' setting in the SSL client auth field.)"));
+ }
+ CMS.debug("HttpConn:Couldn't reconnect " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "Couldn't reconnect " + e));
+ }
+
+ // if remote closed connection want to reconnect and resend.
+ while (p == null) {
+ try {
+ if (Debug.ON)
+ Debug.trace("sending request");
+ p = mHttpClient.send(mHttpreq);
+ } catch (IOException e) {
+ CMS.debug("HttpConn: mHttpClient.send failed " + e.toString());
+ if (reconnect) {
+ CMS.debug("HttpConn:resend failed again. " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "resend failed again. " + e));
+ }
+ try {
+ CMS.debug("HttpConn: trying a reconnect ");
+ mHttpClient.connect(mDest.getHost(), mDest.getPort());
+ } catch (IOException ex) {
+ CMS.debug("reconnect for resend failed. " + ex);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "reconnect for resend failed." + ex));
+ }
+ reconnect = true;
+ }
+ }
+
+ // got reply; check status
+ String statusStr = p.getStatusCode();
+
+ CMS.debug("HttpConn:server returned status " + statusStr);
+ int statuscode = -1;
+
+ try {
+ statuscode = Integer.parseInt(statusStr);
+ } catch (NumberFormatException e) {
+ statuscode = -1;
+ }
+
+ /* HttpServletResponse.SC_OK = 200 */
+ if (statuscode != 200) {
+
+ /* HttpServletResponse.SC_UNAUTHORIZED = 401 */
+ if (statuscode == 401) {
+ // XXX what to do here.
+ String msg = "request no good " + statuscode + " " + p.getReasonPhrase();
+
+ if (Debug.ON)
+ Debug.trace(msg);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_AUTHENTICATE_FAILED", msg));
+ } else {
+ // XXX what to do here.
+ String msg = "HttpConn:request no good " + statuscode + " " + p.getReasonPhrase();
+
+ CMS.debug(msg);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", msg));
+ }
+ }
+
+ // decode reply.
+ // if reply is bad, error is thrown and request will be resent
+ String pcontent = p.getContent();
+
+ if (Debug.ON) {
+ Debug.trace("Server returned\n");
+ Debug.trace("-------");
+ Debug.trace(pcontent);
+ Debug.trace("-------");
+ }
+
+ try {
+ replymsg = (IPKIMessage) mReqEncoder.decode(pcontent);
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "Could not decode content"));
+ }
+ CMS.debug("HttpConn:decoded reply");
+ return replymsg;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/HttpConnector.java b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnector.java
new file mode 100644
index 000000000..4ce3ed848
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/HttpConnector.java
@@ -0,0 +1,198 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmsutil.http.*;
+import com.netscape.cmsutil.net.*;
+import java.util.*;
+
+
+public class HttpConnector implements IConnector {
+ protected IAuthority mSource = null;
+ protected IRemoteAuthority mDest = null;
+ protected ISocketFactory mFactory = null;
+
+ // XXX todo make this a pool.
+ // XXX use CMMF in the future.
+ protected IHttpConnection mConn = null;
+ private Thread mResendThread = null;
+ private IResender mResender = null;
+ private int mTimeout;
+
+ private HttpConnFactory mConnFactory = null;
+ public HttpConnector(IAuthority source, String nickName,
+ IRemoteAuthority dest, int resendInterval, IConfigStore config) throws EBaseException {
+
+ mTimeout = 0;
+ mSource = source;
+ mDest = dest;
+ mFactory = new JssSSLSocketFactory(nickName);
+
+ int minConns = config.getInteger("minHttpConns", 1);
+ int maxConns = config.getInteger("maxHttpConns", 15);
+
+ CMS.debug("HttpConn: min " + minConns);
+ CMS.debug("HttpConn: max " + maxConns);
+
+ try {
+ mConnFactory = new HttpConnFactory(minConns, maxConns, source, dest, nickName, 0);
+ } catch (EBaseException e) {
+ CMS.debug("can't create new HttpConnFactory " + e.toString());
+ }
+
+ // mConn = CMS.getHttpConnection(dest, mFactory);
+ // this will start resending past requests in parallel.
+ mResender = CMS.getResender(mSource, nickName, dest, resendInterval);
+ mResendThread = new Thread(mResender, "HttpConnector");
+ }
+
+ // Inserted by beomsuk
+ public HttpConnector(IAuthority source, String nickName,
+ IRemoteAuthority dest, int resendInterval, IConfigStore config, int timeout) throws EBaseException {
+ mSource = source;
+ mDest = dest;
+ mTimeout = timeout;
+ mFactory = new JssSSLSocketFactory(nickName);
+
+ int minConns = config.getInteger("minHttpConns", 1);
+ int maxConns = config.getInteger("maxHttpConns", 15);
+
+ CMS.debug("HttpConn: min " + minConns);
+ CMS.debug("HttpConn: max " + maxConns);
+
+ try {
+ mConnFactory = new HttpConnFactory(minConns, maxConns, source, dest, nickName, timeout);
+ } catch (EBaseException e) {
+ CMS.debug("can't create new HttpConnFactory");
+ }
+
+ // this will start resending past requests in parallel.
+ mResender = CMS.getResender(mSource, nickName, dest, resendInterval);
+ mResendThread = new Thread(mResender, "HttpConnector");
+ }
+
+ // Insert end
+
+ public boolean send(IRequest r)
+ throws EBaseException {
+ IHttpConnection curConn = null;
+
+ try {
+ IHttpPKIMessage tomsg = (IHttpPKIMessage) CMS.getHttpPKIMessage();
+ HttpPKIMessage replymsg = null;
+
+ tomsg.fromRequest(r);
+ CMS.debug("Before synch");
+
+ curConn = mConnFactory.getConn();
+
+ CMS.debug("HttpConnector.send " + curConn);
+
+ replymsg = (HttpPKIMessage) curConn.send(tomsg);
+
+ if (replymsg == null) {
+ CMS.debug("HttpConncter. replymsg is null");
+ return false;
+ }
+
+ CMS.debug("HttpConncter.send has been called");
+
+ RequestStatus replyStatus;
+ RequestId replyRequestId;
+
+ replyStatus = RequestStatus.fromString(replymsg.reqStatus);
+ int index = replymsg.reqId.lastIndexOf(':');
+
+ replyRequestId = new RequestId(replymsg.reqId.substring(index + 1));
+ CMS.debug("reply request id " + replyRequestId);
+ r.setExtData(IRequest.REMOTE_REQID, replyRequestId.toString());
+
+ CMS.debug("reply request type " + r.getRequestType());
+ CMS.debug("reply status " + replyStatus);
+
+ // non terminal states.
+ // XXX hack: don't resend get revocation info requests since
+ // resent results are ignored.
+ if ((!r.getRequestType().equals(
+ IRequest.GETREVOCATIONINFO_REQUEST)) &&
+ (replyStatus == RequestStatus.BEGIN ||
+ replyStatus == RequestStatus.PENDING ||
+ replyStatus == RequestStatus.SVC_PENDING ||
+ replyStatus == RequestStatus.APPROVED)) {
+ CMS.debug("HttpConn: remote request id still pending " +
+ r.getRequestId() + " state " + replyStatus);
+ mSource.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CONNECTOR_REQUEST_NOT_COMPLETED", r.getRequestId().toString()));
+ mResender.addRequest(r);
+ return false;
+ }
+
+ // request was completed.
+ replymsg.toRequest(r); // this only copies contents.
+
+ // terminal states other than completed
+ if (replyStatus == RequestStatus.REJECTED ||
+ replyStatus == RequestStatus.CANCELED) {
+ CMS.debug(
+ "remote request id " + r.getRequestId() +
+ " was rejected or cancelled.");
+ r.setExtData(IRequest.REMOTE_STATUS, replyStatus.toString());
+ r.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ r.setExtData(IRequest.ERROR,
+ new EBaseException(CMS.getUserMessage("CMS_BASE_REMOTE_AUTHORITY_ERROR")));
+ // XXX overload svcerrors for now.
+ Vector policyErrors = r.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (policyErrors != null && policyErrors.size() > 0) {
+ r.setExtData(IRequest.SVCERRORS, policyErrors);
+ }
+ }
+
+ CMS.debug(
+ "remote request id " + r.getRequestId() + " was completed");
+ return true;
+ } catch (EBaseException e) {
+ CMS.debug("HttpConn: inside EBaseException " + e.toString());
+
+ if (!r.getRequestType().equals(IRequest.GETREVOCATIONINFO_REQUEST))
+ mResender.addRequest(r);
+
+ CMS.debug("HttpConn: error sending request to cert " + e.toString());
+ mSource.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CONNECTOR_SEND_REQUEST", r.getRequestId().toString(), mDest.getHost(), Integer.toString(mDest.getPort())));
+ // mSource.log(ILogger.LL_INFO,
+ // "Queing " + r.getRequestId() + " for resend.");
+ return false;
+ } finally {
+
+ if (curConn != null) {
+ mConnFactory.returnConn(curConn);
+ }
+ }
+ }
+
+ public void start() {
+ mResendThread.start();
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java b/pki/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java
new file mode 100644
index 000000000..b9e32cbd9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java
@@ -0,0 +1,221 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.Debug;
+import java.util.*;
+import java.io.*;
+
+
+/**
+ * simple name/value pair message.
+ */
+public class HttpPKIMessage implements IHttpPKIMessage {
+ // initialized to "" because nulls don't serialize well.
+ public String reqType = "";
+ public String reqId = "";
+ protected String reqStatus = "";
+ protected Vector mNameVals = new Vector(); // sequence of name/vals.
+
+ public HttpPKIMessage() {
+ }
+
+ public String getReqStatus() {
+ return reqStatus;
+ }
+
+ public String getReqType() {
+ return reqType;
+ }
+
+ public String getReqId() {
+ return reqId;
+ }
+
+ /**
+ * copy contents of request to make a simple name/value message.
+ */
+ public void fromRequest(IRequest r) {
+ // actually don't need to copy source id since
+ reqType = r.getRequestType();
+ reqId = r.getRequestId().toString();
+ reqStatus = r.getRequestStatus().toString();
+
+ CMS.debug("HttpPKIMessage.fromRequest: requestId=" + r.getRequestId().toString() + " requestStatus=" + reqStatus + " instance=" + r);
+
+ String attrs[] = RequestTransfer.getTransferAttributes(r);
+ int len = attrs.length;
+ String[] names = attrs;
+ Object value = null;
+
+ for (int i = 0; i < len; i++) {
+ String key = names[i];
+ if (r.isSimpleExtDataValue(key)) {
+ value = r.getExtDataInString(key);
+ } else {
+ value = r.getExtDataInHashtable(key);
+ }
+ if (value != null) {
+ mNameVals.addElement(key);
+ mNameVals.addElement(value);
+ }
+ }
+ }
+
+ /**
+ * copy contents to request.
+ */
+ public void toRequest(IRequest r) {
+ // id, type and status
+ // type had to have been set in instantiation.
+ // id is checked but not reset.
+ // request status cannot be set, but can be looked at.
+ reqStatus = r.getRequestStatus().toString();
+ CMS.debug("HttpPKMessage.toRequest: requestStatus=" + reqStatus);
+
+ int len = RequestTransfer.getTransferAttributes(r).length;
+ String key;
+ Object value;
+ Enumeration enum1 = mNameVals.elements();
+
+ while (enum1.hasMoreElements()) {
+ key = (String) enum1.nextElement();
+ try {
+ value = enum1.nextElement();
+ if (value instanceof String) {
+ r.setExtData(key, (String) value);
+ } else if (value instanceof Hashtable) {
+ r.setExtData(key, (Hashtable) value);
+ } else {
+ CMS.debug("HttpPKIMessage.toRequest(): key: " + key +
+ " has unexpected type " + value.getClass().toString());
+ }
+ } catch (NoSuchElementException e) {
+ CMS.debug("Incorrect pairing of name/value for " + key);
+ }
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws IOException {
+ CMS.debug("writeObject");
+ out.writeObject(reqType);
+ if (Debug.ON)
+ Debug.trace("read object req type " + reqType);
+ out.writeObject(reqId);
+ if (Debug.ON)
+ Debug.trace("read object req id " + reqId);
+ out.writeObject(reqStatus);
+ if (Debug.ON)
+ Debug.trace("read object req source status " + reqStatus);
+ Enumeration enum1 = mNameVals.elements();
+
+ while (enum1.hasMoreElements()) {
+ Object key = null;
+ Object val = null;
+ key = enum1.nextElement();
+ try {
+ val = enum1.nextElement();
+ // test if key and value are serializable
+ ObjectOutputStream os =
+ new ObjectOutputStream(new ByteArrayOutputStream());
+ os.writeObject(key);
+ os.writeObject(val);
+
+ // ok, if we dont have problem serializing the objects,
+ // then write the objects into the real object stream
+ out.writeObject(key);
+ out.writeObject(val);
+ } catch (Exception e) {
+ // skip not serialiable attribute in DRM
+ // DRM does not need to store the enrollment request anymore
+ CMS.debug("HttpPKIMessage:skipped key=" +
+ key.getClass().getName());
+ if (val == null) {
+ CMS.debug("HttpPKIMessage:skipped val= null");
+ } else {
+ CMS.debug("HttpPKIMessage:skipped val=" +
+ val.getClass().getName());
+ }
+ }
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException, OptionalDataException {
+ reqType = (String) in.readObject();
+ reqId = (String) in.readObject();
+ reqStatus = (String) in.readObject();
+ mNameVals = new Vector();
+ Object keyorval = null;
+
+ try {
+ boolean iskey = true;
+
+ while (true) {
+ boolean skipped = false;
+ try {
+ keyorval = in.readObject();
+ } catch (OptionalDataException e) {
+ throw e;
+ } catch (IOException e) {
+ // just skipped parameter
+ CMS.debug("skipped attribute in request e="+e);
+ if (!iskey) {
+ int s = mNameVals.size();
+ if (s > 0) {
+ // remove previous key if this is value
+ mNameVals.removeElementAt(s - 1);
+ skipped = true;
+ keyorval = "";
+ }
+ }
+ }
+ if (iskey) {
+ if (Debug.ON)
+ Debug.trace("read key " + keyorval);
+ iskey = false;
+ } else {
+ if (Debug.ON)
+ Debug.trace("read val " + keyorval);
+ iskey = true;
+ }
+ if (Debug.ON)
+ Debug.trace("read " + keyorval);
+ if (!skipped) {
+ if (keyorval == null)
+ break;
+ mNameVals.addElement(keyorval);
+ }
+ }
+ } catch (OptionalDataException e) {
+ if (e.eof == true) {
+ if (Debug.ON)
+ Debug.trace("end of stream");
+ } else {
+ if (Debug.ON)
+ Debug.trace(" " + e.length);
+ throw e;
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java b/pki/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java
new file mode 100644
index 000000000..50b09fd2a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java
@@ -0,0 +1,73 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.cmscore.util.Debug;
+
+import java.io.*;
+
+
+/**
+ * encodes a request by serializing it.
+ */
+public class HttpRequestEncoder implements IRequestEncoder {
+ public String encode(Object r)
+ throws IOException {
+ String s = null;
+ byte[] serial;
+ ByteArrayOutputStream ba = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(ba);
+
+ os.writeObject(r);
+ serial = ba.toByteArray();
+ s = com.netscape.osutil.OSUtil.BtoA(serial);
+ return s;
+ }
+
+ public Object decode(String s)
+ throws IOException {
+ Object result = null;
+ byte[] serial = null;
+
+ try {
+
+ serial = com.netscape.osutil.OSUtil.AtoB(s);
+ ByteArrayInputStream ba = new ByteArrayInputStream(serial);
+ ObjectInputStream is = new ObjectInputStream(ba);
+
+ result = is.readObject();
+ } catch (ClassNotFoundException e) {
+ // XXX hack: change this
+ if (Debug.ON)
+ Debug.trace("class not found ex " + e + e.getMessage());
+ throw new IOException("Class Not Found " + e.getMessage());
+ } catch (OptionalDataException e) {
+ if (e.eof == true) {
+ if (Debug.ON)
+ Debug.trace("done reading input stream " + result);
+ } else {
+ if (Debug.ON)
+ Debug.trace(e.length + " more bytes of primitive data");
+ }
+ }
+ return result;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/LocalConnector.java b/pki/base/common/src/com/netscape/cmscore/connector/LocalConnector.java
new file mode 100644
index 000000000..efc97c435
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/LocalConnector.java
@@ -0,0 +1,203 @@
+// --- 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.cmscore.connector;
+
+
+import java.util.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+public class LocalConnector implements IConnector {
+ ILogger mLogger = CMS.getLogger();
+ ICertAuthority mSource = null;
+ IAuthority mDest = null;
+ Hashtable mSourceReqs = new Hashtable();
+
+ public LocalConnector(ICertAuthority source, IAuthority dest) {
+ mSource = source;
+ // mSource.log(ILogger.LL_DEBUG, "Local connector setup for source " +
+ // mSource.getId());
+ mDest = dest;
+ CMS.debug("Local connector setup for dest " +
+ mDest.getId());
+ // register for events.
+ mDest.registerRequestListener(new LocalConnListener());
+ CMS.debug("Connector inited");
+ }
+
+ /**
+ * send request to local authority.
+ * returns resulting request
+ */
+ public boolean send(IRequest r) throws EBaseException {
+ if (Debug.ON) {
+ Debug.print("send request type " + r.getRequestType() + " status=" + r.getRequestStatus() + " to " + mDest.getId() + " id=" + r.getRequestId() + "\n");
+ }
+ CMS.debug("send request type " + r.getRequestType() +
+ " to " + mDest.getId());
+
+ IRequestQueue destQ = mDest.getRequestQueue();
+ IRequest destreq = destQ.newRequest(r.getRequestType());
+
+ CMS.debug("local connector dest req " +
+ destreq.getRequestId() + " created for source rId " + r.getRequestId());
+ // mSource.log(ILogger.LL_DEBUG,
+ // "setting connector dest " + mDest.getId() +
+ // " source id to " + r.getRequestId());
+
+ // XXX set context to the real identity later.
+ destreq.setSourceId(
+ mSource.getX500Name().toString() + ":" + r.getRequestId().toString());
+ //destreq.copyContents(r); // copy meta attributes in request.
+ transferRequest(r, destreq);
+ // XXX requestor type is not transferred on return.
+ destreq.setExtData(IRequest.REQUESTOR_TYPE,
+ IRequest.REQUESTOR_RA);
+ CMS.debug("connector dest " + mDest.getId() +
+ " processing " + destreq.getRequestId());
+
+ // set context before calling process request so
+ // that request subsystem can record the creator
+ // of the request
+ SessionContext s = SessionContext.getContext();
+
+ if (s.get(SessionContext.USER_ID) == null) {
+ // use $local$ to represent it is not a user who
+ // submit the request, but it is a local subsystem
+ s.put(SessionContext.USER_ID, "$local$" + mSource.getId());
+ }
+
+ // Locally cache the source request so that we
+ // can update it when the dest request is
+ // processed (when LocalConnListener is being called).
+ mSourceReqs.put(r.getRequestId().toString(), r);
+ try {
+ destQ.processRequest(destreq);
+ } catch (EBaseException ex) {
+ throw ex;
+ } finally {
+ // release the source id either success or failure
+ mSourceReqs.remove(r.getRequestId().toString());
+ }
+
+ CMS.debug("connector dest " + mDest.getId() +
+ " processed " + destreq.getRequestId() +
+ " status " + destreq.getRequestStatus());
+
+ if (destreq.getRequestStatus() == RequestStatus.COMPLETE) {
+ // no need to transfer contents if request wasn't complete.
+ transferRequest(destreq, r);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public class LocalConnListener implements IRequestListener {
+
+ public void init(ISubsystem sys, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public void set(String name, String val) {
+ }
+
+ public void accept(IRequest destreq) {
+ if (Debug.ON) {
+ Debug.print("dest " + mDest.getId() + " done with " + destreq.getRequestId());
+ }
+ CMS.debug(
+ "dest " + mDest.getId() + " done with " + destreq.getRequestId());
+
+ IRequestQueue sourceQ = mSource.getRequestQueue();
+ // accept requests that only belong to us.
+ // XXX review death scenarios here. - If system dies anywhere
+ // here need to check all requests at next server startup.
+ String sourceNameAndId = destreq.getSourceId();
+ String sourceName = mSource.getX500Name().toString();
+
+ if (sourceNameAndId == null ||
+ !sourceNameAndId.toString().regionMatches(0,
+ sourceName, 0, sourceName.length())) {
+ CMS.debug("request " + destreq.getRequestId() +
+ " from " + sourceNameAndId + " not ours.");
+ return;
+ }
+ int index = sourceNameAndId.lastIndexOf(':');
+
+ if (index == -1) {
+ mSource.log(ILogger.LL_FAILURE,
+ "request " + destreq.getRequestId() +
+ " for " + sourceNameAndId + " malformed.");
+ return;
+ }
+ String sourceId = sourceNameAndId.substring(index + 1);
+ RequestId rId = new RequestId(sourceId);
+
+ // mSource.log(ILogger.LL_DEBUG, mDest.getId() + " " +
+ // destreq.getRequestId() + " mapped to " + mSource.getId() + " " + rId);
+
+ IRequest r = null;
+
+ // 391439: Previously, we try to access the request
+ // via request queue here. Due to the recent
+ // performance enhancement, approved request will
+ // not be immediately available in the database. So
+ // retrieving the request from the queue within
+ // the serviceRequest() function will have
+ // diffculities.
+ // You may wonder what happen if the system crashes
+ // during the request servicing. Yes, the request
+ // will be lost. This is ok because the users will
+ // resubmit their requests again.
+ // Note that the pending requests, on the other hand,
+ // are persistent before the servicing.
+ // Please see stateEngine() function in
+ // ARequestQueue.java for details.
+ r = (IRequest) mSourceReqs.get(rId);
+ if (r != null) {
+ if (r.getRequestStatus() != RequestStatus.SVC_PENDING) {
+ mSource.log(ILogger.LL_FAILURE,
+ "request state of " + rId + "not pending " +
+ " from dest authority " + mDest.getId());
+ sourceQ.releaseRequest(r);
+ return;
+ }
+ transferRequest(destreq, r);
+ sourceQ.markAsServiced(r);
+ sourceQ.releaseRequest(r);
+
+ CMS.debug("released request " + r.getRequestId());
+ }
+ }
+ }
+
+ public void start() {
+ }
+
+ protected void transferRequest(IRequest src, IRequest dest) {
+ RequestTransfer.transfer(src, dest);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java b/pki/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java
new file mode 100644
index 000000000..6a9703b69
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java
@@ -0,0 +1,70 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.connector.*;
+
+
+public class RemoteAuthority implements IRemoteAuthority {
+ String mHost = null;
+ int mPort = -1;
+ String mURI = null;
+ int mTimeout = 0;
+
+ /**
+ * host parameter can be:
+ * "directory.knowledge.com"
+ * "199.254.1.2"
+ * "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
+ */
+ public RemoteAuthority(String host, int port, String uri, int timeout) {
+ mHost = host;
+ mPort = port;
+ mURI = uri;
+ mTimeout = timeout;
+ }
+
+ public RemoteAuthority() {
+ }
+
+ public void init(IConfigStore c)
+ throws EBaseException {
+ mHost = c.getString("host");
+ mPort = c.getInteger("port");
+ mURI = c.getString("uri");
+ mTimeout = c.getInteger("timeout");
+ }
+
+ public String getHost() {
+ return mHost;
+ }
+
+ public int getPort() {
+ return mPort;
+ }
+
+ public String getURI() {
+ return mURI;
+ }
+
+ public int getTimeout() {
+ return mTimeout;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java b/pki/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java
new file mode 100644
index 000000000..825f4d564
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java
@@ -0,0 +1,124 @@
+// --- 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.cmscore.connector;
+
+
+import java.util.*;
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cmscore.authentication.ChallengePhraseAuthentication;
+
+
+public class RequestTransfer {
+
+ private static final String DOT = ".";
+
+ private static String[] transferAttributes = {
+ IRequest.HTTP_PARAMS,
+ IRequest.AGENT_PARAMS,
+ IRequest.CERT_INFO,
+ IRequest.ISSUED_CERTS,
+ IRequest.OLD_CERTS,
+ IRequest.OLD_SERIALS,
+ IRequest.REVOKED_CERTS,
+ IRequest.CACERTCHAIN,
+ IRequest.CRL,
+ IRequest.ERRORS,
+ IRequest.RESULT,
+ IRequest.ERROR,
+ IRequest.SVCERRORS,
+ IRequest.REMOTE_STATUS,
+ IRequest.REMOTE_REQID,
+ IRequest.REVOKED_CERT_RECORDS,
+ IRequest.CERT_STATUS,
+ ChallengePhraseAuthentication.CHALLENGE_PHRASE,
+ ChallengePhraseAuthentication.SUBJECTNAME,
+ ChallengePhraseAuthentication.SERIALNUMBER,
+ ChallengePhraseAuthentication.SERIALNOARRAY,
+ IRequest.ISSUERDN,
+ IRequest.CERT_FILTER,
+ "keyRecord",
+ "uid", // UidPwdDirAuthentication.CRED_UID,
+ "udn", // UdnPwdDirAuthentication.CRED_UDN,
+ };
+
+ public static boolean isProfileRequest(IRequest request) {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals(""))
+ return false;
+ else
+ return true;
+ }
+
+ public static String[] getTransferAttributes(IRequest r) {
+ if (isProfileRequest(r)) {
+ // copy everything in the request
+ CMS.debug("RequestTransfer: profile request " +
+ r.getRequestId().toString());
+ Enumeration e = r.getExtDataKeys();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ String k = (String) e.nextElement();
+
+ if (k.equals("requestType"))
+ continue;
+ if (k.equals("requestId"))
+ continue;
+ if (k.equals("requestVersion"))
+ continue;
+ if (k.equals("AUTH_TOKEN"))
+ continue;
+ CMS.debug("RequestTransfer: attribute=" + k);
+ if (k.equals("requestStatus")) {
+ CMS.debug("RequestTransfer : requestStatus=" +
+ r.getExtDataInString("requestStatus"));
+ }
+ v.addElement(k);
+ }
+ CMS.debug("RequestTransfer: attribute size=" + v.size());
+ if (v.size() == 0)
+ return null;
+ String attrs[] = new String[v.size()];
+
+ v.copyInto(attrs);
+ return attrs;
+ } else {
+ return transferAttributes;
+ }
+ }
+
+ public static void transfer(IRequest src, IRequest dest) {
+ CMS.debug("Transfer srcId=" +
+ src.getRequestId().toString() +
+ " destId=" + dest.getRequestId().toString());
+ String attrs[] = getTransferAttributes(src);
+
+ for (int i = 0; i < attrs.length; i++) {
+ String key = attrs[i];
+ if (src.isSimpleExtDataValue(key)) {
+ dest.setExtData(key, src.getExtDataInString(key));
+ } else {
+ dest.setExtData(key, src.getExtDataInHashtable(key));
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/connector/Resender.java b/pki/base/common/src/com/netscape/cmscore/connector/Resender.java
new file mode 100644
index 000000000..78fddaf5c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/connector/Resender.java
@@ -0,0 +1,249 @@
+// --- 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.cmscore.connector;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.http.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.*;
+
+
+/**
+ * Resend requests at intervals to the server to check if it's been completed.
+ * Default interval is 5 minutes.
+ */
+public class Resender implements IResender {
+ public static final int SECOND = 1000; //milliseconds
+ public static final int MINUTE = 60 * SECOND;
+ public static final int HOUR = 60 * MINUTE;
+ public static final int DAY = 24 * HOUR;
+
+ protected IAuthority mAuthority = null;
+ IRequestQueue mQueue = null;
+ protected IRemoteAuthority mDest = null;
+
+ /* Vector of Request Id *Strings* */
+ protected Vector mRequestIds = new Vector();
+
+ protected HttpConnection mConn = null;
+
+ protected String mNickName = null;
+
+ // default interval.
+ // XXX todo add another interval for requests unsent because server
+ // was down (versus being serviced in request queue)
+ protected int mInterval = 1 * MINUTE;
+
+ public Resender(IAuthority authority, String nickName, IRemoteAuthority dest) {
+ mAuthority = authority;
+ mQueue = mAuthority.getRequestQueue();
+ mDest = dest;
+ mNickName = nickName;
+
+ //mConn = new HttpConnection(dest,
+ // new JssSSLSocketFactory(nickName));
+ }
+
+ public Resender(
+ IAuthority authority, String nickName,
+ IRemoteAuthority dest, int interval) {
+ mAuthority = authority;
+ mQueue = mAuthority.getRequestQueue();
+ mDest = dest;
+ if (interval > 0)
+ mInterval = interval * SECOND; // interval specified in seconds.
+
+ //mConn = new HttpConnection(dest,
+ // new JssSSLSocketFactory(nickName));
+ }
+
+ // must be done after a subsystem 'start' so queue is initialized.
+ private void initRequests() {
+ mQueue = mAuthority.getRequestQueue();
+ // get all requests in mAuthority that are still pending.
+ IRequestList list =
+ mQueue.listRequestsByStatus(RequestStatus.SVC_PENDING);
+
+ while (list != null && list.hasMoreElements()) {
+ RequestId rid = list.nextRequestId();
+
+ CMS.debug(
+ "added request Id " + rid + " in init to resend queue.");
+ // note these are added as strings
+ mRequestIds.addElement(rid.toString());
+ }
+ }
+
+ public void addRequest(IRequest r) {
+ synchronized (mRequestIds) {
+ // note the request ids are added as strings.
+ mRequestIds.addElement(r.getRequestId().toString());
+ }
+ CMS.debug(
+ "added " + r.getRequestId() + " to resend queue");
+ }
+
+ public void run() {
+
+ CMS.debug("Resender: In resender Thread run:");
+ mConn = new HttpConnection(mDest,
+ new JssSSLSocketFactory(mNickName));
+ initRequests();
+
+ do {
+ resend();
+ try {
+ Thread.sleep(mInterval);
+ } catch (InterruptedException e) {
+ mAuthority.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CONNECTOR_RESENDER_INTERRUPTED"));
+ continue;
+ }
+ }
+ while (true);
+ }
+
+ private void resend() {
+ // clone a seperate list so mRequestIds can be modified
+ Vector rids = (Vector) mRequestIds.clone();
+ Vector completedRids = new Vector();
+
+ // resend each request to CA to ping for status.
+ Enumeration enum1 = rids.elements();
+
+ while (enum1.hasMoreElements()) {
+ // request ids are added as strings.
+ String ridString = (String) enum1.nextElement();
+ RequestId rid = new RequestId(ridString);
+ IRequest r = null;
+
+ CMS.debug(
+ "resend processing request id " + rid);
+
+ try {
+ r = mQueue.findRequest(rid);
+ } catch (EBaseException e) {
+ // XXX bad case. should we remove the rid now ?
+ mAuthority.log(ILogger.LL_WARN, CMS.getLogMessage("CMSCORE_CONNECTOR_REQUEST_NOT_FOUND", rid.toString()));
+ continue;
+ }
+ try {
+ if (r.getRequestStatus() != RequestStatus.SVC_PENDING) {
+ // request not pending anymore - aborted or cancelled.
+ completedRids.addElement(rid);
+ CMS.debug(
+ "request id " + rid + " no longer service pending");
+ } else {
+ boolean completed = send(r);
+
+ if (completed) {
+ completedRids.addElement(rid);
+ mAuthority.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CONNECTOR_REQUEST_COMPLETED", rid.toString()));
+ }
+ }
+ } catch (IOException e) {
+ mAuthority.log(ILogger.LL_WARN, CMS.getLogMessage("CMSCORE_CONNECTOR_REQUEST_ERROR", rid.toString(), e.toString()));
+ } catch (EBaseException e) {
+ // if connection is down, don't send the remaining request
+ // as it will sure fail.
+ mAuthority.log(ILogger.LL_WARN, CMS.getLogMessage("CMSCORE_CONNECTOR_DOWN"));
+ if (e.toString().indexOf("connection not available")
+ >= 0)
+ break;
+ }
+ }
+
+ // remove completed ones from list so they won't be resent.
+ Enumeration en = completedRids.elements();
+
+ synchronized (mRequestIds) {
+ while (en.hasMoreElements()) {
+ RequestId id = (RequestId) en.nextElement();
+
+ CMS.debug(
+ "Connector: Removed request " + id + " from re-send queue");
+ mRequestIds.removeElement(id.toString());
+ CMS.debug(
+ "Connector: mRequestIds now has " +
+ mRequestIds.size() + " elements.");
+ }
+ }
+ }
+
+ // this is almost the same as connector's send.
+ private boolean send(IRequest r)
+ throws IOException, EBaseException {
+ IRequest reply = null;
+
+ try {
+ HttpPKIMessage tomsg = new HttpPKIMessage();
+ HttpPKIMessage replymsg = null;
+
+ tomsg.fromRequest(r);
+ replymsg = (HttpPKIMessage) mConn.send(tomsg);
+ if(replymsg==null)
+ return false;
+ CMS.debug(
+ r.getRequestId() + " resent to CA");
+
+ RequestStatus replyStatus =
+ RequestStatus.fromString(replymsg.reqStatus);
+ int index = replymsg.reqId.lastIndexOf(':');
+ RequestId replyRequestId =
+ new RequestId(replymsg.reqId.substring(index + 1));
+
+ if (Debug.ON)
+ Debug.trace("reply request id " + replyRequestId +
+ " for request " + r.getRequestId());
+
+ if (replyStatus != RequestStatus.COMPLETE) {
+ CMS.debug("resend " +
+ r.getRequestId() + " still not completed.");
+ return false;
+ }
+
+ // request was completed. copy relevant contents.
+ replymsg.toRequest(r);
+ if (Debug.ON)
+ Debug.trace("resend request id was completed " + r.getRequestId());
+ mQueue.markAsServiced(r);
+ mQueue.releaseRequest(r);
+ CMS.debug(
+ "resend released request " + r.getRequestId());
+ return true;
+ } catch (EBaseException e) {
+ // same as not having sent it, so still want to resend.
+ mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CONNECTOR_RESEND_ERROR", r.getRequestId().toString(), e.toString()));
+ if (e.toString().indexOf("Connection refused by peer") > 0)
+ throw new EBaseException("connection not available");
+ }
+ return false;
+
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java b/pki/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java
new file mode 100644
index 000000000..fbb652282
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java
@@ -0,0 +1,122 @@
+// --- 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.cmscore.crmf;
+
+
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.crmf.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkcs11.*;
+import java.io.*;
+import java.util.*;
+
+import com.netscape.certsrv.apps.*;
+
+
+public class CRMFParser {
+
+ private static final OBJECT_IDENTIFIER PKIARCHIVEOPTIONS_OID =
+ new OBJECT_IDENTIFIER(new long[] {1, 3, 6, 1, 5, 5, 7, 5, 1, 4}
+ );
+
+ /**
+ * Retrieves PKIArchiveOptions from CRMF request.
+ *
+ * @param request CRMF request
+ * @return PKIArchiveOptions
+ * @exception failed to extrace option
+ */
+ public static PKIArchiveOptionsContainer[]
+ getPKIArchiveOptions(String crmfBlob) throws IOException {
+ Vector options = new Vector();
+
+ byte[] crmfBerBlob = null;
+
+ crmfBerBlob = CMS.AtoB(crmfBlob);
+ if (crmfBerBlob == null)
+ throw new IOException("no CRMF data found");
+
+ ByteArrayInputStream crmfBerBlobIn = new
+ ByteArrayInputStream(crmfBerBlob);
+ SEQUENCE crmfmsgs = null;
+
+ try {
+ crmfmsgs = (SEQUENCE) new
+ SEQUENCE.OF_Template(new
+ CertReqMsg.Template()).decode(
+ crmfBerBlobIn);
+ } catch (IOException e) {
+ throw new IOException("[crmf msgs]" + e.toString());
+ } catch (InvalidBERException e) {
+ throw new IOException("[crmf msgs]" + e.toString());
+ }
+
+ for (int z = 0; z < crmfmsgs.size(); z++) {
+ CertReqMsg certReqMsg = (CertReqMsg)
+ crmfmsgs.elementAt(z);
+ CertRequest certReq = certReqMsg.getCertReq();
+
+ // try to locate PKIArchiveOption control
+ AVA archAva = null;
+
+ try {
+ for (int i = 0; i < certReq.numControls(); i++) {
+ AVA ava = certReq.controlAt(i);
+ OBJECT_IDENTIFIER oid = ava.getOID();
+
+ if (oid.equals(PKIARCHIVEOPTIONS_OID)) {
+ archAva = ava;
+ break;
+ }
+ }
+ } catch (Exception e) {
+ throw new IOException("no PKIArchiveOptions found " + e.toString());
+ }
+ if (archAva != null) {
+
+ ASN1Value archVal = archAva.getValue();
+ ByteArrayInputStream bis = new ByteArrayInputStream(ASN1Util.encode(archVal));
+ PKIArchiveOptions archOpts = null;
+
+ try {
+ archOpts = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(bis);
+ } catch (IOException e) {
+ throw new IOException("[PKIArchiveOptions]" + e.toString());
+ } catch (InvalidBERException e) {
+ throw new IOException("[PKIArchiveOptions]" + e.toString());
+ }
+ options.addElement(new PKIArchiveOptionsContainer(archOpts, z));
+ }
+ }
+ if (options.size() == 0) {
+ throw new IOException("no PKIArchiveOptions found");
+ } else {
+ PKIArchiveOptionsContainer p[] = new PKIArchiveOptionsContainer[options.size()];
+
+ options.copyInto(p);
+ // options.clear();
+ return p;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java b/pki/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java
new file mode 100644
index 000000000..04529be69
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java
@@ -0,0 +1,33 @@
+// --- 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.cmscore.crmf;
+
+
+import org.mozilla.jss.pkix.crmf.*;
+
+
+public class PKIArchiveOptionsContainer {
+
+ public PKIArchiveOptions mAO = null;
+ public int mReqPos;
+
+ public PKIArchiveOptionsContainer(PKIArchiveOptions ao, int reqpos) {
+ mAO = ao;
+ mReqPos = reqpos;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java
new file mode 100644
index 000000000..c0afbe742
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java
@@ -0,0 +1,118 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java BigInteger object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class BigIntegerMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs BigInteger mapper.
+ */
+ public BigIntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ BigIntegerToDB((BigInteger) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, BigIntegerFromDB(
+ (String) attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String v = null;
+
+ try {
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ v = BigIntegerToDB(new
+ BigInteger(value.substring(2), 16));
+ } else {
+ v = BigIntegerToDB(new BigInteger(value));
+ }
+ } catch (NumberFormatException e) {
+ v = value;
+ }
+ return mLdapName + op + v;
+ }
+
+ public static String BigIntegerToDB(BigInteger i) {
+ int len = i.toString().length();
+ String ret = null;
+
+ if (len < 10) {
+ ret = "0" + Integer.toString(len) + i.toString();
+ } else {
+ ret = Integer.toString(len) + i.toString();
+ }
+ return ret;
+ }
+
+ public static BigInteger BigIntegerFromDB(String i) {
+ String s = i.substring(2);
+
+ // possibly check length
+ return new BigInteger(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java
new file mode 100644
index 000000000..fcb806bb5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java byte array object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ByteArrayMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a byte array mapper.
+ */
+ public ByteArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Lists a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ byte data[] = (byte[]) obj;
+ if (data == null) {
+ CMS.debug("ByteArrayMapper:mapObjectToLDAPAttributeSet " + name +
+ " size=0");
+ } else {
+ CMS.debug("ByteArrayMapper:mapObjectToLDAPAttributeSet " + name +
+ " size=" + data.length);
+ }
+ attrs.add(new LDAPAttribute(mLdapName, data));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, (byte[]) attr.getByteValues().nextElement());
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java
new file mode 100644
index 000000000..ad065f924
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java
@@ -0,0 +1,57 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of schema information
+ * for CRL.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_OC_CRL_RECORD = "crlIssuingPointRecord";
+ public static final String LDAP_ATTR_CRL_ID = "cn";
+ public static final String LDAP_ATTR_CRL_NUMBER = "crlNumber";
+ public static final String LDAP_ATTR_DELTA_NUMBER = "deltaNumber";
+ public static final String LDAP_ATTR_CRL_SIZE = "crlSize";
+ public static final String LDAP_ATTR_DELTA_SIZE = "deltaSize";
+ public static final String LDAP_ATTR_THIS_UPDATE = "thisUpdate";
+ public static final String LDAP_ATTR_NEXT_UPDATE = "nextUpdate";
+ public static final String LDAP_ATTR_FIRST_UNSAVED = "firstUnsaved";
+ public static final String LDAP_ATTR_CRL = "certificateRevocationList";
+ public static final String LDAP_ATTR_CA_CERT = "cACertificate";
+ public static final String LDAP_ATTR_CRL_CACHE = "crlCache";
+ public static final String LDAP_ATTR_REVOKED_CERTS = "revokedCerts";
+ public static final String LDAP_ATTR_UNREVOKED_CERTS = "unrevokedCerts";
+ public static final String LDAP_ATTR_EXPIRED_CERTS = "expiredCerts";
+ public static final String LDAP_ATTR_DELTA_CRL = "deltaRevocationList";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
new file mode 100644
index 000000000..8d7f19ca6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
@@ -0,0 +1,325 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+
+/**
+ * A class represents a CRL issuing point record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLIssuingPointRecord implements ICRLIssuingPointRecord, IDBObj {
+
+ protected String mId = null; // internal unique id
+ protected BigInteger mCRLNumber = null; // CRL number
+ protected Long mCRLSize = null;
+ protected Date mThisUpdate = null;
+ protected Date mNextUpdate = null;
+ protected BigInteger mDeltaCRLNumber = null; // delta CRL number
+ protected Long mDeltaCRLSize = null;
+ protected String mFirstUnsaved = null;
+ protected byte mCRL[] = null;
+ protected byte mCACert[] = null;
+ protected Hashtable mCRLCache = null;
+ protected Hashtable mRevokedCerts = null;
+ protected Hashtable mUnrevokedCerts = null;
+ protected Hashtable mExpiredCerts = null;
+ protected byte mDeltaCRL[] = null;
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_CRL_NUMBER);
+ mNames.addElement(ATTR_DELTA_NUMBER);
+ mNames.addElement(ATTR_CRL_SIZE);
+ mNames.addElement(ATTR_DELTA_SIZE);
+ mNames.addElement(ATTR_THIS_UPDATE);
+ mNames.addElement(ATTR_NEXT_UPDATE);
+ mNames.addElement(ATTR_FIRST_UNSAVED);
+ mNames.addElement(ATTR_CRL);
+ mNames.addElement(ATTR_CA_CERT);
+ mNames.addElement(ATTR_CRL_CACHE);
+ mNames.addElement(ATTR_REVOKED_CERTS);
+ mNames.addElement(ATTR_UNREVOKED_CERTS);
+ mNames.addElement(ATTR_EXPIRED_CERTS);
+ mNames.addElement(ATTR_DELTA_CRL);
+ }
+
+ /**
+ * Constructs empty CRLIssuingPointRecord. This is
+ * required in database framework.
+ */
+ public CRLIssuingPointRecord() {
+ }
+
+ /**
+ * Constructs a CRLIssuingPointRecord
+ */
+ public CRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize,
+ Date thisUpdate, Date nextUpdate) {
+ mId = id;
+ mCRLNumber = crlNumber;
+ mCRLSize = crlSize;
+ mThisUpdate = thisUpdate;
+ mNextUpdate = nextUpdate;
+ mDeltaCRLNumber = BigInteger.ZERO;
+ mFirstUnsaved = NEW_CACHE;
+ mDeltaCRLSize = Long.valueOf(-1L);
+ mCRLCache = null;
+ mRevokedCerts = null;
+ mUnrevokedCerts = null;
+ mExpiredCerts = null;
+ }
+
+ /**
+ * Constructs a CRLIssuingPointRecord
+ */
+ public CRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize,
+ Date thisUpdate, Date nextUpdate, BigInteger deltaCRLNumber, Long deltaCRLSize,
+ Hashtable revokedCerts, Hashtable unrevokedCerts, Hashtable expiredCerts) {
+ mId = id;
+ mCRLNumber = crlNumber;
+ mCRLSize = crlSize;
+ mThisUpdate = thisUpdate;
+ mNextUpdate = nextUpdate;
+ mDeltaCRLNumber = deltaCRLNumber;
+ mDeltaCRLSize = deltaCRLSize;
+ mFirstUnsaved = NEW_CACHE;
+ mCRLCache = null;
+ mRevokedCerts = revokedCerts;
+ mUnrevokedCerts = unrevokedCerts;
+ mExpiredCerts = expiredCerts;
+ }
+
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_ID)) {
+ mId = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_NUMBER)) {
+ mCRLNumber = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_SIZE)) {
+ mCRLSize = (Long) obj;
+ } else if (name.equalsIgnoreCase(ATTR_THIS_UPDATE)) {
+ mThisUpdate = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_NEXT_UPDATE)) {
+ mNextUpdate = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_NUMBER)) {
+ mDeltaCRLNumber = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_SIZE)) {
+ mDeltaCRLSize = (Long) obj;
+ } else if (name.equalsIgnoreCase(ATTR_FIRST_UNSAVED)) {
+ mFirstUnsaved = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL)) {
+ mCRL = (byte[]) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CA_CERT)) {
+ mCACert = (byte[]) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_CACHE)) {
+ mCRLCache = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_CERTS)) {
+ mRevokedCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_UNREVOKED_CERTS)) {
+ mUnrevokedCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_EXPIRED_CERTS)) {
+ mExpiredCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_CRL)) {
+ mDeltaCRL = (byte[]) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mId;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_NUMBER)) {
+ return mCRLNumber;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_SIZE)) {
+ return mCRLSize;
+ } else if (name.equalsIgnoreCase(ATTR_THIS_UPDATE)) {
+ return mThisUpdate;
+ } else if (name.equalsIgnoreCase(ATTR_NEXT_UPDATE)) {
+ return mNextUpdate;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_NUMBER)) {
+ return mDeltaCRLNumber;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_SIZE)) {
+ return mDeltaCRLSize;
+ } else if (name.equalsIgnoreCase(ATTR_FIRST_UNSAVED)) {
+ return mFirstUnsaved;
+ } else if (name.equalsIgnoreCase(ATTR_CRL)) {
+ return mCRL;
+ } else if (name.equalsIgnoreCase(ATTR_CA_CERT)) {
+ return mCACert;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_CACHE)) {
+ return mCRLCache;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_CERTS)) {
+ return mRevokedCerts;
+ } else if (name.equalsIgnoreCase(ATTR_UNREVOKED_CERTS)) {
+ return mUnrevokedCerts;
+ } else if (name.equalsIgnoreCase(ATTR_EXPIRED_CERTS)) {
+ return mExpiredCerts;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_CRL)) {
+ return mDeltaCRL;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieve unique CRL identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Retrieves CRL number.
+ */
+ public BigInteger getCRLNumber() {
+ return mCRLNumber;
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getCRLSize() {
+ return mCRLSize;
+ }
+
+ /**
+ * Retrieves this update time.
+ */
+ public Date getThisUpdate() {
+ return mThisUpdate;
+ }
+
+ /**
+ * Retrieves next update time.
+ */
+ public Date getNextUpdate() {
+ return mNextUpdate;
+ }
+
+ /**
+ * Retrieves delta CRL number.
+ */
+ public BigInteger getDeltaCRLNumber() {
+ return mDeltaCRLNumber;
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getDeltaCRLSize() {
+ return mDeltaCRLSize;
+ }
+
+ /**
+ * Retrieve unique CRL identifier.
+ */
+ public String getFirstUnsaved() {
+ return mFirstUnsaved;
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getCRL() {
+ return mCRL;
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getDeltaCRL() {
+ return mDeltaCRL;
+ }
+
+ public byte[] getCACert() {
+ return mCACert;
+ }
+
+ public Hashtable getCRLCacheNoClone() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return (Hashtable) mCRLCache;
+ }
+
+ public Hashtable getCRLCache() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return (Hashtable) mCRLCache.clone();
+ }
+
+ /**
+ * Retrieves cache info of revoked certificates.
+ */
+ public Hashtable getRevokedCerts() {
+ if (mRevokedCerts == null)
+ return null;
+ else
+ return (Hashtable) mRevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of unrevoked certificates.
+ */
+ public Hashtable getUnrevokedCerts() {
+ if (mUnrevokedCerts == null)
+ return null;
+ else
+ return (Hashtable) mUnrevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of expired certificates.
+ */
+ public Hashtable getExpiredCerts() {
+ if (mExpiredCerts == null)
+ return null;
+ else
+ return (Hashtable) mExpiredCerts.clone();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java
new file mode 100644
index 000000000..c2eba5acb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java
@@ -0,0 +1,365 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+import com.netscape.certsrv.apps.*;
+
+/**
+ * A class represents a CRL repository. It stores all the
+ * CRL issuing points.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLRepository extends Repository implements ICRLRepository {
+
+ private final String mLdapCRLIssuingPointName = "cn";
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+
+ /**
+ * Constructs a CRL repository.
+ */
+ public CRLRepository(IDBSubsystem dbService, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = dbService;
+
+ IDBRegistry reg = dbService.getRegistry();
+
+ /**
+ String crlRecordOC[] = new String[1];
+ crlRecordOC[0] = Schema.LDAP_OC_CRL_RECORD;
+ reg.registerObjectClass(CRLIssuingPointRecord.class.getName(),
+ crlRecordOC);
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_ID, new
+ StringMapper(Schema.LDAP_ATTR_CRL_ID));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_NUMBER, new
+ BigIntegerMapper(Schema.LDAP_ATTR_CRL_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_SIZE, new
+ LongMapper(Schema.LDAP_ATTR_CRL_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_THIS_UPDATE, new
+ DateMapper(Schema.LDAP_ATTR_THIS_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE, new
+ DateMapper(Schema.LDAP_ATTR_NEXT_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL, new
+ ByteArrayMapper(Schema.LDAP_ATTR_CRL));
+ **/
+ }
+
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ }
+
+ /**
+ * Adds CRL issuing points.
+ */
+ public void addCRLIssuingPointRecord(ICRLIssuingPointRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" +
+ ((CRLIssuingPointRecord) rec).getId().toString() + "," + getDN();
+
+ s.add(name, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Retrieves all issuing points' names
+ */
+ public Vector getIssuingPointsNames() throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ try {
+ String[] attrs = {ICRLIssuingPointRecord.ATTR_ID, "objectclass"};
+ String filter = "objectclass=" + CMS.getCRLIssuingPointRecordName();
+ IDBSearchResults res = s.search(getDN(), filter, attrs);
+ Vector v = new Vector();
+ while (res.hasMoreElements()) {
+ ICRLIssuingPointRecord nextelement =
+ (ICRLIssuingPointRecord)res.nextElement();
+ CMS.debug("CRLRepository getIssuingPointsNames(): name = "
+ +nextelement.getId());
+ v.addElement(nextelement.getId());
+ }
+
+ return v;
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Reads issuing point record.
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPointRecord(String id)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CRLIssuingPointRecord rec = null;
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) {
+ rec = (CRLIssuingPointRecord) s.read(name);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * deletes issuing point record.
+ */
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException {
+ IDBSSession s = null;
+
+ try {
+ s = mDBService.createSession();
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void modifyCRLIssuingPointRecord(String id,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) s.modify(name, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Updates CRL issuing point record.
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (newCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, newCRL);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, thisUpdate);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record.
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize,
+ Hashtable revokedCerts, Hashtable unrevokedCerts, Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (newCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, newCRL);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, thisUpdate);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ if (revokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ }
+ if (unrevokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ }
+ if (expiredCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ }
+ if (revokedCerts != null || unrevokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with recently revoked certificates info.
+ */
+ public void updateRevokedCerts(String id, Hashtable revokedCerts,
+ Hashtable unrevokedCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with recently expired certificates info.
+ */
+ public void updateExpiredCerts(String id, Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with CRL cache info.
+ */
+ public void updateCRLCache(String id, Long crlSize,
+ Hashtable revokedCerts,
+ Hashtable unrevokedCerts,
+ Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (crlSize != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with delta-CRL.
+ */
+ public void updateDeltaCRL(String id, BigInteger deltaCRLNumber,
+ Long deltaCRLSize, Date nextUpdate,
+ byte[] deltaCRL)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (deltaCRLNumber != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_NUMBER,
+ Modification.MOD_REPLACE, deltaCRLNumber);
+ }
+ if (deltaCRLSize != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_SIZE,
+ Modification.MOD_REPLACE, deltaCRLSize);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ if (deltaCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_CRL,
+ Modification.MOD_REPLACE, deltaCRL);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ public void updateFirstUnsaved(String id, String firstUnsaved)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (firstUnsaved != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, firstUnsaved);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java
new file mode 100644
index 000000000..c444a45ac
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java
@@ -0,0 +1,64 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of certificate record
+ * specific schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_ATTR_META_INFO = "metaInfo";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_CREATE_TIME = "dateOfCreate";
+ public static final String LDAP_ATTR_MODIFY_TIME = "dateOfModify";
+ public static final String LDAP_ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+
+ public static final String LDAP_OC_CERT_RECORD = "certificateRecord";
+ public static final String LDAP_ATTR_CERT_RECORD_ID = "certRecordId";
+ public static final String LDAP_ATTR_NOT_BEFORE = "notBefore";
+ public static final String LDAP_ATTR_NOT_AFTER = "notAfter";
+ public static final String LDAP_ATTR_SIGNED_CERT = "userCertificate";
+ public static final String LDAP_ATTR_VERSION = "version";
+ public static final String LDAP_ATTR_DURATION = "duration";
+ public static final String LDAP_ATTR_SUBJECT = "subjectName";
+ public static final String LDAP_ATTR_ALGORITHM = "algorithmId";
+ public static final String LDAP_ATTR_SIGNING_ALGORITHM = "signingAlgorithmId";
+ public static final String LDAP_ATTR_REVO_INFO = "revInfo";
+ public static final String LDAP_ATTR_CERT_STATUS = "certStatus";
+ public static final String LDAP_ATTR_AUTO_RENEW = "autoRenew";
+ public static final String LDAP_ATTR_ISSUED_BY = "issuedBy";
+ public static final String LDAP_ATTR_REVOKED_BY = "revokedBy";
+ public static final String LDAP_ATTR_REVOKED_ON = "revokedOn";
+ public static final String LDAP_ATTR_EXTENSION = "extension";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java
new file mode 100644
index 000000000..308d801e3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java
@@ -0,0 +1,278 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a serializable certificate record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertRecord implements IDBObj, ICertRecord {
+
+ private BigInteger mId = null;
+ private X509CertImpl mX509Certificate = null;
+ private String mStatus = null;
+ private String mAutoRenew = null;
+ private MetaInfo mMetaInfo = null;
+ // XXX revocationInfo not serializable
+ private transient RevocationInfo mRevocationInfo = null;
+ private Date mCreateTime = null;
+ private Date mModifyTime = null;
+ private String mIssuedBy = null;
+ private String mRevokedBy = null;
+ private Date mRevokedOn = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_META_INFO);
+ mNames.addElement(ATTR_REVO_INFO);
+ mNames.addElement(ATTR_X509CERT);
+ mNames.addElement(ATTR_CREATE_TIME);
+ mNames.addElement(ATTR_MODIFY_TIME);
+ mNames.addElement(ATTR_CERT_STATUS);
+ mNames.addElement(ATTR_AUTO_RENEW);
+ mNames.addElement(ATTR_ISSUED_BY);
+ mNames.addElement(ATTR_REVOKED_BY);
+ mNames.addElement(ATTR_REVOKED_ON);
+ }
+
+ /**
+ * Constructs empty certificate record.
+ */
+ public CertRecord() {
+ }
+
+ /**
+ * Constructs certiificate record with certificate
+ * and meta info.
+ */
+ public CertRecord(BigInteger id, Certificate cert, MetaInfo meta) {
+ mId = id;
+ if (cert instanceof X509CertImpl)
+ mX509Certificate = (X509CertImpl) cert;
+ mMetaInfo = meta;
+ mStatus = STATUS_VALID;
+ mAutoRenew = AUTO_RENEWAL_ENABLED;
+ mCreateTime = CMS.getCurrentDate();
+ mModifyTime = CMS.getCurrentDate();
+ }
+
+ /**
+ * Sets attribute to this record.
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_REVO_INFO)) {
+ mRevocationInfo = (RevocationInfo) obj;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ mId = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ mMetaInfo = (MetaInfo) obj;
+ } else if (name.equalsIgnoreCase(ATTR_X509CERT)) {
+ mX509Certificate = (X509CertImpl) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CERT_STATUS)) {
+ mStatus = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_AUTO_RENEW)) {
+ mAutoRenew = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ mCreateTime = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ mModifyTime = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_ISSUED_BY)) {
+ mIssuedBy = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_BY)) {
+ mRevokedBy = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_ON)) {
+ mRevokedOn = (Date) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves attributes from this record.
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_REVO_INFO)) {
+ return mRevocationInfo;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mId;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ return mMetaInfo;
+ } else if (name.equalsIgnoreCase(ATTR_X509CERT)) {
+ return mX509Certificate;
+ } else if (name.equalsIgnoreCase(ATTR_CERT_STATUS)) {
+ return mStatus;
+ } else if (name.equalsIgnoreCase(ATTR_AUTO_RENEW)) {
+ return mAutoRenew;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ return mCreateTime;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ return mModifyTime;
+ } else if (name.equalsIgnoreCase(ATTR_ISSUED_BY)) {
+ return mIssuedBy;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_BY)) {
+ return mRevokedBy;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_ON)) {
+ return mRevokedOn;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes attribute from this record.
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves X509 certificate.
+ */
+ public X509CertImpl getCertificate() {
+ return mX509Certificate;
+ }
+
+ /**
+ * Retrieves meta information.
+ */
+ public MetaInfo getMetaInfo() {
+ return mMetaInfo;
+ }
+
+ /**
+ * Retrieves certificate status.
+ */
+ public String getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Retrieves the auto renew mode.
+ */
+ public String getAutoRenew() {
+ return mAutoRenew;
+ }
+
+ /**
+ * Retrieves revocation information.
+ */
+ public IRevocationInfo getRevocationInfo() {
+ return mRevocationInfo;
+ }
+
+ /**
+ * Retrieves serial number of this record. Usually,
+ * it is the same of the serial number of the
+ * associated certificate.
+ */
+ public BigInteger getSerialNumber() {
+ return mId;
+ }
+
+ /**
+ * Retrieves the person who issues this certificate.
+ */
+ public String getIssuedBy() {
+ return mIssuedBy;
+ }
+
+ /**
+ * Retrieves the person who revokes this certificate.
+ */
+ public String getRevokedBy() {
+ return mRevokedBy;
+ }
+
+ /**
+ * Retrieves the date which this record is revoked.
+ */
+ public Date getRevokedOn() {
+ return mRevokedOn;
+ }
+
+ /**
+ * Retrieves certificate serial number.
+ */
+ public BigInteger getCertificateSerialNumber() {
+ return mX509Certificate.getSerialNumber();
+ }
+
+ /**
+ * Retrieves not after.
+ */
+ public Date getNotAfter() {
+ return mX509Certificate.getNotAfter();
+ }
+
+ public Date getNotBefore() {
+ return mX509Certificate.getNotBefore();
+ }
+
+ /**
+ * Return revocation date.
+ */
+ public Date getRevocationDate() throws EDBException {
+ return mRevocationInfo.getRevocationDate();
+ }
+
+ public Date getCreateTime() {
+ return mCreateTime;
+ }
+
+ public Date getModifyTime() {
+ return mModifyTime;
+ }
+
+ /**
+ * String representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("CertRecord: ");
+ if (getSerialNumber() != null)
+ buf.append(" " + getSerialNumber().toString());
+ return buf.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java
new file mode 100644
index 000000000..18b8c1bf5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java
@@ -0,0 +1,118 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a list of certificate records.
+ * <P>
+ *
+ * @author thomask mzhao
+ * @version $Revision$, $Date$
+ */
+public class CertRecordList implements ICertRecordList {
+
+ private IDBVirtualList mVlist = null;
+
+ /**
+ * Constructs a request list.
+ */
+ public CertRecordList(IDBVirtualList vlist) {
+ mVlist = vlist;
+ }
+
+ public int getCurrentIndex() {
+ return mVlist.getCurrentIndex();
+ }
+
+ /**
+ * Retrieves the size of request list.
+ */
+ public int getSize() {
+ // get the size of the virtual list
+ return mVlist.getSize();
+ }
+
+ public int getSizeBeforeJumpTo() {
+ return mVlist.getSizeBeforeJumpTo();
+
+ }
+
+ public int getSizeAfterJumpTo() {
+ return mVlist.getSizeAfterJumpTo();
+
+ }
+
+ /**
+ * Process certificate record as soon as it is returned.
+ * kmccarth: changed to ignore startidx and endidx because VLVs don't
+ * provide a stable list.
+ */
+ public void processCertRecords(int startidx, int endidx,
+ IElementProcessor ep) throws EBaseException {
+ int i = 0;
+ while ( i<mVlist.getSize() ) {
+ Object element = mVlist.getElementAt(i);
+ if (element != null && (! (element instanceof String)) ) {
+ ep.process(element);
+ }
+ i++;
+ }
+ }
+
+ /**
+ * Retrieves requests.
+ * It's no good to call this if you didnt check
+ * if the startidx, endidx are valid.
+ */
+ public Enumeration getCertRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector entries = new Vector();
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = mVlist.getElementAt(i);
+
+ // CMS.debug("gerCertRecords[" + i + "] element: " + element);
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ return entries.elements();
+ }
+
+ public Object getCertRecord(int index)
+ throws EBaseException {
+
+ Object element = mVlist.getElementAt(index);
+
+ return element;
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java
new file mode 100644
index 000000000..6b910ebbb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java
@@ -0,0 +1,98 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * A class represents a mapper to serialize
+ * certificate record into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertRecordMapper implements IDBAttrMapper {
+
+ private ICertificateRepository mDB = null;
+
+ public CertRecordMapper(ICertificateRepository db) {
+ mDB = db;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(CertDBSchema.LDAP_ATTR_CERT_RECORD_ID);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ CertRecord rec = (CertRecord) obj;
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_CERT_RECORD_ID,
+ rec.getSerialNumber().toString()));
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_CERT_RECORD_ID);
+
+ if (attr == null)
+ return;
+ String serialno = (String) attr.getStringValues().nextElement();
+ ICertRecord rec = mDB.readCertificateRecord(
+ new BigInteger(serialno));
+
+ parent.set(name, rec);
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return name + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
new file mode 100644
index 000000000..526e855e6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
@@ -0,0 +1,1985 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.BigInteger;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents a certificate repository. It
+ * stores all the issued certificate.
+ * <P>
+ *
+ * @author thomask
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class CertificateRepository extends Repository
+ implements ICertificateRepository {
+
+ public final String CERT_X509ATTRIBUTE = "x509signedcert";
+
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+ private String mRequestBaseDN;
+ private boolean mConsistencyCheck = false;
+ private boolean mSkipIfInconsistent = false;
+
+ private int mCertStatusUpdateInterval = 0;
+ private Hashtable mCRLIssuingPoints = new Hashtable();
+
+ private int mTransitMaxRecords = 1000000;
+ private int mTransitRecordPageSize = 200;
+
+ /**
+ * Constructs a certificate repository.
+ */
+ public CertificateRepository(IDBSubsystem dbService, String certRepoBaseDN, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = certRepoBaseDN;
+
+ mDBService = dbService;
+
+ // registers CMS database attributes
+ IDBRegistry reg = dbService.getRegistry();
+
+ IConfigStore cfg = mDBService.getConfigStore();
+ }
+
+ public ICertRecord createCertRecord(BigInteger id, Certificate cert, MetaInfo meta) {
+ return new CertRecord(id, cert, meta);
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+
+ CMS.debug("CertificateRepository: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0 )
+ {
+ return null;
+
+ }
+
+ String ldapfilter = "(" + "certstatus" + "=*" + ")";
+
+ String[] attrs = null;
+
+ ICertRecordList recList = findCertRecordsInList(ldapfilter,attrs,serial_upper_bound.toString(10),"serialno", 5 * -1);
+
+ int size = recList.getSize();
+
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: recList size " + size);
+
+ if (size <= 0) {
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: index may be empty");
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < 5; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ BigInteger serial = curRec.getSerialNumber();
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: serialno " + serial);
+
+ if( ((serial.compareTo(serial_low_bound) == 0) || (serial.compareTo(serial_low_bound) == 1) ) &&
+ ((serial.compareTo(serial_upper_bound) == 0) || (serial.compareTo(serial_upper_bound) == -1) ))
+ {
+ CMS.debug("getLastSerialNumberInRange returning: " + serial);
+ return serial;
+ }
+ } else {
+ CMS.debug("getLastSerialNumberInRange:found null from getCertRecord");
+ }
+ }
+
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeCertRecords(BigInteger beginS, BigInteger endS) throws EBaseException
+ {
+ String filter = "(" + CertRecord.ATTR_CERT_STATUS + "=*" + ")";
+ ICertRecordList list =findCertRecordsInList(filter,
+ null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+ BigInteger cur = rec.getSerialNumber();
+ BigInteger max = cur.max(beginS);
+ BigInteger min = cur;
+ if (endS != null)
+ min = cur.min(endS);
+ if (cur.equals(beginS) || cur.equals(endS) ||
+ (cur.equals(max) && cur.equals(min)))
+ deleteCertificateRecord(cur);
+ }
+ }
+
+ public void setConsistencyCheck(boolean ConsistencyCheck) {
+ mConsistencyCheck = ConsistencyCheck;
+ }
+
+ public void setSkipIfInConsistent(boolean SkipIfInconsistent) {
+ mSkipIfInconsistent = SkipIfInconsistent;
+ }
+
+ public void setTransitMaxRecords(int max) {
+ mTransitMaxRecords = max;
+ }
+
+ public void setTransitRecordPageSize(int size) {
+ mTransitRecordPageSize = size;
+
+ }
+
+ /**
+ * register CRL Issuing Point
+ */
+ public void addCRLIssuingPoint(String id, ICRLIssuingPoint crlIssuingPoint) {
+ mCRLIssuingPoints.put(id, crlIssuingPoint);
+ }
+
+ /**
+ * interval value: (in seconds)
+ * 0 - disable
+ * >0 - enable
+ */
+ public CertStatusUpdateThread mCertStatusUpdateThread = null;
+ public RetrieveModificationsThread mRetrieveModificationsThread = null;
+
+ public void setCertStatusUpdateInterval(IRepository requestRepo, int interval, boolean listenToCloneModifications) {
+ CMS.debug("In setCertStatusUpdateInterval " + interval);
+ if (interval == 0) {
+ CMS.debug("In setCertStatusUpdateInterval interval = 0" + interval);
+ if (mCertStatusUpdateThread != null) {
+ mCertStatusUpdateThread.stop();
+ }
+ if (mRetrieveModificationsThread != null) {
+ mRetrieveModificationsThread.stop();
+ }
+ return;
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval listenToCloneModifications="+listenToCloneModifications+
+ " mRetrieveModificationsThread="+mRetrieveModificationsThread);
+ if (listenToCloneModifications && mRetrieveModificationsThread == null) {
+ CMS.debug("In setCertStatusUpdateInterval about to create RetrieveModificationsThread");
+ mRetrieveModificationsThread = new RetrieveModificationsThread(this, "RetrieveModificationsThread");
+ LDAPSearchResults mResults = null;
+ try {
+ mResults = startSearchForModifiedCertificateRecords();
+ } catch (Exception e) {
+ mResults = null;
+ }
+ if (mResults != null) {
+ mRetrieveModificationsThread.setResults(mResults);
+ mRetrieveModificationsThread.start();
+ }
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval mCertStatusUpdateThread " + mCertStatusUpdateThread);
+ if (mCertStatusUpdateThread == null) {
+ CMS.debug("In setCertStatusUpdateInterval about to create CertStatusUpdateThread ");
+ mCertStatusUpdateThread = new CertStatusUpdateThread(this, requestRepo, "CertStatusUpdateThread");
+ mCertStatusUpdateThread.setInterval(interval);
+ mCertStatusUpdateThread.start();
+ } else {
+ CMS.debug("In setCertStatusUpdateInterval it thinks the thread is up already ");
+ mCertStatusUpdateThread.setInterval(interval);
+ // dont do anything if we have a thread running already
+ }
+ }
+
+
+ /**
+ * Blocking method.
+ */
+ public void updateCertStatus() throws EBaseException {
+
+ CMS.debug("In updateCertStatus()");
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_VALID_SEARCH"));
+ transitInvalidCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_VALID_SEARCH"));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_EXPIRED_SEARCH"));
+ transitValidCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_EXPIRED_SEARCH"));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_REVOKED_EXPIRED_SEARCH"));
+ transitRevokedExpiredCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_REVOKED_EXPIRED_SEARCH"));
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ public void setRequestDN( String requestDN ) {
+ mRequestBaseDN = requestDN;
+ }
+
+ public String getRequestDN() {
+ return mRequestBaseDN;
+ }
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Adds a certificate record to the repository. Each certificate
+ * record contains four parts: certificate, meta-attributes,
+ * issue information and reovcation information.
+ * <P>
+ *
+ * @param cert X.509 certificate
+ * @exception EBaseException failed to add new certificate to
+ * the repository
+ */
+ public void addCertificateRecord(ICertRecord record)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ ((CertRecord) record).getSerialNumber().toString() + "," + getDN();
+ SessionContext ctx = SessionContext.getContext();
+ String uid = (String) ctx.get(SessionContext.USER_ID);
+
+ if (uid == null) {
+ // XXX is this right?
+ record.set(CertRecord.ATTR_ISSUED_BY, "system");
+
+ /**
+ System.out.println("XXX servlet should set USER_ID");
+ throw new EBaseException(BaseResources.UNKNOWN_PRINCIPAL_1,
+ "null");
+ **/
+ } else {
+ record.set(CertRecord.ATTR_ISSUED_BY, uid);
+ }
+
+ // Check validity of this certificate. If it is not invalid,
+ // mark it so. We will have a thread to transit the status
+ // from INVALID to VALID.
+ X509CertImpl x509cert = (X509CertImpl) record.get(
+ CertRecord.ATTR_X509CERT);
+
+ if (x509cert != null) {
+ Date now = CMS.getCurrentDate();
+
+ if (x509cert.getNotBefore().after(now)) {
+ // not yet valid
+ record.set(ICertRecord.ATTR_CERT_STATUS,
+ ICertRecord.STATUS_INVALID);
+ }
+ }
+
+ s.add(name, record);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Used by the Clone Master (CLA) to add a revoked certificate
+ * record to the repository.
+ * <p>
+ *
+ * @param record a CertRecord
+ * @exception EBaseException failed to add new certificate to
+ * the repository
+ */
+ public void addRevokedCertRecord(CertRecord record)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ record.getSerialNumber().toString() + "," + getDN();
+
+ s.add(name, record);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * This transits a certificate status from VALID to EXPIRED
+ * if a certificate becomes expired.
+ */
+ public void transitValidCertificates() throws EBaseException {
+
+ Date now = CMS.getCurrentDate();
+ ICertRecordList recList = getValidCertsByNotAfterDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("transidValidCertificates: list size: " + size);
+ CMS.debug("transitValidCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ Date notAfter = curRec.getNotAfter();
+
+ //CMS.debug("notAfter " + notAfter.toString() + " now " + now.toString());
+ if (notAfter.after(now)) {
+ CMS.debug("Record does not qualify,notAfter " + notAfter.toString() + " date " + now.toString());
+ continue;
+ }
+
+ CMS.debug("transitValid: curRec: " + i + " " + curRec.toString());
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+ } else {
+ CMS.debug("found null from getCertRecord");
+ }
+ }
+
+ CertRecord cRec = null;
+ BigInteger serial = null;
+
+ transitCertList(cList, CertRecord.STATUS_EXPIRED);
+ }
+
+ /**
+ * This transits a certificate status from REVOKED to REVOKED_EXPIRED
+ * if an revoked certificate becomes expired.
+ */
+ public void transitRevokedExpiredCertificates() throws EBaseException {
+ Date now = CMS.getCurrentDate();
+ ICertRecordList recList = getRevokedCertsByNotAfterDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+
+ int ltSize = recList.getSizeBeforeJumpTo();
+ Vector cList = new Vector(ltSize);
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ CMS.debug("transitRevokedExpiredCertificates: list size: " + size);
+ CMS.debug("transitRevokedExpiredCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+ CMS.debug("transitRevokedExpired: curRec: " + i + " " + curRec.toString());
+
+ Date notAfter = curRec.getNotAfter();
+
+ // CMS.debug("notAfter " + notAfter.toString() + " now " + now.toString());
+ if (notAfter.after(now)) {
+ CMS.debug("Record does not qualify,notAfter " + notAfter.toString() + " date " + now.toString());
+ continue;
+ }
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+ } else {
+ CMS.debug("found null record in getCertRecord");
+ }
+ }
+
+ transitCertList(cList, CertRecord.STATUS_REVOKED_EXPIRED);
+
+ }
+
+ /**
+ * This transits a certificate status from INVALID to VALID
+ * if a certificate becomes valid.
+ */
+ public void transitInvalidCertificates() throws EBaseException {
+
+ Date now = CMS.getCurrentDate();
+
+ ICertRecordList recList = getInvalidCertsByNotBeforeDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("transidInValidCertificates: list size: " + size);
+ CMS.debug("transitInValidCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ Date notBefore = curRec.getNotBefore();
+
+ //CMS.debug("notBefore " + notBefore.toString() + " now " + now.toString());
+ if (notBefore.after(now)) {
+ CMS.debug("Record does not qualify,notBefore " + notBefore.toString() + " date " + now.toString());
+ continue;
+
+ }
+ CMS.debug("transitInValid: curRec: " + i + " " + curRec.toString());
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+
+ } else {
+ CMS.debug("found null from getCertRecord");
+ }
+ }
+
+ transitCertList(cList, CertRecord.STATUS_VALID);
+
+ }
+
+ private void transitCertList(Vector cList, String newCertStatus) throws EBaseException {
+ CertRecord cRec = null;
+ BigInteger serial = null;
+
+ int i;
+
+ CMS.debug("transitCertList " + newCertStatus);
+
+ for (i = 0; i < cList.size(); i++) {
+ if (mConsistencyCheck) {
+ cRec = (CertRecord) cList.elementAt(i);
+
+ if (cRec == null)
+ continue;
+
+ serial = cRec.getSerialNumber();
+ } else {
+ serial = (BigInteger) cList.elementAt(i);
+ }
+
+ updateStatus(serial, newCertStatus);
+
+ if (newCertStatus.equals(CertRecord.STATUS_REVOKED_EXPIRED)) {
+
+ // inform all CRLIssuingPoints about revoked and expired certificate
+
+ Enumeration eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) eIPs.nextElement();
+
+ if (ip != null) {
+ ip.addExpiredCert(serial);
+ }
+ }
+
+ }
+
+ CMS.debug("transitCertList number at: " + i + " = " + serial);
+ }
+
+ cList.removeAllElements();
+ }
+
+ /**
+ * Reads the certificate identified by the given serial no.
+ */
+ public X509CertImpl getX509Certificate(BigInteger serialNo)
+ throws EBaseException {
+ X509CertImpl cert = null;
+ ICertRecord cr = readCertificateRecord(serialNo);
+
+ return (cr.getCertificate());
+ }
+
+ /**
+ * Deletes certificate record.
+ */
+ public void deleteCertificateRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ s.delete(name);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Reads certificate from repository.
+ */
+ public ICertRecord readCertificateRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecord rec = null;
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ rec = (CertRecord) s.read(name);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return rec;
+ }
+
+ public synchronized void modifyCertificateRecord(BigInteger serialNo,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ mods.add(CertRecord.ATTR_MODIFY_TIME, Modification.MOD_REPLACE,
+ CMS.getCurrentDate());
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Checks if the specified certificate is in the repository.
+ */
+ public boolean containsCertificate(BigInteger serialNo)
+ throws EBaseException {
+ try {
+ ICertRecord cr = readCertificateRecord(serialNo);
+
+ if (cr != null)
+ return true;
+ } catch (EBaseException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Marks certificate as revoked.
+ */
+ public void markAsRevoked(BigInteger id, IRevocationInfo info)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_REVO_INFO, Modification.MOD_ADD, info);
+ SessionContext ctx = SessionContext.getContext();
+ String uid = (String) ctx.get(SessionContext.USER_ID);
+
+ if (uid == null) {
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_ADD,
+ "system");
+ } else {
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_ADD,
+ uid);
+ }
+ mods.add(CertRecord.ATTR_REVOKED_ON, Modification.MOD_ADD,
+ CMS.getCurrentDate());
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ CertRecord.STATUS_REVOKED);
+ modifyCertificateRecord(id, mods);
+ }
+
+ /**
+ * Unmarks revoked certificate.
+ */
+ public void unmarkRevoked(BigInteger id, IRevocationInfo info,
+ Date revokedOn, String revokedBy)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_REVO_INFO, Modification.MOD_DELETE, info);
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_DELETE, revokedBy);
+ mods.add(CertRecord.ATTR_REVOKED_ON, Modification.MOD_DELETE, revokedOn);
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ CertRecord.STATUS_VALID);
+ modifyCertificateRecord(id, mods);
+ }
+
+ /**
+ * Updates the certificiate record status to the specified.
+ */
+ public void updateStatus(BigInteger id, String status)
+ throws EBaseException {
+ CMS.debug("updateStatus: " + id + " status " + status);
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ status);
+ modifyCertificateRecord(id, mods);
+ }
+
+ public Enumeration searchCertificates(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ CMS.debug("searchCertificates filter " + filter + " maxSize " + maxSize);
+ try {
+ e = s.search(getDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public Enumeration searchCertificates(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ CMS.debug("searchCertificateswith time limit filter " + filter);
+ try {
+ e = s.search(getDN(), filter, maxSize, timeLimit);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Returns a list of X509CertImp that satisfies the filter.
+ * @deprecated replaced by <code>findCertificatesInList</code>
+ */
+ public Enumeration findCertRecs(String filter)
+ throws EBaseException {
+ CMS.debug("findCertRecs " + filter);
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ try {
+ e = s.search(getDN(), filter);
+ } finally {
+ if (s != null) s.close();
+ }
+ return e;
+ }
+
+ public Enumeration findCertRecs(String filter, String[] attrs)
+ throws EBaseException {
+
+ CMS.debug( "findCertRecs " + filter
+ + "attrs " + Arrays.toString( attrs ) );
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ try {
+ e = s.search(getDN(), filter, attrs);
+ } finally {
+ if (s != null) s.close();
+ }
+ return e;
+
+ }
+
+ public Enumeration findCertificates(String filter)
+ throws EBaseException {
+ Enumeration e = findCertRecords(filter);
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ return v.elements();
+ }
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ * If you are going to process everything in the list,
+ * use this.
+ */
+ public Enumeration findCertRecords(String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ //e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Finds certificate records. Here is a list of filter
+ * attribute can be used:
+ * <pre>
+ * certRecordId
+ * certMetaInfo
+ * certStatus
+ * certCreateTime
+ * certModifyTime
+ * x509Cert.notBefore
+ * x509Cert.notAfter
+ * x509Cert.subject
+ * </pre>
+ * The filter should follow RFC1558 LDAP filter syntax.
+ * For example,
+ * <pre>
+ * (&(certRecordId=5)(x509Cert.notBefore=934398398))
+ * </pre>
+ */
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException {
+ return findCertRecordsInList(filter, attrs, CertRecord.ATTR_ID,
+ pageSize);
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ CMS.debug("In findCertRecordsInList");
+ CertRecordList list = null;
+
+ try {
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter, attrs,
+ sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ return findCertRecordsInList(filter, attrs, jumpTo, false, sortKey, pageSize);
+
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, boolean hardJumpTo,
+ String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecordList list = null;
+
+ CMS.debug("In findCertRecordsInList with Jumpto " + jumpTo);
+ try {
+ String jumpToVal = null;
+
+ if (hardJumpTo) {
+ CMS.debug("In findCertRecordsInList with hardJumpto ");
+ jumpToVal = "99";
+ } else {
+ int len = jumpTo.length();
+
+ if (len > 9) {
+ jumpToVal = Integer.toString(len) + jumpTo;
+ } else {
+ jumpToVal = "0" + Integer.toString(len) + jumpTo;
+ }
+ }
+
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter,
+ attrs, jumpToVal, sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList findCertRecordsInListRawJumpto(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecordList list = null;
+
+ CMS.debug("In findCertRecordsInListRawJumpto with Jumpto " + jumpTo);
+
+ try {
+
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter,
+ attrs, jumpTo, sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ /**
+ * Marks certificate as renewable.
+ */
+ public void markCertificateAsRenewable(ICertRecord record)
+ throws EBaseException {
+ changeRenewalAttribute(((CertRecord) record).getSerialNumber().toString(),
+ CertRecord.AUTO_RENEWAL_ENABLED);
+ }
+
+ /**
+ * Marks certificate as renewable.
+ */
+ public void markCertificateAsNotRenewable(ICertRecord record)
+ throws EBaseException {
+ changeRenewalAttribute(((CertRecord) record).getSerialNumber().toString(),
+ CertRecord.AUTO_RENEWAL_DISABLED);
+ }
+
+ public void markCertificateAsRenewed(String serialNo)
+ throws EBaseException {
+ changeRenewalAttribute(serialNo, CertRecord.AUTO_RENEWAL_DONE);
+ }
+
+ public void markCertificateAsRenewalNotified(String serialNo)
+ throws EBaseException {
+ changeRenewalAttribute(serialNo, CertRecord.AUTO_RENEWAL_NOTIFIED);
+ }
+
+ private void changeRenewalAttribute(String serialno, String value)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" + serialno +
+ "," + getDN();
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_AUTO_RENEW, Modification.MOD_REPLACE,
+ value);
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * temp solution...
+ */
+ public class RenewableCertificateCollection {
+ Vector mToRenew = null;
+ Vector mToNotify = null;
+ public RenewableCertificateCollection() {
+ }
+
+ public Vector getRenewable() {
+ return mToRenew;
+ }
+
+ public Vector getNotifiable() {
+ return mToNotify;
+ }
+
+ public void addCertificate(String renewalFlag, Object o) {
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_ENABLED)) {
+ if (mToRenew == null)
+ mToRenew = new Vector();
+ mToRenew.addElement(o);
+ }
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_DISABLED)) {
+ if (mToNotify == null)
+ mToNotify = new Vector();
+ mToNotify.addElement(o);
+ }
+ }
+ }
+
+ public Hashtable getRenewableCertificates(String renewalTime)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ Hashtable tab = null;
+
+ try {
+ String filter = "(&(" + CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID + ")("
+ + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + "<=" + renewalTime +
+ ")(!(" + CertRecord.ATTR_AUTO_RENEW + "=" +
+ CertRecord.AUTO_RENEWAL_DONE +
+ "))(!(" + CertRecord.ATTR_AUTO_RENEW + "=" +
+ CertRecord.AUTO_RENEWAL_NOTIFIED + ")))";
+ //Enumeration e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+
+ tab = new Hashtable();
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ String subjectDN = cert.getSubjectDN().toString();
+ String renewalFlag = rec.getAutoRenew();
+
+ // See if the subjectDN is in the table
+ Object val = null;
+
+ if ((val = tab.get(subjectDN)) == null) {
+ RenewableCertificateCollection collection =
+ new RenewableCertificateCollection();
+
+ collection.addCertificate(renewalFlag, cert);
+ tab.put(subjectDN, collection);
+ } else {
+ ((RenewableCertificateCollection) val).addCertificate(renewalFlag, cert);
+ }
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return tab;
+ }
+
+ /**
+ * Gets all valid and unexpired certificates pertaining
+ * to a subject DN.
+ *
+ * @param subjectDN The distinguished name of the subject.
+ * @param validityType The type of certificates to get.
+ * @return An array of certificates.
+ */
+
+ public X509CertImpl[] getX509Certificates(String subjectDN,
+ int validityType) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ X509CertImpl certs[] = null;
+
+ try {
+ // XXX - not checking validityType...
+ String filter = "(&(" + CertRecord.ATTR_X509CERT +
+ "." + X509CertInfo.SUBJECT + "=" + subjectDN;
+
+ if (validityType == ALL_VALID_CERTS) {
+ filter += ")(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID;
+ }
+ if (validityType == ALL_UNREVOKED_CERTS) {
+ filter += ")(|(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID + ")(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_EXPIRED + ")";
+ }
+ filter += "))";
+
+ //Enumeration e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ if (v.size() == 0)
+ return null;
+ certs = new X509CertImpl[v.size()];
+ v.copyInto(certs);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return certs;
+ }
+
+ public X509CertImpl[] getX509Certificates(String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ X509CertImpl certs[] = null;
+
+ try {
+ Enumeration e = null;
+
+ if (filter != null && filter.length() > 0) {
+ //e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ }
+
+ Vector v = new Vector();
+
+ while (e != null && e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ if (v.size() > 0) {
+ certs = new X509CertImpl[v.size()];
+ v.copyInto(certs);
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return certs;
+ }
+
+ /**
+ * Retrives all valid certificates excluding ones already revoked.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getValidCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector v = new Vector();
+
+ try {
+
+ // 'from' determines 'jumpto' value
+ // 'to' determines where to stop looking
+
+ String ldapfilter = "(certstatus=VALID)";
+
+ String fromVal = "0";
+ try {
+ if (from != null) {
+ int fv = Integer.parseInt(from);
+ fromVal = from;
+ }
+ } catch (Exception e1) {
+ // from is not integer
+ }
+
+ ICertRecordList list =
+ findCertRecordsInList(ldapfilter, null, fromVal, "serialno", 40);
+
+ BigInteger toInt = null;
+ if (to != null && !to.trim().equals("")) {
+ toInt = new BigInteger(to);
+ }
+
+ for (int i=0;; i++) {
+ CertRecord rec = (CertRecord) list.getCertRecord(i);
+ CMS.debug("processing record: "+i);
+ if (rec == null) {
+ break; // no element returned
+ } else {
+
+ CMS.debug("processing record: "+i+" "+rec.getSerialNumber());
+ // Check if we are past the 'to' marker
+ if (toInt != null) {
+ if (rec.getSerialNumber().compareTo(toInt) > 0) {
+ break;
+ }
+ }
+ v.addElement(rec);
+ }
+ }
+
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ CMS.debug("returning "+v.size()+" elements");
+ return v.elements();
+ }
+
+ /**
+ * Retrives all valid certificates excluding ones already revoked.
+ */
+ public Enumeration getAllValidCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all valid not published certificates
+ * excluding ones already revoked.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getValidNotPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")(!(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true)))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all valid not published certificates
+ * excluding ones already revoked.
+ */
+ public Enumeration getAllValidNotPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")(!(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true)))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired certificates.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getExpiredCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")))";
+ //e = s.search(getDN(), ldapfilter);
+
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired certificates.
+ */
+ public Enumeration getAllExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired published certificates.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getExpiredPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ //DateMapper.dateToDB(now) + ")))";
+ DateMapper.dateToDB(now) + "))(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ //e = s.search(getDN(), ldapfilter);
+
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired publishedcertificates.
+ */
+ public Enumeration getAllExpiredPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&";
+
+ ldapfilter += "(!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public ICertRecordList getInvalidCertsByNotBeforeDate(Date date, int pageSize)
+ throws EBaseException {
+
+ String now = null;
+
+ Date rightNow = CMS.getCurrentDate();
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_INVALID + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_ID, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getInvalidCertificatesByNotBeforeDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ CMS.debug("getInvalidCertificatesByNotBeforeDate: about to call findCertRecordsInList");
+
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs,
+ DateMapper.dateToDB(date), "notBefore", pageSize);
+
+ //e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+
+ CMS.debug("In getInvalidCertsByNotBeforeDate finally.");
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+
+ }
+
+ public ICertRecordList getValidCertsByNotAfterDate(Date date, int pageSize)
+ throws EBaseException {
+
+ String now = null;
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_VALID + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_ID, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getValidCertsByNotAfterDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs, DateMapper.dateToDB(date), "notAfter", pageSize);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList getRevokedCertsByNotAfterDate(Date date, int pageSize)
+ throws EBaseException {
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_REVOKED_ON, CertRecord.ATTR_ID,
+ CertRecord.ATTR_REVO_INFO, CertificateValidity.NOT_AFTER, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getRevokedCertificatesByNotAfterDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ CMS.debug("getRevokedCertificatesByNotAfterDate: about to call findCertRecordsInList");
+
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs,
+ DateMapper.dateToDB(date), "notafter", pageSize);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+
+ }
+
+ /**
+ * Retrieves all revoked certificates in the serial number range.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getRevokedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ String ldapfilter = "(&(" + CertRecord.ATTR_REVO_INFO + "=*)";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + ">=" + from + ")";
+ if (to != null && to.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + "<=" + to + ")";
+ ldapfilter += ")";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked certificates including ones already expired or
+ * not yet valid.
+ */
+ public Enumeration getAllRevokedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))"; // index is setup for this filter
+
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves all revoked publishedcertificates in the serial number range.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getRevokedPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ String ldapfilter = "(&(" + CertRecord.ATTR_REVO_INFO + "=*)";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + ">=" + from + ")";
+ if (to != null && to.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + "<=" + to + ")";
+ //ldapfilter += ")";
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked published certificates including ones
+ * already expired or not yet valid.
+ */
+ public Enumeration getAllRevokedPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(&(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))"; // index is setup for this filter
+
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves all revoked certificates that have not expired.
+ */
+ public Enumeration getRevokedCertificates(Date asOfDate)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+
+ /*e = s.search(getDN(), "(&(" +
+ CertRecord.ATTR_REVO_INFO + "=*)(" + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + " >= " +
+ DateMapper.dateToDB(asOfDate) + "))");*/
+ String ldapfilter = "(&(" +
+ CertRecord.ATTR_REVO_INFO + "=*)(" + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + " >= " +
+ DateMapper.dateToDB(asOfDate) + "))";
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked certificates excluing ones already expired.
+ */
+ public Enumeration getAllRevokedNonExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")"; // index is setup for this filter
+
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ private LDAPSearchResults startSearchForModifiedCertificateRecords()
+ throws EBaseException {
+ CMS.debug("startSearchForModifiedCertificateRecords");
+ LDAPSearchResults r = null;
+ IDBSSession s = mDBService.createSession();
+
+ String filter = "(" + CertRecord.ATTR_CERT_STATUS + "=*)";
+ try {
+ r = s.persistentSearch(getDN(), filter, null);
+ CMS.debug("startSearchForModifiedCertificateRecords persistentSearch started");
+ } catch (Exception e) {
+ CMS.debug("startSearchForModifiedCertificateRecords persistentSearch Exception="+e);
+ r = null;
+ if (s != null)
+ s.close();
+ }
+ return r;
+ }
+
+ public void getModifications(LDAPEntry entry) {
+ if (entry != null) {
+ CMS.debug("getModifications entry DN="+entry.getDN());
+
+ LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+ ICertRecord certRec = null;
+ try {
+ certRec = (ICertRecord)mDBService.getRegistry().createObject(entryAttrs);
+ } catch (Exception e) {
+ }
+ if (certRec != null) {
+ String status = certRec.getStatus();
+ CMS.debug("getModifications serialNumber="+certRec.getSerialNumber()+
+ " status="+status);
+ if (status != null && (status.equals(ICertRecord.STATUS_VALID) ||
+ status.equals(ICertRecord.STATUS_REVOKED))) {
+
+ Enumeration eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) eIPs.nextElement();
+
+ if (ip != null) {
+ if (status.equals(ICertRecord.STATUS_REVOKED)) {
+ IRevocationInfo rInfo = certRec.getRevocationInfo();
+ if (rInfo != null) {
+ ip.addRevokedCert(certRec.getSerialNumber(),
+ new RevokedCertImpl(certRec.getSerialNumber(),
+ rInfo.getRevocationDate(),
+ rInfo.getCRLEntryExtensions()));
+ }
+ } else {
+ ip.addUnrevokedCert(certRec.getSerialNumber());
+ }
+ }
+ }
+
+ }
+ }
+ } else {
+ CMS.debug("getModifications entry == null");
+ }
+ }
+
+
+ /**
+ * Checks if the presented certificate belongs to the repository
+ * and is revoked.
+ *
+ * @param cert certificate to verify.
+ * @return RevocationInfo if the presented certificate is revoked otherwise null.
+ */
+ public RevocationInfo isCertificateRevoked(X509CertImpl cert)
+ throws EBaseException {
+ RevocationInfo info = null;
+
+ // 615932
+ if (cert == null)
+ return null;
+
+ ICertRecord rec = readCertificateRecord(cert.getSerialNumber());
+
+ if (rec != null) {
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ X500Name name = (X500Name) cert.getSubjectDN();
+ X500Name repCertName = (X500Name) rec.getCertificate().getSubjectDN();
+
+ if (name.equals(repCertName)) {
+ byte[] certEncoded = null;
+ byte[] repCertEncoded = null;
+
+ try {
+ certEncoded = cert.getEncoded();
+ repCertEncoded = rec.getCertificate().getEncoded();
+ } catch (Exception e) {
+ }
+
+ if (certEncoded != null &&
+ repCertEncoded != null &&
+ certEncoded.length == repCertEncoded.length) {
+ int i;
+
+ for (i = 0; i < certEncoded.length; i++) {
+ if (certEncoded[i] != repCertEncoded[i])
+ break;
+ }
+ if (i >= certEncoded.length) {
+ info = (RevocationInfo) ((CertRecord) rec).getRevocationInfo();
+ }
+ }
+ }
+ }
+ }
+
+ return info;
+ }
+
+ public void shutdown() {
+ if (mCertStatusUpdateThread != null)
+ mCertStatusUpdateThread.destroy();
+
+ if (mRetrieveModificationsThread != null)
+ mRetrieveModificationsThread.destroy();
+ }
+}
+
+
+class CertStatusUpdateThread extends Thread {
+ CertificateRepository _cr = null;
+ IRepository _rr = null;
+ int _interval;
+
+ CertStatusUpdateThread(CertificateRepository cr, IRepository rr, String name) {
+ super(name);
+ CMS.debug("new CertStatusUpdateThread");
+ //setName(name);
+
+ _cr = cr;
+ _rr = rr;
+ }
+
+ public void setInterval(int interval) {
+ _interval = interval;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of CertStatusUpdateThread");
+
+ while (true) {
+ try {
+ // block the update while another thread
+ // (such as the CRL Update) is running
+ CMS.debug("About to start updateCertStatus");
+ synchronized (_cr.mCertStatusUpdateThread) {
+ CMS.debug("Starting updateCertStatus (entered lock)");
+ _cr.updateCertStatus();
+ CMS.debug("updateCertStatus done");
+
+ CMS.debug("Starting cert checkRanges");
+ _cr.checkRanges();
+ CMS.debug("cert checkRanges done");
+
+ CMS.debug("Starting request checkRanges");
+ _rr.checkRanges();
+ CMS.debug("request checkRanges done");
+ }
+
+ } catch (Exception e) {
+ CMS.debug("updateCertStatus done: " + e.toString());
+ }
+ try {
+ sleep(_interval * 1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
+
+
+class RetrieveModificationsThread extends Thread {
+ CertificateRepository _cr = null;
+ LDAPSearchResults _results = null;
+
+ RetrieveModificationsThread(CertificateRepository cr, String name) {
+ super(name);
+ CMS.debug("new RetrieveModificationsThread");
+ //setName(name);
+
+ _cr = cr;
+ }
+
+ public void setResults(LDAPSearchResults results) {
+ _results = results;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of RetrieveModificationsThread");
+
+ if (_results != null) {
+ try {
+ while (_results.hasMoreElements()) {
+ LDAPEntry entry = _results.next();
+ _cr.getModifications(entry);
+ }
+ } catch (LDAPException e) {
+ CMS.debug("LDAPException: "+e.toString());
+ }
+ } else {
+ CMS.debug("_results are null");
+ }
+ CMS.debug("Done with run method of RetrieveModificationsThread");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
new file mode 100644
index 000000000..660e385fe
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
@@ -0,0 +1,553 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a registry where all the
+ * schema (object classes and attribute) information
+ * is stored.
+ *
+ * Attribute mappers can be registered with this
+ * registry.
+ *
+ * Given the schema information stored, this registry
+ * has knowledge to convert a Java object into a
+ * LDAPAttributeSet or vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBRegistry implements IDBRegistry, ISubsystem {
+
+ private IConfigStore mConfig = null;
+ private Hashtable mOCclassNames = new Hashtable();
+ private Hashtable mOCldapNames = new Hashtable();
+ private Hashtable mAttrufNames = new Hashtable();
+ private IFilterConverter mConverter = null;
+ private Vector mDynAttrMappers = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs registry.
+ */
+ public DBRegistry() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return "dbsregistry";
+ }
+
+ /**
+ * Sets subsystem identifier. This is an internal
+ * subsystem, and is not loadable.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Initializes the internal registery. Connects to the
+ * data source, and create a pool of connection of which
+ * applications can use. Optionally, check the integrity
+ * of the database.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ mConverter = new LdapFilterConverter(mAttrufNames);
+ }
+
+ /**
+ * Retrieves configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Starts up this subsystem.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shutdowns this subsystem gracefully.
+ */
+ public void shutdown() {
+ mOCclassNames.clear();
+ mOCclassNames = null;
+ mOCldapNames.clear();
+ mOCldapNames = null;
+ mAttrufNames.clear();
+ mAttrufNames = null;
+ mConverter = null;
+ }
+
+ /**
+ * Registers object class.
+ */
+ public void registerObjectClass(String className, String ldapNames[])
+ throws EDBException {
+ try {
+ Class c = Class.forName(className);
+
+ mOCclassNames.put(className, ldapNames);
+ mOCldapNames.put(sortAndConcate(
+ ldapNames).toLowerCase(),
+ new NameAndObject(className, c));
+ } catch (ClassNotFoundException e) {
+
+ /*LogDoc
+ *
+ * @phase db startup
+ * @reason failed to register object class
+ * @message DBRegistry: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_CLASS_NAME", className));
+ }
+ }
+
+ /**
+ * See if an object class is registered.
+ */
+ public boolean isObjectClassRegistered(String className) {
+ return mOCclassNames.containsKey(className);
+ }
+
+ /**
+ * Registers attribute mapper.
+ */
+ public void registerAttribute(String ufName, IDBAttrMapper mapper)
+ throws EDBException {
+ // should not allows 'objectclass' as attribute; it has
+ // special meaning
+ mAttrufNames.put(ufName.toLowerCase(), mapper);
+ }
+
+ /**
+ * See if an attribute is registered.
+ */
+ public boolean isAttributeRegistered(String ufName) {
+ return mAttrufNames.containsKey(ufName.toLowerCase());
+ }
+
+ public void registerDynamicMapper(IDBDynAttrMapper mapper) {
+ mDynAttrMappers.add(mapper);
+ }
+
+ /**
+ * Creates LDAP-based search filters with help of
+ * registered mappers.
+ * Parses filter from filter string specified in RFC1558.
+ * <pre>
+ * <filter> ::= '(' <filtercomp> ')'
+ * <filtercomp> ::= <and> | <or> | <not> | <item>
+ * <and> ::= '&' <filterlist>
+ * <or> ::= '|' <filterlist>
+ * <not> ::= '!' <filter>
+ * <filterlist> ::= <filter> | <filter> <filterlist>
+ * <item> ::= <simple> | <present> | <substring>
+ * <simple> ::= <attr> <filtertype> <value>
+ * <filtertype> ::= <equal> | <approx> | <greater> | <less>
+ * <equal> ::= '='
+ * <approx> ::= '~='
+ * <greater> ::= '>='
+ * <less> ::= '<='
+ * <present> ::= <attr> '=*'
+ * <substring> ::= <attr> '=' <initial> <any> <final>
+ * <initial> ::= NULL | <value>
+ * <any> ::= '*' <starval>
+ * <starval> ::= NULL | <value> '*' <starval>
+ * <final> ::= NULL | <value>
+ * </pre>
+ */
+ public String getFilter(String filter) throws EBaseException {
+ return getFilter(filter, mConverter);
+ }
+
+ public String getFilter(String filter, IFilterConverter c)
+ throws EBaseException {
+ String f = filter;
+
+ f = f.trim();
+ if (f.startsWith("(") && f.endsWith(")")) {
+ return "(" + getFilterComp(f.substring(1,
+ f.length() - 1), c) + ")";
+ } else {
+ return getFilterComp(filter, c);
+ }
+ }
+
+ private String getFilterComp(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ if (f.startsWith("&")) { // AND operation
+ return "&" + getFilterList(f.substring(1,
+ f.length()), c);
+ } else if (f.startsWith("|")) { // OR operation
+ return "|" + getFilterList(f.substring(1,
+ f.length()), c);
+ } else if (f.startsWith("!")) { // NOT operation
+ return "!" + getFilter(f.substring(1, f.length()), c);
+ } else { // item
+ return getFilterItem(f, c);
+ }
+ }
+
+ private String getFilterList(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ int level = 0;
+ int start = 0;
+ int end = 0;
+ Vector v = new Vector();
+
+ for (int i = 0; i < f.length(); i++) {
+ if (f.charAt(i) == '(') {
+ if (level == 0) {
+ start = i;
+ }
+ level++;
+ }
+ if (f.charAt(i) == ')') {
+ level--;
+ if (level == 0) {
+ end = i;
+ String filter = getFilter(f.substring(start, end + 1), c);
+
+ v.addElement(filter);
+ }
+ }
+ }
+ String result = "";
+
+ for (int i = 0; i < v.size(); i++) {
+ result += (String) v.elementAt(i);
+ }
+ return result;
+ }
+
+ /**
+ * So, here we need to separate item into name, op, value.
+ */
+ private String getFilterItem(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ int idx = f.indexOf('=');
+
+ if (idx == -1) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_FILTER_ITEM", "="));
+ }
+
+ String type = f.substring(0, idx).trim();
+ String value = f.substring(idx + 1).trim(); // skip '='
+
+ // make decision by looking at the type
+ type = type.trim();
+ if (type.endsWith("~")) {
+ // approximate match
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "~=", value);
+ } else if (type.endsWith("!")) {
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "!=", value);
+ } else if (type.endsWith(">")) {
+ // greater than
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, ">=", value);
+ } else if (type.endsWith("<")) {
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "<=", value);
+ }
+
+ // for those that are not simple
+ if (value.startsWith("*") && value.length() == 1) {
+ return c.convert(type, "=", "*");
+ }
+
+ // if value contains no '*', then it is equality
+ if (value.indexOf('*') == -1) {
+ if (type.equals("objectclass")) {
+ String ldapNames[] = (String[])
+ mOCclassNames.get(value);
+
+ if (ldapNames == null)
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_FILTER_ITEM", f));
+ String filter = "";
+
+ for (int g = 0; g < ldapNames.length; g++) {
+ filter += "(objectclass=" +
+ ldapNames[g] + ")";
+ }
+ return "&" + filter;
+ } else {
+ return c.convert(type, "=", value);
+ }
+ }
+ // XXX - does not support substring!!
+ return c.convert(type, "=", value);
+ }
+
+ /**
+ * Maps object into LDAP attribute set.
+ */
+ public void mapObject(IDBObj parent, String name, Object obj,
+ LDAPAttributeSet attrs) throws EBaseException {
+ IDBAttrMapper mapper = (IDBAttrMapper) mAttrufNames.get(
+ name.toLowerCase());
+
+ if (mapper == null) {
+ return; // no mapper found, just skip this attribute
+ }
+ mapper.mapObjectToLDAPAttributeSet(parent, name, obj, attrs);
+ }
+
+ /**
+ * Retrieves a list of LDAP attributes that are associated
+ * with the given attributes.
+ * This method is used for searches, to map the database attributes
+ * to LDAP attributes.
+ */
+ public String[] getLDAPAttributes(String attrs[])
+ throws EBaseException {
+ IDBAttrMapper mapper;
+
+ if (attrs == null)
+ return null;
+ Vector v = new Vector();
+
+ for (int i = 0; i < attrs.length; i++) {
+
+ if (attrs[i].equals("objectclass")) {
+ v.addElement("objectclass");
+ continue;
+ }
+
+ if (isAttributeRegistered(attrs[i])) {
+ mapper = (IDBAttrMapper)
+ mAttrufNames.get(attrs[i].toLowerCase());
+ if (mapper == null) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INVALID_ATTRS"));
+ }
+ Enumeration e = mapper.getSupportedLDAPAttributeNames();
+
+ while (e.hasMoreElements()) {
+ String s = (String) e.nextElement();
+
+ if (!v.contains(s)) {
+ v.addElement(s);
+ }
+ }
+ } else {
+ IDBDynAttrMapper matchingDynAttrMapper = null;
+ // check if a dynamic mapper can handle the attribute
+ for (Iterator dynMapperIter = mDynAttrMappers.iterator();
+ dynMapperIter.hasNext();) {
+ IDBDynAttrMapper dynAttrMapper =
+ (IDBDynAttrMapper)dynMapperIter.next();
+ if (dynAttrMapper.supportsLDAPAttributeName(attrs[i])) {
+ matchingDynAttrMapper = dynAttrMapper;
+ break;
+ }
+ }
+ if (matchingDynAttrMapper != null) {
+ v.addElement(attrs[i]);
+ } else {
+ /*LogDoc
+ *
+ * @phase retrieve ldap attr
+ * @reason failed to get registered object class
+ * @message DBRegistry: <attr> is not registered
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i]));
+ throw new EDBException(CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i]));
+ }
+ }
+
+ }
+ if (v.size() == 0)
+ return null;
+ String ldapAttrs[] = new String[v.size()];
+
+ v.copyInto(ldapAttrs);
+ return ldapAttrs;
+ }
+
+ /**
+ * Creates attribute set from object.
+ */
+ public LDAPAttributeSet createLDAPAttributeSet(IDBObj obj)
+ throws EBaseException {
+ Enumeration e = obj.getSerializableAttrNames();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ // add object class to attribute set
+ String className = ((Object) obj).getClass().getName();
+ String vals[] = (String[]) mOCclassNames.get(className);
+
+ attrs.add(new LDAPAttribute("objectclass", vals));
+
+ // give every attribute a chance to put stuff in attr set
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (obj.get(name) != null) {
+ mapObject(obj, name, obj.get(name), attrs);
+ }
+ }
+ return attrs;
+ }
+
+ /**
+ * Creates object from attribute set.
+ */
+ public IDBObj createObject(LDAPAttributeSet attrs)
+ throws EBaseException {
+ // map object class attribute to object
+ LDAPAttribute attr = attrs.getAttribute("objectclass");
+
+ //CMS.debug("createObject: attrs " + attrs.toString());
+
+ attrs.remove("objectclass");
+
+ // sort the object class values
+ Enumeration vals = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (vals.hasMoreElements()) {
+ v.addElement(vals.nextElement());
+ }
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ String sorted = sortAndConcate(s).toLowerCase();
+ NameAndObject no = (NameAndObject) mOCldapNames.get(sorted);
+
+ if (no == null) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_CLASS_NAME", sorted));
+ }
+ Class c = (Class) no.getObject();
+
+ try {
+ IDBObj obj = (IDBObj) c.newInstance();
+ Enumeration ee = obj.getSerializableAttrNames();
+
+ while (ee.hasMoreElements()) {
+ String oname = (String) ee.nextElement();
+ IDBAttrMapper mapper = (IDBAttrMapper)
+ mAttrufNames.get(
+ oname.toLowerCase());
+
+ if (mapper == null) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_NO_MAPPER_FOUND", oname));
+ }
+ mapper.mapLDAPAttributeSetToObject(attrs,
+ oname, obj);
+ }
+ return obj;
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase create ldap attr
+ * @reason failed to create object class
+ * @message DBRegistry: <attr> is not registered
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INVALID_ATTRS"));
+ }
+ }
+
+ /**
+ * Sorts and concate given strings.
+ */
+ private String sortAndConcate(String s[]) {
+ Vector v = new Vector();
+
+ // sort it first
+ for (int i = 0; i < s.length; i++) {
+ for (int j = 0; j < v.size(); j++) {
+ String t = (String) v.elementAt(j);
+
+ if (s[i].compareTo(t) < 0) {
+ v.insertElementAt(s[i], j);
+ break;
+ }
+ }
+ if (i != (v.size() - 1))
+ v.addElement(s[i]);
+ }
+
+ // concate them
+ String result = "";
+
+ for (int i = 0; i < v.size(); i++) {
+ result += ((String) v.elementAt(i) + "+");
+ }
+ return result;
+ }
+}
+
+
+/**
+ * Just a convenient container class.
+ */
+class NameAndObject {
+
+ private String mN = null;
+ private Object mO = null;
+
+ public NameAndObject(String name, Object o) {
+ mN = name;
+ mO = o;
+ }
+
+ public String getName() {
+ return mN;
+ }
+
+ public Object getObject() {
+ return mO;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
new file mode 100644
index 000000000..03c86a219
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
@@ -0,0 +1,447 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.controls.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents the database session. Operations
+ * can be performed with a session.
+ *
+ * Transaction and Caching support can be integrated
+ * into session.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSSession implements IDBSSession {
+
+ private IDBSubsystem mDBSystem = null;
+ private LDAPConnection mConn = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a database session.
+ *
+ * @param system the database subsytem
+ * @param c the ldap connection
+ */
+ public DBSSession(IDBSubsystem system, LDAPConnection c) {
+ mDBSystem = system;
+ mConn = c;
+ try {
+ // no limit
+ mConn.setOption(LDAPv2.SIZELIMIT, Integer.valueOf(0));
+ } catch (LDAPException e) {
+ }
+ }
+
+ /**
+ * Returns database subsystem.
+ */
+ public ISubsystem getDBSubsystem() {
+ return mDBSystem;
+ }
+
+ /**
+ * Closes this session.
+ */
+ public void close() throws EDBException {
+ // return ldap connection.
+ mDBSystem.returnConn(mConn);
+ }
+
+ /**
+ * Adds object to backend database. For example,
+ * <PRE>
+ * session.add("cn=123459,o=certificate repository,o=airius.com",
+ * certRec);
+ * </PRE>
+ *
+ * @param name the name of the ldap entry
+ * @param obj the DBobj that can be mapped to ldap attrubute set
+ */
+ public void add(String name, IDBObj obj) throws EBaseException {
+ try {
+ LDAPAttributeSet attrs = mDBSystem.getRegistry(
+ ).createLDAPAttributeSet(obj);
+ LDAPEntry e = new LDAPEntry(name, attrs);
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP add <entry>
+ */
+ mConn.add(e);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Reads an object from the database.
+ * all attributes will be returned
+ *
+ * @param name the name of the ldap entry
+ */
+ public IDBObj read(String name) throws EBaseException {
+ return read(name, null);
+ }
+
+ /**
+ * Reads an object from the database, and only populates
+ * the selected attributes.
+ *
+ * @param name the name of the ldap entry
+ * @param attrs the attributes to be selected
+ */
+ public IDBObj read(String name, String attrs[])
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+
+ /*LogDoc
+ *
+ * @phase local ldap read
+ * @message DBSSession: begin LDAP read <entry>
+ */
+ LDAPSearchResults res = mConn.search(name,
+ LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ ldapattrs, false);
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ return mDBSystem.getRegistry().createObject(
+ entry.getAttributeSet());
+ } catch (LDAPException e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap read
+ * @message DBSSession: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_INFO, "DBSSession: " + e.toString());
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT)
+ throw new EDBRecordNotFoundException(
+ CMS.getUserMessage("CMS_DBS_RECORD_NOT_FOUND"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Deletes object from database.
+ */
+ public void delete(String name) throws EBaseException {
+ try {
+ mConn.delete(name);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Modify an object in the database.
+ */
+ public void modify(String name, ModificationSet mods)
+ throws EBaseException {
+ try {
+ LDAPModificationSet ldapMods = new
+ LDAPModificationSet();
+ Enumeration e = mods.getModifications();
+
+ while (e.hasMoreElements()) {
+ Modification mod = (Modification)
+ e.nextElement();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ mDBSystem.getRegistry().mapObject(null,
+ mod.getName(), mod.getValue(), attrs);
+ Enumeration e0 = attrs.getAttributes();
+
+ while (e0.hasMoreElements()) {
+ ldapMods.add(toLdapModOp(mod.getOp()),
+ (LDAPAttribute)
+ e0.nextElement());
+ }
+ }
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP modify <entry>
+ */
+ mConn.modify(name, ldapMods);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ private int toLdapModOp(int modOp) throws EBaseException {
+ switch (modOp) {
+ case Modification.MOD_ADD:
+ return LDAPModification.ADD;
+
+ case Modification.MOD_DELETE:
+ return LDAPModification.DELETE;
+
+ case Modification.MOD_REPLACE:
+ return LDAPModification.REPLACE;
+ }
+ throw new EBaseException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ Integer.toString(modOp)));
+ }
+
+ /**
+ * Searchs for a list of objects that match the
+ * filter.
+ */
+ public IDBSearchResults search(String base, String filter)
+ throws EBaseException {
+ return search(base, filter, null);
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize)
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(maxSize);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(maxSize);
+ cons.setServerTimeLimit(timeLimit);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Retrieves a list of object that satifies the given
+ * filter.
+ */
+ public IDBSearchResults search(String base, String filter,
+ String attrs[]) throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP search <filter>
+ */
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(0);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ public LDAPSearchResults persistentSearch(String base, String filter, String attrs[])
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ Integer version = (Integer)(mConn.getOption(LDAPv2.PROTOCOL_VERSION));
+
+ // Only version 3 protocol supports persistent search.
+ if (version.intValue() == 2) {
+ mConn.setOption(LDAPv2.PROTOCOL_VERSION, Integer.valueOf(3));
+ }
+
+ int op = LDAPPersistSearchControl.MODIFY;
+
+ boolean changesOnly = true;
+ boolean returnControls = true;
+ boolean isCritical = true;
+ LDAPPersistSearchControl persistCtrl = new
+ LDAPPersistSearchControl( op, changesOnly,
+ returnControls, isCritical );
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+ cons.setBatchSize(0);
+ cons.setServerControls( persistCtrl );
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+ return res;
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[]) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey[]) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey[], int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String startFrom, String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, startFrom, sortKey, pageSize);
+
+ }
+
+ /**
+ * Releases object to this interface. This allows us to
+ * use memory more efficiently.
+ */
+ public void release(Object obj) {
+ // not implemented
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java
new file mode 100644
index 000000000..475a77dcb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java
@@ -0,0 +1,56 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java BigInteger object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSUtil {
+
+ public static String longToDB(long val) {
+ String s = Long.toString(val);
+ // prefix with 2 digits that represents
+ // the length of the value
+ int l = s.length();
+ String dbVal = "";
+
+ if (s.length() < 10) {
+ dbVal = "0";
+ }
+ return dbVal + Integer.toString(l) + s;
+ }
+
+ public static long longFromDB(String dbLong) {
+ // remove the first 2 digits
+ String s = dbLong.substring(2);
+
+ return Long.parseLong(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java
new file mode 100644
index 000000000..b7f6cd616
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java
@@ -0,0 +1,92 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents the search results. A search
+ * results object contain a enumeration of
+ * Java objects that are just read from the database.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSearchResults implements IDBSearchResults {
+
+ private IDBRegistry mRegistry = null;
+ private Enumeration mRes = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs search results.
+ */
+ public DBSearchResults(IDBRegistry registry, Enumeration res) {
+ mRegistry = registry;
+ mRes = res;
+ }
+
+ /**
+ * Checks if any element is available.
+ */
+ public boolean hasMoreElements() {
+ return mRes.hasMoreElements();
+ }
+
+ /**
+ * Retrieves next element.
+ */
+ public Object nextElement() {
+ LDAPEntry entry = null;
+
+ try {
+ Object o = mRes.nextElement();
+
+ if (o instanceof LDAPEntry) {
+ entry = (LDAPEntry) o;
+ return mRegistry.createObject(entry.getAttributeSet());
+ } else {
+ if (o instanceof LDAPException)
+ ;
+ // doing nothing because the last object in the search
+ // results is always LDAPException
+ else
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, "DBSearchResults: result format error class=" + o.getClass().getName());
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason failed to get next element
+ * @message DBSearchResults: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, "DBSearchResults: " + e.toString());
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
new file mode 100644
index 000000000..797dd8324
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
@@ -0,0 +1,951 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents the database subsystem that manages
+ * the backend data storage.
+ *
+ * This subsystem maintains multiple sessions that allows
+ * operations to be performed, and provide a registry
+ * where all the schema information is stored.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSubsystem implements IDBSubsystem {
+
+ public static String ID = IDBSubsystem.SUB_ID;
+
+ private IConfigStore mConfig = null;
+ private IConfigStore mDBConfig = null;
+ private LdapBoundConnFactory mLdapConnFactory = null;
+ private DBRegistry mRegistry = null;
+ private String mBaseDN = null;
+ private ISubsystem mOwner = null;
+
+ private Hashtable[] mRepos = null;
+
+ private BigInteger mNextSerialConfig = null;
+ private boolean mEnableSerialMgmt = false;
+
+ private static final String PEOPLE_DN = "ou=people";
+ private static final String GROUPS_DN = "ou=groups";
+ private static final String REQUESTS_DN = "ou=requests";
+ private static final String XCERTS_DN = "cn=crossCerts";
+ private static final String BASEDN = "o=netscapeCertificateServer";
+ private static final String DEFAULT_DATABASE = "userRoot";
+ private static final String AT_OC = "objectclass";
+ private static final String AT_O = "o";
+ private static final String AT_OU = "ou";
+ private static final String CA_DN = "ou=ca";
+ private static final String CR_DN = "ou=certificateRepository, ou=ca";
+ private static final String CRL_DN = "ou=crlIssuingPoints, ou=ca";
+ private static final String CA_REQUESTS_DN = "ou=ca, ou=requests";
+ private static final String KRA_DN = "ou=kra";
+ private static final String KR_DN = "ou=keyRepository, ou=kra";
+ private static final String KRA_REQUESTS_DN = "ou=kra, ou=requests";
+ private static final String REPLICA_DN = "ou=replica";
+ private static final String PROP_ENABLE_SERIAL_NUMBER_RECOVERY =
+ "enableSerialNumberRecovery";
+ // This value is only equal to the next Serial number that the CA's
+ // going to issue when cms just start up or it's just set from console.
+ // It doesn't record the next serial number at other time when cms's
+ // runing not to increase overhead when issuing certs.
+ private static final String PROP_NEXT_SERIAL_NUMBER =
+ "nextSerialNumber";
+ private static final String PROP_MIN_SERIAL_NUMBER="beginSerialNumber";
+ private static final String PROP_MAX_SERIAL_NUMBER = "endSerialNumber";
+ private static final String PROP_NEXT_MIN_SERIAL_NUMBER="nextBeginSerialNumber";
+ private static final String PROP_NEXT_MAX_SERIAL_NUMBER ="nextEndSerialNumber";
+ private static final String PROP_SERIAL_LOW_WATER_MARK="serialLowWaterMark";
+ private static final String PROP_SERIAL_INCREMENT="serialIncrement";
+ private static final String PROP_SERIAL_BASEDN="serialDN";
+ private static final String PROP_SERIAL_RANGE_DN="serialRangeDN";
+
+ private static final String PROP_MIN_REQUEST_NUMBER="beginRequestNumber";
+ private static final String PROP_MAX_REQUEST_NUMBER="endRequestNumber";
+ private static final String PROP_NEXT_MIN_REQUEST_NUMBER="nextBeginRequestNumber";
+ private static final String PROP_NEXT_MAX_REQUEST_NUMBER="nextEndRequestNumber";
+ private static final String PROP_REQUEST_LOW_WATER_MARK="requestLowWaterMark";
+ private static final String PROP_REQUEST_INCREMENT="requestIncrement";
+ private static final String PROP_REQUEST_BASEDN="requestDN";
+ private static final String PROP_REQUEST_RANGE_DN="requestRangeDN";
+
+ private static final String PROP_MIN_REPLICA_NUMBER="beginReplicaNumber";
+ private static final String PROP_MAX_REPLICA_NUMBER = "endReplicaNumber";
+ private static final String PROP_NEXT_MIN_REPLICA_NUMBER="nextBeginReplicaNumber";
+ private static final String PROP_NEXT_MAX_REPLICA_NUMBER ="nextEndReplicaNumber";
+ private static final String PROP_REPLICA_LOW_WATER_MARK="replicaLowWaterMark";
+ private static final String PROP_REPLICA_INCREMENT="replicaIncrement";
+ private static final String PROP_REPLICA_BASEDN="replicaDN";
+ private static final String PROP_REPLICA_RANGE_DN="replicaRangeDN";
+
+ private static final String PROP_INFINITE_SERIAL_NUMBER = "1000000000";
+ private static final String PROP_INFINITE_REQUEST_NUMBER = "1000000000";
+ private static final String PROP_INFINITE_REPLICA_NUMBER = "1000";
+ private static final String PROP_BASEDN = "basedn";
+ private static final String PROP_LDAP = "ldap";
+ private static final String PROP_NEXT_RANGE = "nextRange";
+ private static final String PROP_ENABLE_SERIAL_MGMT = "enableSerialManagement";
+
+ // hash keys
+ private static final String NAME="name";
+ private static final String PROP_MIN="min";
+ private static final String PROP_MIN_NAME="min_name";
+ private static final String PROP_MAX = "max";
+ private static final String PROP_MAX_NAME = "max_name";
+ private static final String PROP_NEXT_MIN="next_min";
+ private static final String PROP_NEXT_MIN_NAME="next_min_name";
+ private static final String PROP_NEXT_MAX = "next_max";
+ private static final String PROP_NEXT_MAX_NAME = "next_max_name";
+ private static final String PROP_LOW_WATER_MARK="lowWaterMark";
+ private static final String PROP_LOW_WATER_MARK_NAME="lowWaterMark_name";
+ private static final String PROP_INCREMENT = "increment";
+ private static final String PROP_INCREMENT_NAME = "increment_name";
+ private static final String PROP_RANGE_DN="rangeDN";
+
+ private static final BigInteger BI_ONE = new BigInteger("1");
+
+ private ILogger mLogger = null;
+
+ // singleton enforcement
+
+ private static IDBSubsystem mInstance = new DBSubsystem();
+
+ public static IDBSubsystem getInstance() {
+ return mInstance;
+ }
+
+ /**
+ * This method is used for unit tests. It allows the underlying instance
+ * to be stubbed out.
+ * @param dbSubsystem The stubbed out subsystem to override with.
+ */
+ public static void setInstance(IDBSubsystem dbSubsystem) {
+ mInstance = dbSubsystem;
+ }
+
+ // end singleton enforcement.
+
+ /**
+ * Constructs database subsystem.
+ */
+ private DBSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return IDBSubsystem.SUB_ID;
+ }
+
+ /**
+ * Sets subsystem identifier.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ public boolean enableSerialNumberRecovery() {
+ try {
+ return mDBConfig.getBoolean(
+ PROP_ENABLE_SERIAL_NUMBER_RECOVERY, true);
+ } catch (EBaseException e) {
+ // by default
+ return true;
+ }
+ }
+
+ public boolean getEnableSerialMgmt() {
+ return mEnableSerialMgmt;
+ }
+
+ public void setEnableSerialMgmt(boolean v)
+ throws EBaseException {
+ if (v) {
+ CMS.debug("DBSubsystem: Enabling Serial Number Management");
+ } else {
+ CMS.debug("DBSubsystem: Disabling Serial Number Management");
+ }
+
+ mDBConfig.putBoolean(PROP_ENABLE_SERIAL_MGMT, v);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ mEnableSerialMgmt = v;
+ }
+
+ public BigInteger getNextSerialConfig() {
+ return mNextSerialConfig;
+ }
+
+ public void setNextSerialConfig(BigInteger serial)
+ throws EBaseException {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_INFO, "DBSubsystem: " +
+ "Setting next serial number: 0x" + serial.toString(16));
+ mDBConfig.putString(PROP_NEXT_SERIAL_NUMBER,
+ serial.toString(16));
+ }
+
+ /**
+ * Gets minimum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number
+ */
+ public String getMinSerialConfig(int repo)
+ {
+ return (String) (mRepos[repo]).get(PROP_MIN);
+ }
+
+ /**
+ * Gets maximum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number
+ */
+ public String getMaxSerialConfig(int repo) {
+ return (String) (mRepos[repo]).get(PROP_MAX);
+ }
+
+ /**
+ * Gets minimum serial number limit in next range in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number in next range
+ */
+ public String getNextMinSerialConfig(int repo)
+ {
+ String ret = (String) (mRepos[repo]).get(PROP_NEXT_MIN);
+ if (ret.equals("-1")) {
+ return null;
+ }
+ else {
+ return ret;
+ }
+ }
+
+ /**
+ * Gets maximum serial number limit in next range in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number in next range
+ */
+ public String getNextMaxSerialConfig(int repo) {
+ String ret = (String) (mRepos[repo]).get(PROP_NEXT_MAX);
+ if (ret.equals("-1")) {
+ return null;
+ }
+ else {
+ return ret;
+ }
+ }
+
+ /**
+ * Gets low water mark limit in config file
+ *
+ * @param repo repo identifier
+ * @return low water mark
+ */
+ public String getLowWaterMarkConfig(int repo) {
+ return (String) (mRepos[repo]).get(PROP_LOW_WATER_MARK);
+ }
+
+ /**
+ * Gets range increment for next range in config file
+ *
+ * @param repo repo identifier
+ * @return range increment
+ */
+ public String getIncrementConfig(int repo)
+ {
+ return (String) (mRepos[repo]).get(PROP_INCREMENT);
+ }
+
+ /**
+ * Sets maximum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @param serial max serial number
+ * @exception EBaseException failed to set
+ */
+ public void setMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ CMS.debug("DBSubsystem: Setting max serial number for " + h.get(NAME) + ": " + serial);
+
+ //persist to file
+ mDBConfig.putString((String) h.get(PROP_MAX_NAME), serial);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+
+ h.put(PROP_MAX, serial);
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets minimum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @param serial min serial number
+ * @exception EBaseException failed to set
+ */
+ public void setMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ CMS.debug("DBSubsystem: Setting min serial number for " + h.get(NAME) + ": " + serial);
+
+ //persist to file
+ mDBConfig.putString((String) h.get(PROP_MIN_NAME), serial);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+
+ h.put(PROP_MIN, serial);
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets maximum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @param serial max serial number for next range
+ * @exception EBaseException failed to set
+ */
+ public void setNextMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ if (serial == null) {
+ CMS.debug("DBSubsystem: Removing next max " + h.get(NAME) + " number");
+ mDBConfig.remove((String) h.get(PROP_NEXT_MAX_NAME));
+ } else {
+ CMS.debug("DBSubsystem: Setting next max " + h.get(NAME) + " number: " + serial);
+ mDBConfig.putString((String) h.get(PROP_NEXT_MAX_NAME), serial);
+ }
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ if (serial == null) {
+ Object o2 = h.remove(PROP_NEXT_MAX);
+ } else {
+ h.put(PROP_NEXT_MAX, serial);
+ }
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets minimum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @param serial min serial number for next range
+ * @exception EBaseException failed to set
+ */
+ public void setNextMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ if (serial == null) {
+ CMS.debug("DBSubsystem: Removing next min " + h.get(NAME) + " number");
+ mDBConfig.remove((String) h.get(PROP_NEXT_MIN_NAME));
+ } else {
+ CMS.debug("DBSubsystem: Setting next min " + h.get(NAME) + " number: " + serial);
+ mDBConfig.putString((String) h.get(PROP_NEXT_MIN_NAME), serial);
+ }
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ if (serial == null) {
+ Object o2 = h.remove(PROP_NEXT_MIN);
+ } else {
+ h.put(PROP_NEXT_MIN, serial);
+ }
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Gets start of next range from database.
+ * Increments the nextRange attribute and allocates
+ * this range to the current instance by creating a pkiRange object.
+ *
+ * @param repo repo identifier
+ * @return start of next range
+ */
+ public String getNextRange(int repo) {
+ LDAPConnection conn = null;
+ String nextRange = null;
+ try {
+ Hashtable h = mRepos[repo];
+ conn = mLdapConnFactory.getConn();
+ String dn = (String) h.get(PROP_BASEDN) + "," + mBaseDN;
+ String rangeDN = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN;
+
+ LDAPEntry entry = conn.read(dn);
+ LDAPAttribute attr = entry.getAttribute(PROP_NEXT_RANGE);
+ nextRange = (String) attr.getStringValues().nextElement();
+
+ BigInteger nextRangeNo = new BigInteger(nextRange);
+ if (nextRangeNo == null) {
+ throw new EBaseException("nextRangeNo is null!");
+ }
+
+ BigInteger incrementNo = new BigInteger((String) h.get(PROP_INCREMENT));
+ if (incrementNo == null) {
+ throw new EBaseException("incrementNo is null!");
+ }
+
+ // To make sure attrNextRange always increments, first delete the current value and then
+ // increment. Two operations in the same transaction
+
+ LDAPAttribute attrNextRange = new LDAPAttribute(PROP_NEXT_RANGE, nextRangeNo.add(incrementNo).toString());
+ LDAPModification [] mods = {
+ new LDAPModification( LDAPModification.DELETE, attr),
+ new LDAPModification( LDAPModification.ADD, attrNextRange ) };
+ conn.modify( dn, mods );
+
+ // Add new range object
+ String endRange = nextRangeNo.add(incrementNo).subtract(BI_ONE).toString();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectClass", "top"));
+ attrs.add(new LDAPAttribute("objectClass", "pkiRange"));
+ attrs.add(new LDAPAttribute("beginRange" , nextRange));
+ attrs.add(new LDAPAttribute("endRange" , endRange));
+ attrs.add(new LDAPAttribute("cn", nextRange));
+ attrs.add(new LDAPAttribute("host", CMS.getEESSLHost()));
+ attrs.add(new LDAPAttribute("securePort", CMS.getEESSLPort()));
+ String dn2 = "cn=" + nextRange + "," + rangeDN;
+ LDAPEntry rangeEntry = new LDAPEntry(dn2, attrs);
+ conn.add(rangeEntry);
+ } catch (Exception e) {
+ CMS.debug("DBSubsystem: getNextRange. Unable to provide next range :" + e);
+ e.printStackTrace();
+ nextRange = null;
+ } finally {
+ try {
+ if ((conn != null) && (mLdapConnFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return nextRange;
+ }
+
+ /**
+ * Determines if a range conflict has been observed in database.
+ * If so, delete the conflict entry and remove the next range.
+ * When the next number is requested, if the number of certs is still
+ * below the low water mark, then a new range will be requested.
+ *
+ * @param repo repo identifier
+ * @return true if range conflict, false otherwise
+ */
+ public boolean hasRangeConflict(int repo)
+ {
+ LDAPConnection conn = null;
+ boolean conflict = false;
+ try {
+ String nextRangeStart = getNextMinSerialConfig(repo);
+ if (nextRangeStart == null) {
+ return false;
+ }
+ Hashtable h = mRepos[repo];
+ conn = mLdapConnFactory.getConn();
+ String rangedn = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN;
+ String filter = "(&(nsds5ReplConflict=*)(objectClass=pkiRange)(host= " +
+ CMS.getEESSLHost() + ")(SecurePort=" + CMS.getEESSLPort() +
+ ")(beginRange=" + nextRangeStart + "))";
+ LDAPSearchResults results = conn.search(rangedn, LDAPv3.SCOPE_SUB,
+ filter, null, false);
+
+ while (results.hasMoreElements()) {
+ conflict = true;
+ LDAPEntry entry = results.next();
+ String dn = entry.getDN();
+ CMS.debug("Deleting conflict entry:" + dn);
+ conn.delete(dn);
+ }
+ } catch (Exception e) {
+ CMS.debug("DBSubsystem: hasRangeConflict. Error while checking next range." + e);
+ e.printStackTrace();
+ } finally {
+ try {
+ if ((conn != null) && (mLdapConnFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return conflict;
+ }
+
+ public ISubsystem getOwner() {
+ return mOwner;
+ }
+
+ /**
+ * Initializes the internal registery. Connects to the
+ * data source, and create a pool of connection of which
+ * applications can use. Optionally, check the integrity
+ * of the database.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+
+ mLogger = CMS.getLogger();
+ mDBConfig = config;
+ mRepos = new Hashtable[IDBSubsystem.NUM_REPOS];
+
+ mConfig = config.getSubStore(PROP_LDAP);
+ IConfigStore tmpConfig = null;
+ try {
+ mBaseDN = mConfig.getString(PROP_BASEDN, "o=NetscapeCertificateServer");
+
+ mOwner = owner;
+
+ mNextSerialConfig = new BigInteger(mDBConfig.getString(
+ PROP_NEXT_SERIAL_NUMBER, "0"), 16);
+
+ mEnableSerialMgmt = mDBConfig.getBoolean(PROP_ENABLE_SERIAL_MGMT, false);
+
+ // populate the certs hash entry
+ Hashtable certs = new Hashtable();
+ certs.put(NAME, "certs");
+ certs.put(PROP_BASEDN, mDBConfig.getString(PROP_SERIAL_BASEDN,""));
+ certs.put(PROP_RANGE_DN, mDBConfig.getString(PROP_SERIAL_RANGE_DN, ""));
+
+ certs.put(PROP_MIN_NAME, PROP_MIN_SERIAL_NUMBER);
+ certs.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_SERIAL_NUMBER, "0"));
+
+ certs.put(PROP_MAX_NAME, PROP_MAX_SERIAL_NUMBER);
+ certs.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_SERIAL_NUMBER, PROP_INFINITE_SERIAL_NUMBER));
+
+ certs.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_SERIAL_NUMBER);
+ certs.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_SERIAL_NUMBER, "-1"));
+
+ certs.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_SERIAL_NUMBER);
+ certs.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_SERIAL_NUMBER, "-1"));
+
+ certs.put(PROP_LOW_WATER_MARK_NAME, PROP_SERIAL_LOW_WATER_MARK);
+ certs.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_SERIAL_LOW_WATER_MARK, "5000"));
+
+ certs.put(PROP_INCREMENT_NAME, PROP_SERIAL_INCREMENT);
+ certs.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_SERIAL_INCREMENT, PROP_INFINITE_SERIAL_NUMBER));
+
+ mRepos[CERTS]=certs;
+
+ // populate the requests hash entry
+ Hashtable requests = new Hashtable();
+ requests.put(NAME, "requests");
+ requests.put(PROP_BASEDN, mDBConfig.getString(PROP_REQUEST_BASEDN,""));
+ requests.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REQUEST_RANGE_DN, ""));
+
+ requests.put(PROP_MIN_NAME, PROP_MIN_REQUEST_NUMBER);
+ requests.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_REQUEST_NUMBER, "0"));
+
+ requests.put(PROP_MAX_NAME, PROP_MAX_REQUEST_NUMBER);
+ requests.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_REQUEST_NUMBER, PROP_INFINITE_REQUEST_NUMBER));
+
+ requests.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REQUEST_NUMBER);
+ requests.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_REQUEST_NUMBER, "-1"));
+
+ requests.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REQUEST_NUMBER);
+ requests.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_REQUEST_NUMBER, "-1"));
+
+ requests.put(PROP_LOW_WATER_MARK_NAME, PROP_REQUEST_LOW_WATER_MARK);
+ requests.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_REQUEST_LOW_WATER_MARK, "5000"));
+
+ requests.put(PROP_INCREMENT_NAME, PROP_REQUEST_INCREMENT);
+ requests.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_REQUEST_INCREMENT, PROP_INFINITE_REQUEST_NUMBER));
+
+ mRepos[REQUESTS] = requests;
+
+ // populate replica ID hash entry
+ Hashtable replicaID = new Hashtable();
+ replicaID.put(NAME, "requests");
+ replicaID.put(PROP_BASEDN, mDBConfig.getString(PROP_REPLICA_BASEDN,""));
+ replicaID.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REPLICA_RANGE_DN, ""));
+
+ replicaID.put(PROP_MIN_NAME, PROP_MIN_REPLICA_NUMBER);
+ replicaID.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_REPLICA_NUMBER, "1"));
+
+ replicaID.put(PROP_MAX_NAME, PROP_MAX_REPLICA_NUMBER);
+ replicaID.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_REPLICA_NUMBER, PROP_INFINITE_REPLICA_NUMBER));
+
+ replicaID.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REPLICA_NUMBER);
+ replicaID.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_REPLICA_NUMBER, "-1"));
+
+ replicaID.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REPLICA_NUMBER);
+ replicaID.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_REPLICA_NUMBER, "-1"));
+
+ replicaID.put(PROP_LOW_WATER_MARK_NAME, PROP_REPLICA_LOW_WATER_MARK);
+ replicaID.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_REPLICA_LOW_WATER_MARK, "10"));
+
+ replicaID.put(PROP_INCREMENT_NAME, PROP_REPLICA_INCREMENT);
+ replicaID.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_REPLICA_INCREMENT, PROP_INFINITE_REPLICA_NUMBER));
+
+ mRepos[REPLICA_ID] = replicaID;
+
+
+ // initialize registry
+ mRegistry = new DBRegistry();
+ mRegistry.init(this, null);
+
+ // initialize LDAP connection factory
+ // by default return error if server is down at startup time.
+ mLdapConnFactory = new LdapBoundConnFactory(true);
+ tmpConfig = (IConfigStore) (((PropConfigStore) mConfig).clone());
+
+ tmpConfig.putString(PROP_BASEDN, mBaseDN);
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+
+ try {
+ mLdapConnFactory.init(tmpConfig);
+ } catch (ELdapServerDownException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ } catch (ELdapException ex) {
+ if (CMS.isPreOpMode())
+ return;
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_ERROR", ex.toString()));
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+
+ try {
+ // registers CMS database attributes
+ IDBRegistry reg = getRegistry();
+
+ String certRecordOC[] = new String[2];
+
+ certRecordOC[0] = CertDBSchema.LDAP_OC_TOP;
+ certRecordOC[1] = CertDBSchema.LDAP_OC_CERT_RECORD;
+
+ if (!reg.isObjectClassRegistered(CertRecord.class.getName())) {
+ reg.registerObjectClass(CertRecord.class.getName(),
+ certRecordOC);
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_ID)) {
+ reg.registerAttribute(CertRecord.ATTR_ID, new
+ BigIntegerMapper(CertDBSchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_META_INFO)) {
+ reg.registerAttribute(CertRecord.ATTR_META_INFO, new
+ MetaInfoMapper(CertDBSchema.LDAP_ATTR_META_INFO));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVO_INFO)) {
+ reg.registerAttribute(CertRecord.ATTR_REVO_INFO, new
+ RevocationInfoMapper());
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_X509CERT)) {
+ reg.registerAttribute(CertRecord.ATTR_X509CERT, new
+ X509CertImplMapper());
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_CERT_STATUS)) {
+ reg.registerAttribute(CertRecord.ATTR_CERT_STATUS, new
+ StringMapper(CertDBSchema.LDAP_ATTR_CERT_STATUS));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_AUTO_RENEW)) {
+ reg.registerAttribute(CertRecord.ATTR_AUTO_RENEW, new
+ StringMapper(CertDBSchema.LDAP_ATTR_AUTO_RENEW));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_CREATE_TIME)) {
+ reg.registerAttribute(CertRecord.ATTR_CREATE_TIME, new
+ DateMapper(CertDBSchema.LDAP_ATTR_CREATE_TIME));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_MODIFY_TIME)) {
+ reg.registerAttribute(CertRecord.ATTR_MODIFY_TIME, new
+ DateMapper(CertDBSchema.LDAP_ATTR_MODIFY_TIME));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_ISSUED_BY)) {
+ reg.registerAttribute(CertRecord.ATTR_ISSUED_BY, new
+ StringMapper(CertDBSchema.LDAP_ATTR_ISSUED_BY));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVOKED_BY)) {
+ reg.registerAttribute(CertRecord.ATTR_REVOKED_BY, new
+ StringMapper(CertDBSchema.LDAP_ATTR_REVOKED_BY));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVOKED_ON)) {
+ reg.registerAttribute(CertRecord.ATTR_REVOKED_ON, new
+ DateMapper(CertDBSchema.LDAP_ATTR_REVOKED_ON));
+ }
+
+ if (!reg.isAttributeRegistered(CertificateValidity.NOT_AFTER)) {
+ reg.registerAttribute(CertificateValidity.NOT_AFTER, new
+ DateMapper(CertDBSchema.LDAP_ATTR_NOT_AFTER));
+ }
+
+ if (!reg.isAttributeRegistered(CertificateValidity.NOT_BEFORE)) {
+ reg.registerAttribute(CertificateValidity.NOT_BEFORE, new
+ DateMapper(CertDBSchema.LDAP_ATTR_NOT_BEFORE));
+ }
+
+ String crlRecordOC[] = new String[2];
+
+ crlRecordOC[0] = CRLDBSchema.LDAP_OC_TOP;
+ crlRecordOC[1] = CRLDBSchema.LDAP_OC_CRL_RECORD;
+ reg.registerObjectClass(CRLIssuingPointRecord.class.getName(),
+ crlRecordOC);
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_ID, new
+ StringMapper(CRLDBSchema.LDAP_ATTR_CRL_ID));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_NUMBER, new
+ BigIntegerMapper(CRLDBSchema.LDAP_ATTR_CRL_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_NUMBER, new
+ BigIntegerMapper(CRLDBSchema.LDAP_ATTR_DELTA_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_SIZE, new
+ LongMapper(CRLDBSchema.LDAP_ATTR_CRL_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_SIZE, new
+ LongMapper(CRLDBSchema.LDAP_ATTR_DELTA_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_THIS_UPDATE, new
+ DateMapper(CRLDBSchema.LDAP_ATTR_THIS_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE, new
+ DateMapper(CRLDBSchema.LDAP_ATTR_NEXT_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED, new
+ StringMapper(CRLDBSchema.LDAP_ATTR_FIRST_UNSAVED));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_CRL));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_CRL, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_DELTA_CRL));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CA_CERT, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_CA_CERT));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_CACHE, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_CRL_CACHE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_REVOKED_CERTS));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_UNREVOKED_CERTS));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_EXPIRED_CERTS));
+
+ if (!reg.isObjectClassRegistered(
+ RepositoryRecord.class.getName())) {
+ String repRecordOC[] = new String[2];
+
+ repRecordOC[0] = RepositorySchema.LDAP_OC_TOP;
+ repRecordOC[1] = RepositorySchema.LDAP_OC_REPOSITORY;
+ reg.registerObjectClass(
+ RepositoryRecord.class.getName(), repRecordOC);
+ }
+ if (!reg.isAttributeRegistered(IRepositoryRecord.ATTR_SERIALNO)) {
+ reg.registerAttribute(IRepositoryRecord.ATTR_SERIALNO,
+ new BigIntegerMapper(RepositorySchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ reg.registerAttribute(IRepositoryRecord.ATTR_PUB_STATUS,
+ new StringMapper(RepositorySchema.LDAP_ATTR_PUB_STATUS));
+ }
+
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+ }
+
+ /**
+ * Starts up this service.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Retrieves configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves base DN of backend database.
+ */
+ public String getBaseDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Retrieves LDAP connection info (host, port, secure)
+ */
+ public LdapConnInfo getLdapConnInfo() {
+ if (mLdapConnFactory != null)
+ return mLdapConnFactory.getConnInfo();
+ return null;
+ }
+
+ public LdapAuthInfo getLdapAuthInfo() {
+ if (mLdapConnFactory != null)
+ return mLdapConnFactory.getAuthInfo();
+ return null;
+ }
+
+ /**
+ * Shutdowns this subsystem gracefully.
+ */
+ public void shutdown() {
+ try {
+ if (mLdapConnFactory != null) {
+ mLdapConnFactory.reset();
+ mLdapConnFactory = null;
+ }
+ } catch (ELdapException e) {
+
+ /*LogDoc
+ *
+ * @phase shutdown server
+ * @reason shutdown db subsystem
+ * @message DBSubsystem: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ if (mRegistry != null)
+ mRegistry.shutdown();
+ }
+
+ /**
+ * Retrieves the registry.
+ */
+ public IDBRegistry getRegistry() {
+ return mRegistry;
+ }
+
+ /**
+ * Creates a database session.
+ */
+ public IDBSSession createSession() throws EDBException {
+ LDAPConnection conn = null;
+
+ try {
+ conn = mLdapConnFactory.getConn();
+
+ String schemaAdded = mDBConfig.getString("newSchemaEntryAdded", "");
+
+ if (schemaAdded.equals("")) {
+ LDAPSchema dirSchema = new LDAPSchema();
+
+ // create new attribute: userType
+ dirSchema.fetchSchema(conn);
+ LDAPAttributeSchema userType = dirSchema.getAttribute("usertype");
+
+ if (userType == null) {
+ userType = new LDAPAttributeSchema("usertype", "usertype-oid",
+ "Distinguish whether the user is administrator, agent or subsystem.",
+ LDAPAttributeSchema.cis, false);
+ userType.add(conn);
+ }
+
+ // create new objectclass: cmsuser
+ dirSchema.fetchSchema(conn);
+ LDAPObjectClassSchema newObjClass = dirSchema.getObjectClass("cmsuser");
+ String[] requiredAttrs = {"usertype"};
+ String[] optionalAttrs = new String[0];
+
+ if (newObjClass == null) {
+ newObjClass = new LDAPObjectClassSchema("cmsuser", "cmsuser-oid",
+ "top", "CMS User", requiredAttrs, optionalAttrs);
+ newObjClass.add(conn);
+ }
+ mDBConfig.putString("newSchemaEntryAdded", "true");
+ IConfigStore rootStore = getOwner().getConfigStore();
+
+ rootStore.commit(false);
+ }
+ } catch (ELdapException e) {
+ if (e instanceof ELdapServerDownException) {
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ }
+
+ /*LogDoc
+ *
+ * @phase create db session
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_CONN_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_CONNECT_LDAP_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != 20) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_SCHEMA_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_ADD_ENTRY_FAILED", e.toString()));
+ }
+ } catch (EBaseException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_CONF_ERROR",
+ e.toString()));
+ }
+ return new DBSSession(this, conn);
+ }
+
+ public void returnConn(LDAPConnection conn) {
+ mLdapConnFactory.returnConn(conn);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
new file mode 100644
index 000000000..8a3b3cba7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
@@ -0,0 +1,769 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.controls.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a virtual list of search results.
+ * Note that this class must be used with DS4.0.
+ *
+ * @author thomask
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class DBVirtualList implements IDBVirtualList {
+
+ private IDBRegistry mRegistry = null;
+ private LDAPConnection mConn = null;
+ private String mBase = null;
+ private String mFilter = null;
+ private String mAttrs[] = null;
+ // virtual list size
+ private int mSize = -1;
+
+ private Vector mEntries = new Vector();
+ // mSize is get or not?
+ private boolean mInitialized = false;
+ private LDAPSortKey[] mKeys;
+ private LDAPControl[] mPageControls = null;
+ // page buffer size
+ private int mPageSize = 10;
+ // the top of the buffer
+ private int mTop = 0;
+ private int mBeforeCount;
+ private int mAfterCount;
+ // the index of the first entry returned
+ private int mSelectedIndex = 0;
+ private int mJumpToIndex = 0;
+ private int mJumpToInitialIndex = 0; // Initial index hit in jumpto operation
+ private int mJumpToDirection = 1; // Do we proceed forward or backwards
+ private String mJumpTo = null; // Determines if this is the jumpto case
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ * Be sure to setSortKey() before fetchs
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[]) throws EBaseException {
+ mRegistry = registry;
+ mFilter = filter;
+ mBase = base;
+ mAttrs = attrs;
+ CMS.debug( "In DBVirtualList filter attrs filter: " + filter
+ + " attrs: " + Arrays.toString( attrs ) );
+ mPageControls = new LDAPControl[2];
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attributes to sort by
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey[])
+ throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sotrKey[] filter: " + filter
+ + " attrs: " + Arrays.toString( attrs ) );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ }
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attribute to sort by
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey)
+ throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey filter: " + filter + " attrs: " + Arrays.toString( attrs ) );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ }
+
+ /**
+ * Constructs a virtual list.
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attributes to sort by
+ * param pageSize the size of a page. There is a 3*pageSize buffer maintained so
+ * pageUp and pageDown won't invoke fetch from ldap server
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey[],
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey[] pageSize filter: "
+ + filter + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ setPageSize(pageSize);
+ }
+
+ /**
+ * Constructs a virtual list.
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attribute to sort by
+ * param pageSize the size of a page. There is a 3*pageSize buffer maintained so
+ * pageUp and pageDown won't invoke fetch from ldap server
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey,
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey pageSize filter: "
+ + filter + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ setPageSize(pageSize);
+ }
+
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[],
+ String startFrom, String sortKey,
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs startFrom sortKey pageSize "
+ + "filter: " + filter
+ + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize + " startFrom " + startFrom );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ mJumpTo = startFrom;
+ setSortKey(sortKey);
+ // setPageSize(pageSize);
+
+ if (pageSize < 0) {
+ mJumpToDirection = -1;
+ }
+ mPageSize = pageSize;
+
+ mBeforeCount = 0;
+ mAfterCount = mPageSize;
+ }
+
+ /**
+ * Set the paging size of this virtual list.
+ * The page size here is just a buffer size. A buffer is kept around
+ * that is three times as large as the number of visible entries.
+ * That way, you can scroll up/down several items(up to a page-full)
+ * without refetching entries from the directory.
+ *
+ * @param size the page size
+ */
+ public void setPageSize(int size) {
+
+ if (mJumpTo != null) {
+ return;
+ }
+
+ mPageSize = size;
+ mBeforeCount = 0; //mPageSize;
+ mAfterCount = mPageSize; // mPageSize + mPageSize;
+
+ //CMS.debug("In setPageSize " + size + " mBeforeCount " + mBeforeCount + " mAfterCount " + mAfterCount);
+ }
+
+ /**
+ * set the sort key
+ *
+ * @param sortKey the attribute to sort by
+ */
+ public void setSortKey(String sortKey) throws EBaseException {
+ String keys[] = new String[1];
+
+ keys[0] = sortKey;
+ setSortKey(keys);
+ }
+
+ /**
+ * set the sort key
+ *
+ * @param sortKey the attributes to sort by
+ */
+ public void setSortKey(String[] sortKeys) throws EBaseException {
+ if (sortKeys == null)
+ throw new EBaseException("sort keys cannot be null");
+ try {
+
+ mKeys = new LDAPSortKey[sortKeys.length];
+ String la[] = mRegistry.getLDAPAttributes(sortKeys);
+
+ for (int j = 0; j < sortKeys.length; j++) {
+ mKeys[j] = new LDAPSortKey(la[j]);
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed at setSortKey.
+ * @message DBVirtualList: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ // Paged results also require a sort control
+ if (mKeys != null) {
+ mPageControls[0] =
+ new LDAPSortControl(mKeys, true);
+ }else {
+ throw new EBaseException("sort keys cannot be null");
+ }
+ }
+
+ /**
+ * Retrieves the size of this virtual list.
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ */
+ public int getSize() {
+ if (!mInitialized) {
+ mInitialized = true;
+ // Do an initial search to get the virtual list size
+ // Keep one page before and one page after the start
+ if (mJumpTo == null) {
+ mBeforeCount = 0; //mPageSize;
+ mAfterCount = mPageSize; // mPageSize + mPageSize;
+ }
+ // Create the initial paged results control
+ /* Since this one is only used to get the size of the virtual list;
+ we don't care about the starting index. If there is no partial
+ match, the first one before (or after, if none before) is returned
+ as the index entry. Instead of "A", you could use the other
+ constructor and specify 0 both for startIndex and for
+ contentCount. */
+ LDAPVirtualListControl cont = null;
+
+ if (mJumpTo == null) {
+ cont = new LDAPVirtualListControl("A",
+ mBeforeCount,
+ mAfterCount);
+ } else {
+
+ if (mPageSize < 0) {
+ mBeforeCount = mPageSize * -1;
+ mAfterCount = 0;
+ }
+ cont = new LDAPVirtualListControl(mJumpTo,
+ mBeforeCount,
+ mAfterCount);
+ }
+ mPageControls[1] = cont;
+ getJumpToPage();
+ }
+
+ CMS.debug("Getting Virtual List size: " + mSize);
+ return mSize;
+ }
+
+ public int getSizeBeforeJumpTo() {
+
+ if (!mInitialized || mJumpTo == null)
+ return 0;
+
+ int size = 0;
+
+ if (mJumpToDirection < 0) {
+ size = mTop + mEntries.size();
+ } else {
+ size = mTop;
+
+ }
+
+ return size;
+
+ }
+
+ public int getSizeAfterJumpTo() {
+
+ if (!mInitialized || mJumpTo == null)
+ return 0;
+
+ int size = mSize - mTop;
+
+ return size;
+
+ }
+
+ private synchronized boolean getEntries() {
+ // Specify necessary controls for vlist
+ // LDAPSearchConstraints cons = mConn.getSearchConstraints();
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(0);
+ if (mPageControls != null) {
+ cons.setServerControls(mPageControls);
+ //System.out.println( "setting vlist control" );
+ }
+ // Empty the buffer
+ mEntries.removeAllElements();
+ // Do a search
+ try {
+ //what happen if there is no matching?
+ String ldapFilter = mRegistry.getFilter(mFilter);
+ String ldapAttrs[] = null;
+ LDAPSearchResults result;
+
+ if (mAttrs != null) {
+ ldapAttrs = mRegistry.getLDAPAttributes(mAttrs);
+
+ /*
+ LDAPv2.SCOPE_BASE:
+ (search only the base DN)
+ LDAPv2.SCOPE_ONE:
+ (search only entries under the base DN)
+ LDAPv2.SCOPE_SUB:
+ (search the base DN and all entries within its subtree)
+ */
+ result = mConn.search(mBase,
+ LDAPConnection.SCOPE_ONE, ldapFilter, ldapAttrs,
+ false, cons);
+
+ } else {
+ result = mConn.search(mBase,
+ LDAPConnection.SCOPE_ONE, ldapFilter, null,
+ false, cons);
+ }
+ if (result == null) {
+ return false;
+ }
+ int damageCounter = 0;
+
+ while (result.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) result.nextElement();
+
+ try {
+ //maintain mEntries as vector of LDAPEntry
+ Object o = mRegistry.createObject(entry.getAttributeSet());
+
+ mEntries.addElement(o);
+ } catch (Exception e) {
+
+ CMS.debug("Exception " + e);
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed to get enties.
+ * @message DBVirtualList: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_ADD", e.toString()));
+ // #539044
+ damageCounter++;
+ if (damageCounter > 100) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_CORRUPTED_ENTRIES", Integer.toString(damageCounter)));
+ return false;
+ }
+ }
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed to get enties.
+ * @message DBVirtualList: <exception thrown>
+ */
+ CMS.debug("getEntries: exception " + e);
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ //System.out.println( "Returning " + mEntries.size() +
+ // " entries" );
+
+ CMS.debug("getEntries returning " + mEntries.size());
+ return true;
+ }
+
+ public int getCurrentIndex() {
+ return mTop;
+ }
+
+ private synchronized boolean getJumpToPage() {
+ try {
+ // Get the actual entries
+ if (!getEntries())
+ return false;
+
+ // Check if we have a control returned
+ LDAPControl[] c = mConn.getResponseControls();
+ LDAPVirtualListResponse nextCont =
+ LDAPVirtualListResponse.parseResponse(c);
+
+ if (nextCont != null) {
+ mSelectedIndex = nextCont.getFirstPosition() - 1;
+ mTop = Math.max(0, mSelectedIndex - mBeforeCount);
+
+ CMS.debug("mTop " + mTop);
+ if (mJumpTo != null) {
+ mJumpToInitialIndex = mTop;
+ }
+
+ // Now we know the total size of the virtual list box
+ mSize = nextCont.getContentCount();
+ ((LDAPVirtualListControl) mPageControls[1]).setListSize(mSize);
+ mInitialized = true;
+ //System.out.println( "Virtual window: " + mTop +
+ // ".." + (mTop+mEntries.size()-1) +
+ // " of " + mSize );
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_VL_NULL_RESPONSE"));
+ }
+ return true;
+ } catch (Exception e) {
+ // happens when connection is not available
+ return false;
+ }
+ }
+
+ /** Get a page starting at "first" (although we may also fetch
+ * some preceding entries)
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ *
+ * @param first the index of the first entry of the page you want to fetch
+ */
+ public boolean getPage(int first) {
+ CMS.debug("getPage " + first);
+ if (!mInitialized) {
+ LDAPVirtualListControl cont = new LDAPVirtualListControl(0,
+ mBeforeCount,
+ mAfterCount, 0);
+
+ mPageControls[1] = cont;
+ }
+
+ //CMS.debug("about to set range first " + first + " mBeforeCount " + mBeforeCount + " mAfterCount " + mAfterCount);
+ ((LDAPVirtualListControl) mPageControls[1]).setRange(first, mBeforeCount, mAfterCount);
+ return getPage();
+ }
+
+ /** Fetch a buffer
+ */
+ private boolean getPage() {
+ // Get the actual entries
+ if (!getEntries())
+ return false;
+
+ // Check if we have a control returned
+ LDAPControl[] c = mConn.getResponseControls();
+ LDAPVirtualListResponse nextCont =
+ LDAPVirtualListResponse.parseResponse(c);
+
+ if (nextCont != null) {
+ mSelectedIndex = nextCont.getFirstPosition() - 1;
+ mTop = Math.max(0, mSelectedIndex - mBeforeCount);
+ //CMS.debug("New mTop: " + mTop + " mSelectedIndex " + mSelectedIndex);
+ // Now we know the total size of the virtual list box
+ mSize = nextCont.getContentCount();
+ ((LDAPVirtualListControl) mPageControls[1]).setListSize(mSize);
+ mInitialized = true;
+ //System.out.println( "Virtual window: " + mTop +
+ // ".." + (mTop+mEntries.size()-1) +
+ // " of " + mSize );
+ } else {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_NULL_RESPONSE"));
+ }
+ return true;
+ }
+
+ /** Called by application to scroll the list with initial letters.
+ * Consider text to be an initial substring of the attribute of the
+ * primary sorting key(the first one specified in the sort key array)
+ * of an entry.
+ * If no entries match, the one just before(or after, if none before)
+ * will be returned as mSelectedIndex
+ *
+ * @param text the prefix of the first entry of the page you want to fetch
+ */
+ public boolean getPage(String text) {
+ mPageControls[1] =
+ new LDAPVirtualListControl(text,
+ mBeforeCount,
+ mAfterCount);
+ //System.out.println( "Setting requested start to " +
+ // text + ", -" + mBeforeCount + ", +" +
+ // mAfterCount );
+ return getPage();
+ }
+
+ /**
+ * fetch data of a single list item
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ * If the index is out of range of the virtual list, an exception will be thrown
+ * and return null
+ *
+ * @param index the index of the element to fetch
+ */
+ public Object getElementAt(int index) {
+
+ /* mSize may not be init at this time! Bad !
+ * the caller should really check the index is within bound before this
+ * but I'll take care of this just in case they are too irresponsible
+ */
+ int baseJumpTo = 0;
+
+ if (!mInitialized)
+ mSize = getSize();
+
+ CMS.debug("getElementAt: " + index + " mTop " + mTop);
+
+ //System.out.println( "need entry " + index );
+ if ((index < 0) || (index >= mSize)) {
+ CMS.debug("returning null");
+ return null;
+ }
+
+ if (mJumpTo != null) { //Handle the explicit jumpto case
+
+ if (index == 0)
+ mJumpToIndex = 0; // Keep a running jumpto index for this page of data
+ else
+ mJumpToIndex++;
+
+ //CMS.debug("getElementAtJT: " + index + " mTop " + mTop + " mEntries.size() " + mEntries.size());
+
+ if ((mJumpToDirection > 0) && (mJumpToInitialIndex + index >= mSize)) // out of data in forward paging jumpto case
+ {
+ CMS.debug("mJumpTo virtual list exhausted mTop " + mTop + " mSize " + mSize);
+ return null;
+ }
+
+ if (mJumpToIndex >= mEntries.size()) // In jumpto case, page of data has been exhausted
+ {
+ mJumpToIndex = 0; // new page will be needed reset running count
+
+ if (mJumpToDirection > 0) { //proceed in positive direction past hit point
+ getPage(index + mJumpToInitialIndex + 1);
+ } else { //proceed backwards from hit point
+ if (mTop == 0) {
+ getPage(0);
+ CMS.debug("asking for a page less than zero in reverse case, return null");
+ return null;
+ }
+
+ CMS.debug("getting page reverse mJumptoIndex " + mJumpToIndex + " mTop " + mTop);
+ getPage(mTop);
+
+ }
+
+ }
+
+ if (mJumpToDirection > 0) // handle getting entry in forward direction
+ {
+ return mEntries.elementAt(mJumpToIndex);
+ } else { // handle getting entry in reverse direction
+ int reverse_index = mEntries.size() - mJumpToIndex - 1;
+
+ CMS.debug("reverse direction getting index " + reverse_index);
+
+ if (reverse_index < 0 || reverse_index >= mEntries.size()) {
+ CMS.debug("reverse_index out of range " + reverse_index);
+ return null;
+ }
+ return mEntries.elementAt(reverse_index);
+ }
+ }
+
+ //CMS.debug("getElementAt noJumpto: " + index);
+
+ if ((index < mTop) || (index >= mTop + mEntries.size())) { // handle the non jumpto case
+ //fetch a new page
+ //System.out.println( "fetching a page starting at " +
+ // index );
+ // CMS.debug("getElementAt noJumpto: getting page index: " + index + " mEntries.size() " + mEntries.size() + " mTop: " + mTop);
+ getPage(index);
+ }
+
+ int offset = index - mTop;
+
+ if ((offset < 0) || (offset >= mEntries.size()))
+ //XXX
+ return ("No entry at " + index);
+ else
+ return mEntries.elementAt(offset);
+ }
+
+ public Object getJumpToElementAt(int i) {
+ return mEntries.elementAt(i);
+ }
+
+ /**
+ * This function processes elements as soon as it arrives. It is
+ * more memory-efficient.
+ */
+ public void processElements(int startidx, int endidx, IElementProcessor ep)
+ throws EBaseException {
+
+ /* mSize may not be init at this time! Bad !
+ * the caller should really check the index is within bound before this
+ * but I'll take care of this just in case they are too irresponsible
+ */
+ if (!mInitialized)
+ mSize = getSize();
+
+ // short-cut the existing code ... :(
+ if (mJumpTo != null) {
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = getJumpToElementAt(i);
+
+ if (element != null)
+ ep.process(element);
+ }
+ return;
+ }
+
+ //guess this is what you really mean to try to improve performance
+ if (startidx >= endidx) {
+ throw new EBaseException("startidx must be less than endidx");
+ }else {
+ setPageSize(endidx - startidx);
+ getPage(startidx);
+ }
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = getElementAt(i);
+
+ if (element != null)
+ ep.process(element);
+ }
+ }
+
+ /**
+ * get the virutal selected index
+ */
+ public int getSelectedIndex() {
+ return mSelectedIndex;
+ }
+
+ /**
+ * get the top of the buffer
+ */
+ public int getFirstIndex() {
+ return mTop;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
new file mode 100644
index 000000000..e073fe633
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
@@ -0,0 +1,105 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Date array object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DateArrayMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a date array mapper.
+ */
+ public DateArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of support ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to a set of attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ Date dates[] = (Date[]) obj;
+
+ if (dates == null)
+ return;
+ LDAPAttribute attr = new LDAPAttribute(mLdapName);
+
+ for (int i = 0; i < dates.length; i++) {
+ attr.addValue(DateMapper.dateToDB(dates[i]));
+ }
+ attrs.add(attr);
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration e = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ v.addElement(DateMapper.dateFromDB((String)
+ e.nextElement()));
+ }
+ if (v.size() == 0)
+ return;
+ Date dates[] = new Date[v.size()];
+
+ v.copyInto(dates);
+ parent.set(name, dates);
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java
new file mode 100644
index 000000000..8b0009479
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java
@@ -0,0 +1,108 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.text.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Date object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DateMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+ private static SimpleDateFormat formatter = new
+ SimpleDateFormat("yyyyMMddHHmmss'Z'");
+
+ /**
+ * Constructs date mapper.
+ */
+ public DateMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ dateToDB((Date) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, dateFromDB((String)
+ attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String val = null;
+
+ try {
+ val = dateToDB(new Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ val = value;
+ }
+ return mLdapName + op + val;
+ }
+
+ public synchronized static String dateToDB(Date date) {
+ return formatter.format(date);
+ }
+
+ public synchronized static Date dateFromDB(String dbDate) {
+ try {
+ return formatter.parse(dbDate);
+ } catch (ParseException e) {
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java
new file mode 100644
index 000000000..2293bea26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java
@@ -0,0 +1,86 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Integer object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class IntegerMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs mapper to deal with Integer.
+ */
+ public IntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((Integer) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, new Integer((String)
+ attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java
new file mode 100644
index 000000000..7a5e02a04
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java
@@ -0,0 +1,58 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of key record
+ * specific schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_CREATE_TIME = "dateOfCreate";
+ public static final String LDAP_ATTR_MODIFY_TIME = "dateOfModify";
+ public static final String LDAP_ATTR_META_INFO = "metaInfo";
+ public static final String LDAP_OC_KEYRECORD = "keyRecord";
+ public static final String LDAP_ATTR_OWNER_NAME = "ownerName";
+ public static final String LDAP_ATTR_PRIVATE_KEY_DATA = "privateKeyData";
+ public static final String LDAP_ATTR_KEY_RECORD_ID = "keyRecordId";
+ public static final String LDAP_ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+ public static final String LDAP_ATTR_KEY_SIZE = "keySize";
+ public static final String LDAP_ATTR_ALGORITHM = "algorithm";
+ public static final String LDAP_ATTR_STATE = "keyState";
+ public static final String LDAP_ATTR_DATE_OF_RECOVERY =
+ "dateOfRecovery";
+ public static final String LDAP_ATTR_PUBLIC_KEY_FORMAT =
+ "publicKeyFormat";
+ public static final String LDAP_ATTR_ARCHIVED_BY = "archivedBy";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java
new file mode 100644
index 000000000..7b6fcdb8d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java
@@ -0,0 +1,348 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+//import netscape.security.provider.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.ldap.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+
+/**
+ * A class represents a Key record. It maintains the key
+ * life cycle as well as other information about an
+ * archived key. Namely, whether a key is inactive because
+ * of compromise.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecord implements IDBObj, IKeyRecord {
+
+ private BigInteger mSerialNo = null;
+ private KeyState mState = null;
+ private MetaInfo mMetaInfo = null;
+ private String mAlgorithm = null;
+ private byte mPrivateKey[] = null;
+ private byte mPublicKey[] = null;
+ private Integer mSize = null;
+ private String mOwnerName = null;
+ private Date mDatesOfRecovery[] = null;
+ private Date mCreateTime = null;
+ private Date mModifyTime = null;
+ private String mArchivedBy = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_STATE);
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_OWNER_NAME);
+ mNames.addElement(ATTR_KEY_SIZE);
+ mNames.addElement(ATTR_ALGORITHM);
+ mNames.addElement(ATTR_PRIVATE_KEY_DATA);
+ mNames.addElement(ATTR_PUBLIC_KEY_DATA);
+ mNames.addElement(ATTR_DATE_OF_RECOVERY);
+ mNames.addElement(ATTR_META_INFO);
+ mNames.addElement(ATTR_CREATE_TIME);
+ mNames.addElement(ATTR_MODIFY_TIME);
+ mNames.addElement(ATTR_ARCHIVED_BY);
+ }
+
+ /**
+ * Constructs empty key record.
+ */
+ public KeyRecord() {
+ }
+
+ /*
+ * Constructs key record.
+ *
+ * @param key key to be archived
+ */
+ public KeyRecord(BigInteger serialNo, byte publicData[],
+ byte privateData[], String owner,
+ String algorithm, String agentId)
+ throws EBaseException {
+ mSerialNo = serialNo;
+ mPublicKey = publicData;
+ mPrivateKey = privateData;
+ mOwnerName = owner;
+ mAlgorithm = algorithm;
+ mState = KeyState.VALID;
+ mCreateTime = com.netscape.certsrv.apps.CMS.getCurrentDate();
+ mModifyTime = com.netscape.certsrv.apps.CMS.getCurrentDate();
+ mArchivedBy = agentId;
+ }
+
+ /**
+ * Sets an attribute.
+ * <P>
+ */
+ public void set(String name, Object object) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_STATE)) {
+ mState = (KeyState) object;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ mSerialNo = (BigInteger) object;
+ } else if (name.equalsIgnoreCase(ATTR_KEY_SIZE)) {
+ mSize = (Integer) object;
+ } else if (name.equalsIgnoreCase(ATTR_OWNER_NAME)) {
+ mOwnerName = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_ALGORITHM)) {
+ mAlgorithm = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_PRIVATE_KEY_DATA)) {
+ mPrivateKey = (byte[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_PUBLIC_KEY_DATA)) {
+ mPublicKey = (byte[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_DATE_OF_RECOVERY)) {
+ mDatesOfRecovery = (Date[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ mMetaInfo = (MetaInfo) object;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ mCreateTime = (Date) object;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ mModifyTime = (Date) object;
+ } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) {
+ mArchivedBy = (String) object;
+ } else {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves an attribute.
+ * <P>
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_STATE)) {
+ return mState;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mSerialNo;
+ } else if (name.equalsIgnoreCase(ATTR_KEY_SIZE)) {
+ return mSize;
+ } else if (name.equalsIgnoreCase(ATTR_OWNER_NAME)) {
+ return mOwnerName;
+ } else if (name.equalsIgnoreCase(ATTR_ALGORITHM)) {
+ return mAlgorithm;
+ } else if (name.equalsIgnoreCase(ATTR_PRIVATE_KEY_DATA)) {
+ return mPrivateKey;
+ } else if (name.equalsIgnoreCase(ATTR_PUBLIC_KEY_DATA)) {
+ return mPublicKey;
+ } else if (name.equalsIgnoreCase(ATTR_DATE_OF_RECOVERY)) {
+ return mDatesOfRecovery;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ return mCreateTime;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ return mModifyTime;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ return mMetaInfo;
+ } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) {
+ return mArchivedBy;
+ } else {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes an attribute.
+ * <P>
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ /**
+ * Retrieves an enumeration of attributes.
+ * <P>
+ */
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serializable attribute names.
+ */
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serial number of the key record. Each key record
+ * is uniquely identified by serial number.
+ * <P>
+ *
+ * @return serial number of this key record
+ */
+ public BigInteger getSerialNumber() throws EBaseException {
+ return mSerialNo;
+ }
+
+ /**
+ * Sets serial number.
+ */
+ public void setSerialNumber(BigInteger serialno) throws EBaseException {
+ mSerialNo = serialno;
+ }
+
+ /**
+ * Retrieves the key state. This gives key life cycle
+ * information.
+ * <P>
+ *
+ * @return key state
+ */
+ public KeyState getState() throws EBaseException {
+ return mState;
+ }
+
+ /**
+ * Sets key state.
+ * <P>
+ */
+ public void setState(KeyState state) throws EBaseException {
+ mState = state;
+ }
+
+ /**
+ * Retrieves the uid of person who archived this record.
+ */
+ public String getArchivedBy() {
+ return mArchivedBy;
+ }
+
+ /**
+ * Retrieves key.
+ * <P>
+ *
+ * @return archived key
+ */
+ public byte[] getPrivateKeyData() throws EBaseException {
+ return mPrivateKey;
+ }
+
+ /**
+ * Sets key data.
+ */
+ public void setPrivateKeyData(byte keydata[]) throws EBaseException {
+ mPrivateKey = keydata;
+ }
+
+ /**
+ * Retrieves the key size.
+ * <P>
+ *
+ * @return key size
+ */
+ public Integer getKeySize() throws EBaseException {
+ return mSize;
+ }
+
+ /**
+ * Sets key size.
+ * <P>
+ */
+ public void setKeySize(Integer keySize) throws EBaseException {
+ mSize = keySize;
+ }
+
+ /**
+ * Retrieves owner name.
+ * <P>
+ */
+ public String getOwnerName() throws EBaseException {
+ return mOwnerName;
+ }
+
+ /**
+ * Sets owner name.
+ * <P>
+ */
+ public void setOwnerName(String name) throws EBaseException {
+ mOwnerName = name;
+ }
+
+ /**
+ * Retrieves the public key.
+ * <P>
+ */
+ public byte[] getPublicKeyData() throws EBaseException {
+ return mPublicKey;
+ }
+
+ /**
+ * Sets the public key.
+ * <P>
+ */
+ public void setPublicKeyData(byte key[]) throws EBaseException {
+ mPublicKey = key;
+ }
+
+ /**
+ * Retrieves the date(s) of revocation.
+ * <P>
+ */
+ public Date[] getDateOfRevocation() throws EBaseException {
+ return mDatesOfRecovery;
+ }
+
+ /**
+ * Sets the dateso of revocation.
+ * <P>
+ */
+ public void setDateOfRevocation(Date dates[]) throws EBaseException {
+ mDatesOfRecovery = dates;
+ }
+
+ /**
+ * Retrieves algorithm of the key pair.
+ */
+ public String getAlgorithm() {
+ return mAlgorithm;
+ }
+
+ public MetaInfo getMetaInfo() {
+ return mMetaInfo;
+ }
+
+ /**
+ * Retrieves the creation time of this record.
+ */
+ public Date getCreateTime() {
+ return mCreateTime;
+ }
+
+ /**
+ * Retrieves the last modification time of
+ * this record.
+ */
+ public Date getModifyTime() {
+ return mModifyTime;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java
new file mode 100644
index 000000000..250e66e6c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.cmscore.dbs.*;
+
+
+/**
+ * A class represents a list of key records.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordList implements IKeyRecordList {
+
+ private IDBVirtualList mVlist = null;
+
+ /**
+ * Constructs a key list.
+ */
+ public KeyRecordList(IDBVirtualList vlist) {
+ mVlist = vlist;
+ }
+
+ /**
+ * Retrieves the size of key list.
+ */
+ public int getSize() {
+ return mVlist.getSize();
+ }
+
+ public int getSizeBeforeJumpTo() {
+
+ return mVlist.getSizeBeforeJumpTo();
+
+ }
+
+ public int getSizeAfterJumpTo() {
+
+ return mVlist.getSizeAfterJumpTo();
+ }
+
+ public IKeyRecord getKeyRecord(int i) {
+ KeyRecord record = (KeyRecord) mVlist.getElementAt(i);
+
+ if (record == null) return null;
+
+ return record;
+ }
+ /**
+ * Retrieves requests.
+ */
+ public Enumeration getKeyRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector entries = new Vector();
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = mVlist.getElementAt(i);
+
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ if (entries != null) {
+ return entries.elements();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java
new file mode 100644
index 000000000..eaaf3779f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java
@@ -0,0 +1,111 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a mapper to serialize
+ * key record into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordMapper implements IDBAttrMapper {
+
+ private IKeyRepository mDB = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ public KeyRecordMapper(IKeyRepository db) {
+ mDB = db;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ try {
+ KeyRecord rec = (KeyRecord) obj;
+
+ attrs.add(new LDAPAttribute(KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID,
+ rec.getSerialNumber().toString()));
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps object to ldap attribute set
+ * @message KeyRecordMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_KEYRECORD_MAPPER_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID);
+
+ if (attr == null)
+ return;
+ String serialno = (String) attr.getStringValues().nextElement();
+ IKeyRecord rec = mDB.readKeyRecord(new
+ BigInteger(serialno));
+
+ parent.set(name, rec);
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps ldap attribute set to object
+ * @message KeyRecordMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_KEYRECORD_MAPPER_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return name + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
new file mode 100644
index 000000000..06b5f2614
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
@@ -0,0 +1,553 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.dbs.*;
+
+
+/**
+ * A class represents a Key repository. This is the container of
+ * archived keys.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRepository extends Repository implements IKeyRepository {
+
+ public KeyStatusUpdateThread mKeyStatusUpdateThread = null;
+ protected IDBSubsystem mDBService = null;
+
+ /**
+ * Internal constants
+ */
+ private String mBaseDN = null;
+
+ /**
+ * Constructs a key repository. It checks if the key repository
+ * does exist. If not, it creates the repository.
+ * <P>
+ *
+ * @param service db service
+ * @exception EBaseException failed to setup key repository
+ */
+ public KeyRepository(IDBSubsystem service, int increment, String baseDN)
+ throws EDBException {
+ super(service, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = service;
+
+ // register key record schema
+ IDBRegistry reg = service.getRegistry();
+ String keyRecordOC[] = new String[2];
+
+ keyRecordOC[0] = KeyDBSchema.LDAP_OC_TOP;
+ keyRecordOC[1] = KeyDBSchema.LDAP_OC_KEYRECORD;
+
+ if (!reg.isObjectClassRegistered(KeyRecord.class.getName())) {
+ reg.registerObjectClass(KeyRecord.class.getName(),
+ keyRecordOC);
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ID)) {
+ reg.registerAttribute(KeyRecord.ATTR_ID, new
+ BigIntegerMapper(KeyDBSchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ALGORITHM)) {
+ reg.registerAttribute(KeyRecord.ATTR_ALGORITHM, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_ALGORITHM));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_STATE)) {
+ reg.registerAttribute(KeyRecord.ATTR_STATE, new
+ KeyStateMapper(KeyDBSchema.LDAP_ATTR_STATE));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_KEY_SIZE)) {
+ reg.registerAttribute(KeyRecord.ATTR_KEY_SIZE, new
+ IntegerMapper(KeyDBSchema.LDAP_ATTR_KEY_SIZE));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_OWNER_NAME)) {
+ reg.registerAttribute(KeyRecord.ATTR_OWNER_NAME, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_OWNER_NAME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_PRIVATE_KEY_DATA)) {
+ reg.registerAttribute(KeyRecord.ATTR_PRIVATE_KEY_DATA, new
+ ByteArrayMapper(KeyDBSchema.LDAP_ATTR_PRIVATE_KEY_DATA));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_PUBLIC_KEY_DATA)) {
+ reg.registerAttribute(KeyRecord.ATTR_PUBLIC_KEY_DATA, new
+ PublicKeyMapper(KeyDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_DATE_OF_RECOVERY)) {
+ reg.registerAttribute(KeyRecord.ATTR_DATE_OF_RECOVERY, new
+ DateArrayMapper(KeyDBSchema.LDAP_ATTR_DATE_OF_RECOVERY));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_CREATE_TIME)) {
+ reg.registerAttribute(KeyRecord.ATTR_CREATE_TIME, new
+ DateMapper(KeyDBSchema.LDAP_ATTR_CREATE_TIME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_MODIFY_TIME)) {
+ reg.registerAttribute(KeyRecord.ATTR_MODIFY_TIME, new
+ DateMapper(KeyDBSchema.LDAP_ATTR_MODIFY_TIME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_META_INFO)) {
+ reg.registerAttribute(KeyRecord.ATTR_META_INFO, new
+ MetaInfoMapper(KeyDBSchema.LDAP_ATTR_META_INFO));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ARCHIVED_BY)) {
+ reg.registerAttribute(KeyRecord.ATTR_ARCHIVED_BY, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_ARCHIVED_BY));
+ }
+ }
+
+ public void setKeyStatusUpdateInterval(IRepository requestRepo, int interval) {
+ CMS.debug("In setKeyStatusUpdateInterval " + interval);
+ // don't run the thread if serial management is disabled.
+ if ((interval == 0) || (!mDBService.getEnableSerialMgmt())) {
+ CMS.debug("In setKeyStatusUpdateInterval interval = 0" + interval);
+ if (mKeyStatusUpdateThread != null) {
+ mKeyStatusUpdateThread.stop();
+ }
+ return;
+ }
+
+ CMS.debug("In setKeyStatusUpdateInterval mKeyStatusUpdateThread " + mKeyStatusUpdateThread);
+ if (mKeyStatusUpdateThread == null) {
+ CMS.debug("In setKeyStatusUpdateInterval about to create KeyStatusUpdateThread ");
+ mKeyStatusUpdateThread = new KeyStatusUpdateThread(this, requestRepo, "KeyStatusUpdateThread");
+ mKeyStatusUpdateThread.setInterval(interval);
+ mKeyStatusUpdateThread.start();
+ } else {
+ CMS.debug("In setKeyStatusUpdateInterval it thinks the thread is up already ");
+ mKeyStatusUpdateThread.setInterval(interval);
+ // dont do anything if we have a thread running already
+ }
+ }
+
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Retrieves the DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ String filter = "(" + KeyRecord.ATTR_OWNER_NAME + "=*" + ")";
+ IKeyRecordList list = findKeyRecordsInList(filter,
+ null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getKeyRecords(0, size - 1);
+ while (e.hasMoreElements()) {
+ KeyRecord rec = (KeyRecord) e.nextElement();
+ deleteKeyRecord(rec.getSerialNumber());
+ }
+ }
+
+ /**
+ * Archives a key to the repository.
+ * <P>
+ *
+ * @param record key record
+ * @exception EBaseException failed to archive key
+ */
+ public void addKeyRecord(IKeyRecord record) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ ((KeyRecord) record).getSerialNumber().toString() + "," + getDN();
+
+ if (s != null) s.add(name, (KeyRecord) record);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Recovers an archived key by serial number.
+ * <P>
+ *
+ * @param serialNo serial number
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ if (s != null) rec = (KeyRecord) s.read(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Recovers an archived key by owner name.
+ * <P>
+ *
+ * @param ownerName owner name
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(X500Name ownerName)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ KeyRecord keyRec = null;
+
+ try {
+ if (ownerName != null) {
+ String filter = "(" + KeyRecord.ATTR_OWNER_NAME + "=" +
+ ownerName.toString() + ")";
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ keyRec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return keyRec;
+ }
+
+ /**
+ * Recovers archived key using public key.
+ */
+ public IKeyRecord readKeyRecord(PublicKey publicKey)
+ throws EBaseException {
+ // XXX - setup binary search attributes
+ byte data[] = publicKey.getEncoded();
+
+ if (data == null)
+ throw new EBaseException("null data");
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String filter = "(" + KeyRecord.ATTR_PUBLIC_KEY_DATA + "=" +
+ escapeBinaryData(data) + ")";
+ if( s != null ) {
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ rec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+
+ /**
+ * Recovers archived key using b64 encoded cert
+ */
+ public IKeyRecord readKeyRecord(String cert)
+ throws EBaseException {
+
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String filter = "(publicKey=x509cert#\"" +cert+"\")";
+CMS.debug("filter= " + filter);
+
+ if( s != null ) {
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ rec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Modifies key record.
+ */
+ public void modifyKeyRecord(BigInteger serialNo, ModificationSet mods)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ mods.add(KeyRecord.ATTR_MODIFY_TIME, Modification.MOD_REPLACE,
+ new Date());
+ if (s != null) s.modify(name, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void deleteKeyRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Read RFC-2254
+ */
+ public static String escapeBinaryData(byte data[]) {
+ String result = "";
+
+ for (int i = 0; i < data.length; i++) {
+ result = result + "\\" + Integer.toHexString((int) data[i]);
+ }
+ return result;
+ }
+
+ public Enumeration searchKeys(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public Enumeration searchKeys(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getDN(), filter, maxSize, timeLimit);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves key record list.
+ */
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException {
+ return findKeyRecordsInList(filter, attrs, IKeyRecord.ATTR_ID,
+ pageSize);
+ }
+
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ IKeyRecordList list = null;
+
+ try {
+ if (s != null) {
+ list = new KeyRecordList(
+ s.createVirtualList(getDN(), "(&(objectclass=" +
+ KeyRecord.class.getName() + ")" + filter + ")",
+ attrs, sortKey, pageSize));
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return list;
+ }
+
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[],String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ IKeyRecordList list = null;
+
+ int len = jumpTo.length();
+
+ String jumpToVal = null;
+
+ if (len > 9) {
+ jumpToVal = Integer.toString(len) + jumpTo;
+ } else {
+ jumpToVal = "0" + Integer.toString(len) + jumpTo;
+ }
+
+ try {
+ if (s != null) {
+ list = new KeyRecordList(
+ s.createVirtualList(getDN(), "(&(objectclass=" +
+ KeyRecord.class.getName() + ")" + filter + ")",
+ attrs,jumpToVal, sortKey, pageSize));
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return list;
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) throws
+ EBaseException {
+
+ CMS.debug("KeyRepository: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0)
+ {
+ return null;
+ }
+
+ String ldapfilter = "(" + "serialno" + "=*" + ")";
+ String[] attrs = null;
+
+ KeyRecordList recList = (KeyRecordList) findKeyRecordsInList(ldapfilter,attrs,serial_upper_bound.toString(10),"serialno", 5 * -1);
+
+ int size = recList.getSize();
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange: recList size " + size);
+
+ if (size <= 0) {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange: index may be empty");
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + ret );
+ return ret;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("KeyRepository:getLastSerialNumberInRange: ltSize " + ltSize);
+
+ int i;
+ KeyRecord curRec = null;
+
+ for (i = 0; i < 5; i++) {
+ curRec = (KeyRecord) recList.getKeyRecord(i);
+
+ if (curRec != null) {
+
+ BigInteger serial = curRec.getSerialNumber();
+
+ CMS.debug("KeyRepository: getLastCertRecordSerialNo: serialno " + serial);
+
+ if( ((serial.compareTo(serial_low_bound) == 0) || (serial.compareTo(serial_low_bound) == 1) ) &&
+ ((serial.compareTo(serial_upper_bound) == 0) || (serial.compareTo(serial_upper_bound) == -1) ))
+ {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + serial);
+ return serial;
+ }
+ } else {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange:found null from getCertRecord");
+ }
+ }
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + ret );
+ return ret ;
+
+ }
+
+ public void shutdown() {
+ if (mKeyStatusUpdateThread != null)
+ mKeyStatusUpdateThread.destroy();
+ }
+
+}
+
+class KeyStatusUpdateThread extends Thread {
+ KeyRepository _kr = null;
+ IRepository _rr = null;
+ int _interval;
+
+ KeyStatusUpdateThread(KeyRepository kr, IRepository rr, String name) {
+ super(name);
+ CMS.debug("new KeyStatusUpdateThread");
+
+ _kr = kr;
+ _rr = rr;
+ }
+
+ public void setInterval(int interval) {
+ _interval = interval;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of KeyStatusUpdateThread");
+
+ while (true) {
+ try {
+ // block the update while another thread
+ // (such as the CRL Update) is running
+ CMS.debug("About to start checkRanges");
+ synchronized (_kr.mKeyStatusUpdateThread) {
+ CMS.debug("Starting key checkRanges");
+ _kr.checkRanges();
+ CMS.debug("key checkRanges done");
+
+ CMS.debug("Starting request checkRanges");
+ _rr.checkRanges();
+ CMS.debug("request checkRanges done");
+ }
+ } catch (Exception e) {
+ CMS.debug("key checkRanges done");
+ }
+ try {
+ sleep(_interval * 1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
+
+
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java
new file mode 100644
index 000000000..0630efa7c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java
@@ -0,0 +1,80 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+
+/**
+ * A class represents a key state mapper.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyStateMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+
+ public KeyStateMapper(String ldapName) {
+ mLdapName = ldapName;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(mLdapName);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((KeyState) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ parent.set(name, KeyState.toKeyState(
+ ((String) attr.getStringValues().nextElement())));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java b/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java
new file mode 100644
index 000000000..db5db02c9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java
@@ -0,0 +1,61 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a filter converter
+ * that understands how to convert a attribute
+ * type from one defintion to another.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class LdapFilterConverter implements IFilterConverter {
+
+ private Hashtable mReg = null;
+
+ /**
+ * Constructs filter convertor.
+ */
+ public LdapFilterConverter(Hashtable reg) {
+ mReg = reg;
+ }
+
+ /**
+ * Converts database filter to ldap filter.
+ */
+ public String convert(String name, String op, String value) {
+ AttributeNameHelper h = new AttributeNameHelper(name);
+ IDBAttrMapper mapper = (IDBAttrMapper) mReg.get(
+ h.getPrefix().toLowerCase());
+
+ if (mapper == null)
+ return null;
+ try {
+ return mapper.mapSearchFilter(name, op, value);
+ } catch (EBaseException e) {
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java
new file mode 100644
index 000000000..9006081f5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java
@@ -0,0 +1,117 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Long object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class LongMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs Long mapper.
+ */
+ public LongMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ LongToDB((Long) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, LongFromDB(
+ (String) attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String v = null;
+
+ try {
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ v = LongToDB(Long.valueOf(value.substring(2), 16));
+ } else {
+ v = LongToDB(Long.valueOf(value));
+ }
+ } catch (NumberFormatException e) {
+ v = value;
+ }
+ return mLdapName + op + v;
+ }
+
+ public static String LongToDB(Long i) {
+ int len = i.toString().length();
+ String ret = null;
+
+ if (len < 10) {
+ ret = "0" + Integer.toString(len) + i.toString();
+ } else {
+ ret = Integer.toString(len) + i.toString();
+ }
+ return ret;
+ }
+
+ public static Long LongFromDB(String i) {
+ String s = i.substring(2);
+
+ // possibly check length
+ return new Long(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java
new file mode 100644
index 000000000..c3248ec12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java
@@ -0,0 +1,119 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represent mapper for metainfo attribute. Metainfo
+ * is in format of the following:
+ *
+ * <PRE>
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * </PRE>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class MetaInfoMapper implements IDBAttrMapper {
+
+ public static final String SEP = ":";
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a metainfo object.
+ */
+ public MetaInfoMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ MetaInfo info = (MetaInfo) obj;
+ Enumeration e = info.getElements();
+
+ if (!e.hasMoreElements())
+ return; // dont add anything
+ LDAPAttribute attr = new LDAPAttribute(mLdapName);
+
+ while (e.hasMoreElements()) {
+ String s = null;
+ String attrName = (String) e.nextElement();
+ String value = (String) info.get(attrName);
+
+ s = attrName + SEP + value;
+ attr.addValue(s);
+ }
+ attrs.add(attr);
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object into
+ * 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration values = attr.getStringValues();
+ MetaInfo info = new MetaInfo();
+
+ while (values.hasMoreElements()) {
+ String s = (String) values.nextElement();
+ StringTokenizer st = new StringTokenizer(s, SEP);
+
+ info.set(st.nextToken(), st.nextToken());
+ }
+ parent.set(name, info);
+ }
+
+ /**
+ * Map search filters into LDAP search filter.
+ * Possible search filter:
+ * (&(metaInfo=reserver0:value0)(metaInfo=reserved1:value1))
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java
new file mode 100644
index 000000000..5c02b4014
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java
@@ -0,0 +1,135 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+import netscape.ldap.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.logging.ILogger;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ObjectStreamMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs object stream mapper.
+ */
+ public ObjectStreamMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(obj);
+ byte data[] = bos.toByteArray();
+ if (data == null) {
+ CMS.debug("ObjectStreamMapper:mapObjectToLDAPAttributeSet " +
+ name + " size=0");
+ } else {
+ CMS.debug("ObjectStreamMapper:mapObjectToLDAPAttributeSet " +
+ name + " size=" + data.length);
+ }
+ attrs.add(new LDAPAttribute(mLdapName,
+ data));
+ } catch (IOException e) {
+
+ /*LogDoc
+ *
+ * @phase Maps object to ldap attribute set
+ * @message ObjectStreamMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_OBJECTSTREAM_MAPPER_ERROR",
+ e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ (byte[]) attr.getByteValues().nextElement());
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ parent.set(name, is.readObject());
+ } catch (IOException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ } catch (ClassNotFoundException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java
new file mode 100644
index 000000000..4d93f843a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java
@@ -0,0 +1,150 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents an attribute mapper that maps
+ * a public key data into LDAP attribute and
+ * vice versa.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class PublicKeyMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a byte array mapper.
+ */
+ public PublicKeyMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Lists a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName, (byte[]) obj));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ parent.set(name, (byte[]) attr.getByteValues().nextElement());
+ }
+
+ /**
+ * Maps search filters into LDAP search filter. It knows
+ * how to extract public key from the certificate.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ int i = value.indexOf("#");
+
+ if (i != -1) {
+ String tag = value.substring(0, i);
+ String val = value.substring(i + 1);
+
+ try {
+ if (val.startsWith("\"")) {
+ val = val.substring(1, val.length() - 1);
+ }
+ X509Certificate cert = CertUtils.mapCert(val);
+ PublicKey key = cert.getPublicKey();
+ byte pub[] = key.getEncoded();
+
+ return mLdapName + op + escapeBinaryData(pub);
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps search filters into LDAP search filter
+ * @message PublicKeyMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_PUBLICKEY_MAPPER_ERROR",
+ e.toString()));
+ }
+ }
+ return mLdapName + op + value;
+ }
+
+ private String normalize(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ public static String escapeBinaryData(byte data[]) {
+ String result = "";
+
+ for (int i = 0; i < data.length; i++) {
+ int v = 0xff & data[i];
+
+ result = result + "\\" + (v < 16 ? "0" : "") +
+ Integer.toHexString(v);
+ }
+ return result;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java
new file mode 100644
index 000000000..ddf292b12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java
@@ -0,0 +1,82 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+
+/**
+ * A class represents a replica repository. It
+ * creates unique managed replica IDs.
+ * <P>
+ *
+ * @author alee
+ * @version $Revision$, $Date$
+ */
+public class ReplicaIDRepository extends Repository
+ implements IReplicaIDRepository {
+
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+
+ /**
+ * Constructs a certificate repository.
+ */
+ public ReplicaIDRepository(IDBSubsystem dbService, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = dbService;
+ }
+
+
+ /**
+ * Returns last serial number in given range
+ */
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+ CMS.debug("ReplicaIDReposoitory: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0 ) {
+ return null;
+ }
+ BigInteger ret = new BigInteger(getMinSerial());
+ if ((ret==null) || (ret.compareTo(serial_upper_bound) >0) || (ret.compareTo(serial_low_bound) <0)) {
+ return null;
+ }
+ return ret;
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java
new file mode 100644
index 000000000..df84b1156
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java
@@ -0,0 +1,504 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+
+/**
+ * A class represents a generic repository. It maintains unique
+ * serial number within repository.
+ * <P>
+ * To build domain specific repository, subclass should be
+ * created.
+ * <P>
+ *
+ * @author galperin
+ * @author thomask
+ * @version $Revision: 1.4
+ *
+ $, $Date$
+ */
+
+public abstract class Repository implements IRepository {
+
+ private static final BigInteger BI_ONE = new BigInteger("1");
+ private BigInteger BI_INCREMENT = null;
+ private static final BigInteger BI_ZERO = new BigInteger("0");
+ // (the next serialNo to be issued) - 1
+ private BigInteger mSerialNo = null;
+ // the serialNo attribute stored in db
+ private BigInteger mNext = null;
+
+ private String mMaxSerial = null;
+ private String mMinSerial = null;
+ private String mNextMaxSerial = null;
+ private String mNextMinSerial = null;
+
+ private BigInteger mMinSerialNo = null;
+ private BigInteger mMaxSerialNo = null;
+ private BigInteger mNextMinSerialNo = null;
+ private BigInteger mNextMaxSerialNo = null;
+
+ private BigInteger mIncrementNo = null;
+ private BigInteger mLowWaterMarkNo = null;
+
+ private IDBSubsystem mDB = null;
+ private String mBaseDN = null;
+ private boolean mInit = false;
+ private int mRadix = 10;
+ private int mRepo = -1;
+
+
+ private BigInteger mLastSerialNo = null;
+ /**
+ * Constructs a repository.
+ * <P>
+ */
+ public Repository(IDBSubsystem db, int increment, String baseDN)
+ throws EDBException {
+ mDB = db;
+ mBaseDN = baseDN;
+
+
+ BI_INCREMENT = new BigInteger(Integer.toString(increment));
+
+ // register schema
+ IDBRegistry reg = db.getRegistry();
+
+ /**
+ if (!reg.isObjectClassRegistered(
+ RepositoryRecord.class.getName())) {
+ String repRecordOC[] = new String[2];
+ repRecordOC[0] = RepositorySchema.LDAP_OC_TOP;
+ repRecordOC[1] = RepositorySchema.LDAP_OC_REPOSITORY;
+ reg.registerObjectClass(
+ RepositoryRecord.class.getName(), repRecordOC);
+ }
+ if (!reg.isAttributeRegistered(RepositoryRecord.ATTR_SERIALNO)) {
+ reg.registerAttribute(RepositoryRecord.ATTR_SERIALNO,
+ new BigIntegerMapper(RepositorySchema.LDAP_ATTR_SERIALNO));
+ }
+ **/
+ }
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException
+ {
+ IDBSSession s = mDB.createSession();
+
+ try {
+ String name = mBaseDN;
+ ModificationSet mods = new ModificationSet();
+ mods.add(IRepositoryRecord.ATTR_SERIALNO,
+ Modification.MOD_REPLACE, serial);
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Retrieves the next serial number attr in db.
+ * <P>
+ *
+ * @return next serial number
+ */
+ protected BigInteger getSerialNumber() throws EBaseException {
+ IDBSSession s = mDB.createSession();
+
+ CMS.debug("Repository: getSerialNumber.");
+ RepositoryRecord rec = null;
+
+ try {
+ if (s != null) rec = (RepositoryRecord) s.read(mBaseDN);
+ } finally {
+ if (s != null) s.close();
+ }
+
+ if( rec == null ) {
+ CMS.debug( "Repository::getSerialNumber() - "
+ + "- rec is null!" );
+ throw new EBaseException( "rec is null" );
+ }
+
+ BigInteger serial = rec.getSerialNumber();
+
+ if (!mInit) {
+ // cms may crash after issue a cert but before update
+ // the serial number record
+ try {
+ IDBObj obj = s.read("cn=" +
+ serial + "," + mBaseDN);
+
+ if (obj != null) {
+ serial = serial.add(BI_ONE);
+ setSerialNumber(serial);
+ }
+ }catch (EBaseException e) {
+ // do nothing
+ }
+ mInit = true;
+ }
+ return serial;
+ }
+
+ /**
+ * Updates the serial number to the specified in db.
+ * <P>
+ *
+ * @param num serial number
+ */
+ protected void setSerialNumber(BigInteger num) throws EBaseException {
+
+ CMS.debug("Repository:setSerialNumber " + num.toString());
+
+ return;
+
+ }
+
+ /**
+ * Get the maximum serial number.
+ *
+ * @return maximum serial number
+ */
+ public String getMaxSerial() {
+ return mMaxSerial;
+ }
+
+ /**
+ * Set the maximum serial number.
+ *
+ * @param serial maximum number
+ * @exception EBaseException failed to set maximum serial number
+ */
+ public void setMaxSerial(String serial) throws EBaseException {
+ BigInteger maxSerial = null;
+ CMS.debug("Repository:setMaxSerial " + serial);
+
+ maxSerial = new BigInteger(serial, mRadix);
+ if (maxSerial != null) {
+ mMaxSerial = serial;
+ mMaxSerialNo = maxSerial;
+ }
+ }
+
+ /**
+ * Get the maximum serial number in next range.
+ *
+ * @return maximum serial number in next range
+ */
+ public String getNextMaxSerial() {
+ return mNextMaxSerial;
+ }
+
+ /**
+ * Set the maximum serial number in next range
+ *
+ * @param serial maximum number in next range
+ * @exception EBaseException failed to set maximum serial number in next range
+ */
+ public void setNextMaxSerial(String serial) throws EBaseException {
+ BigInteger maxSerial = null;
+ CMS.debug("Repository:setNextMaxSerial " + serial);
+
+ maxSerial = new BigInteger(serial, mRadix);
+ if (maxSerial != null) {
+ mNextMaxSerial = serial;
+ mNextMaxSerialNo = maxSerial;
+ }
+
+ return;
+ }
+
+ /**
+ * Get the minimum serial number.
+ *
+ * @return minimum serial number
+ */
+ public String getMinSerial() {
+ return mMinSerial;
+ }
+
+
+ /**
+ * init serial number cache
+ */
+ private void initCache() throws EBaseException {
+ mNext = getSerialNumber();
+ BigInteger serialConfig = new BigInteger("0");
+ mRadix = 10;
+
+ CMS.debug("Repository: in InitCache");
+
+ if (this instanceof ICertificateRepository) {
+ CMS.debug("Repository: Instance of Certificate Repository.");
+ mRadix = 16;
+ mRepo = IDBSubsystem.CERTS;
+ } else if (this instanceof IKeyRepository) {
+ // Key Repository uses the same configuration parameters as Certificate
+ // Repository. This is ok because they are on separate subsystems.
+ CMS.debug("Repository: Instance of Key Repository");
+ mRadix = 16;
+ mRepo = IDBSubsystem.CERTS;
+ } else if (this instanceof IReplicaIDRepository) {
+ CMS.debug("Repository: Instance of Replica ID repository");
+ mRepo = IDBSubsystem.REPLICA_ID;
+ } else {
+ // CRLRepository subclasses this too, but does not use serial number stuff
+ CMS.debug("Repository: Instance of Request Repository or CRLRepository.");
+ mRepo = IDBSubsystem.REQUESTS;
+ }
+
+ mMinSerial = mDB.getMinSerialConfig(mRepo);
+ mMaxSerial = mDB.getMaxSerialConfig(mRepo);
+ mNextMinSerial = mDB.getNextMinSerialConfig(mRepo);
+ mNextMaxSerial = mDB.getNextMaxSerialConfig(mRepo);
+ String increment = mDB.getIncrementConfig(mRepo);
+ String lowWaterMark = mDB.getLowWaterMarkConfig(mRepo);
+
+ CMS.debug("Repository: minSerial " + mMinSerial + " maxSerial: " + mMaxSerial);
+
+ if(mMinSerial != null)
+ mMinSerialNo = new BigInteger(mMinSerial,mRadix);
+
+ if(mMaxSerial != null)
+ mMaxSerialNo = new BigInteger(mMaxSerial,mRadix);
+
+ if(mNextMinSerial != null)
+ mNextMinSerialNo = new BigInteger(mNextMinSerial,mRadix);
+
+ if(mNextMaxSerial != null)
+ mNextMaxSerialNo = new BigInteger(mNextMaxSerial,mRadix);
+
+ if(lowWaterMark != null)
+ mLowWaterMarkNo = new BigInteger(lowWaterMark,mRadix);
+
+ if(increment != null)
+ mIncrementNo = new BigInteger(increment,mRadix);
+
+ BigInteger theSerialNo = null;
+ theSerialNo = getLastSerialNumberInRange(mMinSerialNo,mMaxSerialNo);
+
+ if(theSerialNo != null) {
+
+ mLastSerialNo = new BigInteger(theSerialNo.toString());
+ CMS.debug("Repository: mLastSerialNo: " + mLastSerialNo.toString());
+
+ }
+ else {
+
+ throw new EBaseException("Error in obtaining the last serial number in the repository!");
+
+ }
+
+ }
+
+ /**
+ * get the next serial number in cache
+ */
+ public BigInteger getTheSerialNumber() throws EBaseException {
+
+ CMS.debug("Repository:In getTheSerialNumber " );
+ if (mLastSerialNo == null)
+ initCache();
+ BigInteger serial = new BigInteger((mLastSerialNo.add(BI_ONE)).toString());
+
+ if (mMaxSerialNo != null && serial.compareTo(mMaxSerialNo) > 0)
+ return null;
+ else
+ return serial;
+ }
+
+ /**
+ * Updates the serial number to the specified in db and cache.
+ * <P>
+ *
+ * @param num serial number
+ */
+ public void setTheSerialNumber(BigInteger num) throws EBaseException {
+ // mSerialNo is already set. But just in case
+
+ CMS.debug("Repository:In setTheSerialNumber " + num.toString());
+ if (mLastSerialNo == null)
+ initCache();
+
+ if (num.compareTo(mSerialNo) <= 0) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_SETBACK_SERIAL",
+ mSerialNo.toString(16)));
+ }
+ // write the config parameter. It's needed in case the serialNum gap
+ // < BI_INCREMENT and server restart right afterwards.
+ mDB.setNextSerialConfig(num);
+
+ mSerialNo = num.subtract(BI_ONE);
+ mNext = num.add(BI_INCREMENT);
+ setSerialNumber(mNext);
+ }
+
+ /**
+ * Retrieves the next serial number, and also increase the
+ * serial number by one.
+ * <P>
+ *
+ * @return serial number
+ */
+ public synchronized BigInteger getNextSerialNumber() throws
+ EBaseException {
+
+ CMS.debug("Repository: in getNextSerialNumber. ");
+
+ if (mLastSerialNo == null) {
+ initCache();
+
+ mLastSerialNo = mLastSerialNo.add(BI_ONE);
+
+
+ } else {
+ mLastSerialNo = mLastSerialNo.add(BI_ONE);
+ }
+
+ if( mLastSerialNo == null ) {
+ CMS.debug( "Repository::getNextSerialNumber() " +
+ "- mLastSerialNo is null!" );
+ throw new EBaseException( "mLastSerialNo is null" );
+ }
+
+ // check if we have reached the end of the range
+ // if so, move to next range
+ if (mLastSerialNo.compareTo( mMaxSerialNo ) > 0 ) {
+ if (mDB.getEnableSerialMgmt()) {
+ CMS.debug("Reached the end of the range. Attempting to move to next range");
+ mMinSerialNo = mNextMinSerialNo;
+ mMaxSerialNo = mNextMaxSerialNo;
+ mLastSerialNo = mMinSerialNo;
+ mNextMinSerialNo = null;
+ mNextMaxSerialNo = null;
+ if ((mMaxSerialNo == null) || (mMinSerialNo == null)) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED",
+ mLastSerialNo.toString()));
+ }
+
+ // persist the changes
+ mDB.setMinSerialConfig(mRepo, mMinSerialNo.toString());
+ mDB.setMaxSerialConfig(mRepo, mMaxSerialNo.toString());
+ mDB.setNextMinSerialConfig(mRepo, null);
+ mDB.setNextMaxSerialConfig(mRepo, null);
+ } else {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED",
+ mLastSerialNo.toString()));
+ }
+ }
+
+ BigInteger retSerial = new BigInteger(mLastSerialNo.toString());
+
+ CMS.debug("Repository: getNextSerialNumber: returning retSerial " + retSerial);
+ return retSerial;
+ }
+
+ /**
+ * Checks to see if a new range is needed, or if we have reached the end of the
+ * current range, or if a range conflict has occurred.
+ *
+ * @exception EBaseException failed to check next range for conflicts
+ */
+ public void checkRanges() throws EBaseException
+ {
+ if (!mDB.getEnableSerialMgmt()) {
+ CMS.debug("Serial Management not enabled. Returning .. ");
+ return;
+ }
+ if (CMS.getEESSLPort() == null) {
+ CMS.debug("Server not completely started. Returning ..");
+ return;
+ }
+
+ if (mLastSerialNo == null)
+ initCache();
+
+ BigInteger numsInRange = mMaxSerialNo.subtract(mLastSerialNo);
+ BigInteger numsInNextRange = null;
+ BigInteger numsAvail = null;
+ CMS.debug("Serial numbers left in range: " + numsInRange.toString());
+ CMS.debug("Last Serial Number: " + mLastSerialNo.toString());
+ if ((mNextMaxSerialNo != null) && (mNextMinSerialNo != null)) {
+ numsInNextRange = mNextMaxSerialNo.subtract(mNextMinSerialNo);
+ numsAvail = numsInRange.add(numsInNextRange);
+ CMS.debug("Serial Numbers in next range: " + numsInNextRange.toString());
+ CMS.debug("Serial Numbers available: " + numsAvail.toString());
+ } else {
+ numsAvail = numsInRange;
+ CMS.debug("Serial Numbers available: " + numsAvail.toString());
+ }
+
+ if ((numsAvail.compareTo(mLowWaterMarkNo) < 0) && (!CMS.isPreOpMode()) ) {
+ CMS.debug("Low water mark reached. Requesting next range");
+ mNextMinSerialNo = new BigInteger(mDB.getNextRange(mRepo), mRadix);
+ if (mNextMinSerialNo == null) {
+ CMS.debug("Next Range not available");
+ } else {
+ CMS.debug("nNextMinSerialNo has been set to " + mNextMinSerialNo.toString(mRadix));
+ mNextMaxSerialNo = mNextMinSerialNo.add(mIncrementNo);
+ numsAvail = numsAvail.add(mIncrementNo);
+ mDB.setNextMinSerialConfig(mRepo, mNextMinSerialNo.toString(mRadix));
+ mDB.setNextMaxSerialConfig(mRepo, mNextMaxSerialNo.toString(mRadix));
+ }
+ }
+
+ if (numsInRange.compareTo (mLowWaterMarkNo) < 0 ) {
+ // check for a replication error
+ CMS.debug("Checking for a range conflict");
+ if (mDB.hasRangeConflict(mRepo)) {
+ CMS.debug("Range Conflict found! Removing next range.");
+ mNextMaxSerialNo = null;
+ mNextMinSerialNo= null;
+ mDB.setNextMinSerialConfig(mRepo, null);
+ mDB.setNextMaxSerialConfig(mRepo, null);
+ }
+ }
+ }
+
+ /**
+ * Sets whether serial number management is enabled for certs
+ * and requests.
+ *
+ * @param value true/false
+ * @exception EBaseException failed to set
+ */
+ public void setEnableSerialMgmt(boolean value) throws EBaseException
+ {
+ mDB.setEnableSerialMgmt(value);
+ }
+
+ public abstract BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) throws
+ EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java
new file mode 100644
index 000000000..7aa63fa1d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java
@@ -0,0 +1,112 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * A class represents a repository record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RepositoryRecord implements IRepositoryRecord {
+
+ private BigInteger mSerialNo = null;
+ private String mPublishingStatus = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(IRepositoryRecord.ATTR_SERIALNO);
+ mNames.addElement(IRepositoryRecord.ATTR_PUB_STATUS);
+ }
+
+ /**
+ * Constructs a repository record.
+ * <P>
+ */
+ public RepositoryRecord() {
+ }
+
+ /**
+ * Sets attribute.
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_SERIALNO)) {
+ mSerialNo = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ mPublishingStatus = (String) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves attribute from this record.
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_SERIALNO)) {
+ return mSerialNo;
+ } else if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ return mPublishingStatus;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes an attribute.
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ /**
+ * Retrieves a list of attribute names.
+ */
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serial number.
+ */
+ public BigInteger getSerialNumber() {
+ return mSerialNo;
+ }
+
+ public String getPublishingStatus() {
+ return mPublishingStatus;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java
new file mode 100644
index 000000000..436c8633e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java
@@ -0,0 +1,44 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of repository-specific
+ * schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RepositorySchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_OC_REPOSITORY = "repository";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_PUB_STATUS = "publishingStatus";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java
new file mode 100644
index 000000000..81ae72053
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java
@@ -0,0 +1,81 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * A class represents a certificate revocation info. This
+ * object is written as an attribute of certificate record
+ * which essentially signifies a revocation act.
+ * <P>
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ */
+public class RevocationInfo implements IRevocationInfo, Serializable {
+
+ private Date mRevocationDate = null;
+ private CRLExtensions mCRLEntryExtensions = null;
+
+ /**
+ * Constructs revocation info.
+ */
+ public RevocationInfo() {
+ }
+
+ /**
+ * Constructs revocation info used by revocation
+ * request implementation.
+ *
+ * @param reason if not null contains CRL entry extension
+ * that specifies revocation reason
+ * @see CRLReasonExtension
+ */
+ public RevocationInfo(Date revocationDate, CRLExtensions exts) {
+ mRevocationDate = revocationDate;
+ mCRLEntryExtensions = exts;
+ }
+
+ /**
+ * Retrieves revocation date.
+ */
+ public Date getRevocationDate() {
+ return mRevocationDate;
+ }
+
+ /**
+ * Retrieves CRL extensions.
+ */
+ public CRLExtensions getCRLEntryExtensions() {
+ return mCRLEntryExtensions;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java
new file mode 100644
index 000000000..6ee2c7bb2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java
@@ -0,0 +1,167 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A class represents a mapper to serialize
+ * revocation information into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RevocationInfoMapper implements IDBAttrMapper {
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(CertDBSchema.LDAP_ATTR_REVO_INFO);
+ }
+
+ /**
+ * Constructs revocation information mapper.
+ */
+ public RevocationInfoMapper() {
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mNames.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ // in format of <date>;<extensions>
+ String value = "";
+ RevocationInfo info = (RevocationInfo) obj;
+ Date d = info.getRevocationDate();
+
+ value = DateMapper.dateToDB(d);
+ CRLExtensions exts = info.getCRLEntryExtensions();
+ // CRLExtension's DER encoding and decoding does not work!
+ // That is why we need to do our own serialization.
+ Enumeration e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ RevocationReason reason =
+ ((CRLReasonExtension) ext).getReason();
+
+ value = value + ";CRLReasonExtension=" +
+ Integer.toString(reason.toInt());
+ } else if (ext instanceof InvalidityDateExtension) {
+ Date invalidityDate =
+ ((InvalidityDateExtension) ext).getInvalidityDate();
+
+ value = value + ";InvalidityDateExtension=" +
+ DateMapper.dateToDB(invalidityDate);
+ } else {
+ Debug.trace("XXX skipped extension");
+ }
+ }
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_REVO_INFO,
+ value));
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_REVO_INFO);
+
+ if (attr == null)
+ return;
+ String value = (String) attr.getStringValues().nextElement();
+ int i = value.indexOf(';'); // look for 1st ";"
+ String str = null;
+ CRLExtensions exts = new CRLExtensions();
+ Date d = null;
+
+ if (i == -1) {
+ // only date found; no extensions
+ d = DateMapper.dateFromDB(value);
+ } else {
+ String s = value;
+
+ str = s.substring(0, i);
+ d = DateMapper.dateFromDB(str);
+ s = s.substring(i + 1);
+ do {
+ i = s.indexOf(';');
+ if (i == -1) {
+ str = s;
+ } else {
+ str = s.substring(0, i);
+ s = s.substring(i + 1);
+ }
+ if (str.startsWith("CRLReasonExtension=")) {
+ String reasonStr = str.substring(19);
+ RevocationReason reason = RevocationReason.fromInt(
+ Integer.parseInt(reasonStr));
+ CRLReasonExtension ext = new CRLReasonExtension(reason);
+
+ exts.set(CRLReasonExtension.NAME, ext);
+ } else if (str.startsWith("InvalidityDateExtension=")) {
+ String invalidityDateStr = str.substring(24);
+ Date invalidityDate = DateMapper.dateFromDB(invalidityDateStr);
+ InvalidityDateExtension ext =
+ new InvalidityDateExtension(invalidityDate);
+
+ exts.set(InvalidityDateExtension.NAME, ext);
+ } else {
+ Debug.trace("XXX skipped extension");
+ }
+ }
+ while (i != -1);
+ }
+ RevocationInfo info = new RevocationInfo(d, exts);
+
+ parent.set(name, info);
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return CertDBSchema.LDAP_ATTR_REVO_INFO + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java
new file mode 100644
index 000000000..e9fbd64e7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java
@@ -0,0 +1,91 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java String object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StringMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs string mapper.
+ */
+ public StringMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName, (String) obj));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent)
+ throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ try {
+ parent.set(name, (String)
+ attr.getStringValues().nextElement());
+ } catch (NoSuchElementException e) {
+ // attribute present, but without value
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java
new file mode 100644
index 000000000..2ec203eb6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java
@@ -0,0 +1,106 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java String object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StringVectorMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs string vector mapper.
+ */
+ public StringVectorMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ Vector v = (Vector) obj;
+ int s = v.size();
+
+ if (s == 0) {
+ return;
+ }
+ String m[] = new String[s];
+
+ for (int i = 0; i < s; i++) {
+ m[i] = (String) v.elementAt(i);
+ }
+ attrs.add(new LDAPAttribute(mLdapName, m));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration e = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ v.addElement((String) e.nextElement());
+ }
+ if (v.size() == 0)
+ return;
+ String m[] = new String[v.size()];
+
+ v.copyInto(m);
+ parent.set(name, m);
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java
new file mode 100644
index 000000000..b7e386f77
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java
@@ -0,0 +1,107 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java X500Name object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class X500NameMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs X500Name mapper.
+ */
+ public X500NameMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((X500Name) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ try {
+ parent.set(name, new X500Name((String)
+ attr.getStringValues().nextElement()));
+ } catch (IOException e) {
+
+ /*LogDoc
+ *
+ * @phase Maps LDAP attributes into object
+ * @message X500NameMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_X500NAME_MAPPER_ERROR",
+ e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java
new file mode 100644
index 000000000..29e1db849
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java
@@ -0,0 +1,363 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A class represents a mapper to serialize
+ * x509 certificate into database.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class X509CertImplMapper implements IDBAttrMapper {
+
+ public X509CertImplMapper() {
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(CertDBSchema.LDAP_ATTR_NOT_BEFORE);
+ v.addElement(CertDBSchema.LDAP_ATTR_NOT_AFTER);
+ v.addElement(CertDBSchema.LDAP_ATTR_DURATION);
+ v.addElement(CertDBSchema.LDAP_ATTR_EXTENSION);
+ v.addElement(CertDBSchema.LDAP_ATTR_SUBJECT);
+ v.addElement(CertDBSchema.LDAP_ATTR_SIGNED_CERT);
+ v.addElement(CertDBSchema.LDAP_ATTR_VERSION);
+ v.addElement(CertDBSchema.LDAP_ATTR_ALGORITHM);
+ v.addElement(CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM);
+ v.addElement(CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ try {
+ X509CertImpl cert = (X509CertImpl) obj;
+ // make information searchable
+ Date notBefore = cert.getNotBefore();
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_NOT_BEFORE,
+ DateMapper.dateToDB(notBefore)));
+ Date notAfter = cert.getNotAfter();
+
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_NOT_AFTER,
+ DateMapper.dateToDB(notAfter)));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_DURATION,
+ DBSUtil.longToDB(notAfter.getTime() - notBefore.getTime())));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_SUBJECT,
+ cert.getSubjectDN().getName()));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA, cert.getPublicKey().getEncoded()));
+ // make extension searchable
+ Set nonCritSet = cert.getNonCriticalExtensionOIDs();
+
+ if (nonCritSet != null) {
+ for (Iterator i = nonCritSet.iterator(); i.hasNext();) {
+ String oid = (String) i.next();
+
+ if (oid.equals("2.16.840.1.113730.1.1")) {
+ String extVal = getCertTypeExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ } else if (oid.equals("2.5.29.19")) {
+ String extVal = getBasicConstraintsExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ }
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_EXTENSION, oid));
+ }
+ }
+ Set critSet = cert.getCriticalExtensionOIDs();
+
+ if (critSet != null) {
+ for (Iterator i = critSet.iterator(); i.hasNext();) {
+ String oid = (String) i.next();
+
+ if (oid.equals("2.16.840.1.113730.1.1")) {
+ String extVal = getCertTypeExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ } else if (oid.equals("2.5.29.19")) {
+ String extVal = getBasicConstraintsExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ }
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_EXTENSION, oid));
+ }
+ }
+
+ // something extra; so that we can rebuild the
+ // object quickly
+ // if we dont add ";binary", communicator does
+ // not know how to display the certificate in
+ // pretty print format.
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT + ";binary",
+ cert.getEncoded()));
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_VERSION,
+ Integer.toString(cert.getVersion())));
+ X509Key pubKey = (X509Key) cert.getPublicKey();
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_ALGORITHM,
+ pubKey.getAlgorithmId().getOID().toString()));
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM,
+ cert.getSigAlgOID()));
+ } catch (CertificateEncodingException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ private String getCertTypeExtensionInfo(X509CertImpl cert) {
+ try {
+ Extension ext = cert.getExtension("2.16.840.1.113730.1.1");
+
+ if (ext == null) {
+ // sometime time (during installation) it
+ // is named differently
+ ext = cert.getExtension(NSCertTypeExtension.NAME);
+ if (ext == null)
+ return null;
+ }
+ NSCertTypeExtension nsExt = (NSCertTypeExtension) ext;
+
+ String result = "";
+
+ Boolean sslServer = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_SERVER);
+
+ result += "SSLServer=" + sslServer.toString() + ",";
+ Boolean sslClient = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_CLIENT);
+
+ result += "SSLClient=" + sslClient.toString() + ",";
+ Boolean email = (Boolean) nsExt.get(
+ NSCertTypeExtension.EMAIL);
+
+ result += "Email=" + email.toString() + ",";
+ Boolean sslCA = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_CA);
+
+ result += "SSLCA=" + sslCA.toString() + ",";
+ Boolean mailCA = (Boolean) nsExt.get(
+ NSCertTypeExtension.EMAIL_CA);
+
+ result += "EmailCA=" + mailCA.toString() + ",";
+ Boolean objectSigning = (Boolean) nsExt.get(
+ NSCertTypeExtension.OBJECT_SIGNING);
+
+ result += "objectSigning=" +
+ objectSigning.toString();
+ return result;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private String getBasicConstraintsExtensionInfo(X509CertImpl cert) {
+ try {
+ Extension ext = cert.getExtension("2.5.29.19");
+
+ if (ext == null) {
+ // sometime time (during installation) it
+ // is named differently
+ ext = cert.getExtension(BasicConstraintsExtension.NAME);
+ if (ext == null)
+ return null;
+ }
+ BasicConstraintsExtension bcExt = (BasicConstraintsExtension) ext;
+
+ String result = "";
+
+ Boolean isCA = (Boolean) bcExt.get(
+ BasicConstraintsExtension.IS_CA);
+
+ result += "isCA=" + isCA.toString() + ",";
+ Integer pathLen = (Integer) bcExt.get(
+ BasicConstraintsExtension.PATH_LEN);
+
+ result += "pathLen=" + pathLen.toString();
+ return result;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ // rebuild object quickly using binary image
+ // XXX bad! when we add this attribute,
+ // we add it as userCertificate, but when
+ // we retrieve it, DS returns it as
+ // userCertificate;binary. So I cannot do the
+ // following:
+ // LDAPAttribute attr = attrs.getAttribute(
+ // Schema.LDAP_ATTR_SIGNED_CERT);
+
+ X509CertInfo certinfo = new X509CertInfo();
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT);
+
+ if (attr == null) {
+ // YUK!
+ attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT + ";binary");
+ }
+ if (attr != null) {
+ byte der[] = (byte[])
+ attr.getByteValues().nextElement();
+ X509CertImpl impl = new X509CertImpl(der);
+
+ parent.set(name, impl);
+ }
+ } catch (CertificateException e) {
+ //throw new EDBException(
+ // DBResources.FAILED_TO_DESERIALIZE_1, name);
+ parent.set(name, null);
+ } catch (Exception e) {
+ //throw new EDBException(
+ // DBResources.FAILED_TO_DESERIALIZE_1, name);
+ parent.set(name, null);
+
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ AttributeNameHelper h = new AttributeNameHelper(name);
+ String suffix = h.getSuffix();
+
+ if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_NOT_BEFORE)) {
+ name = CertDBSchema.LDAP_ATTR_NOT_BEFORE;
+ try {
+ value = DateMapper.dateToDB(new
+ Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ }
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_NOT_AFTER)) {
+ name = CertDBSchema.LDAP_ATTR_NOT_AFTER;
+ try {
+ value = DateMapper.dateToDB(new
+ Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ }
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SUBJECT)) {
+ name = CertDBSchema.LDAP_ATTR_SUBJECT;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_PUBLIC_KEY_DATA)) {
+ name = CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_DURATION)) {
+ name = CertDBSchema.LDAP_ATTR_DURATION;
+ value = DBSUtil.longToDB(Long.parseLong(value));
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_VERSION)) {
+ name = CertDBSchema.LDAP_ATTR_VERSION;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_ALGORITHM)) {
+ name = CertDBSchema.LDAP_ATTR_ALGORITHM;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SIGNING_ALGORITHM)) {
+ name = CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SERIAL_NUMBER)) {
+ name = CertDBSchema.LDAP_ATTR_CERT_RECORD_ID;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_EXTENSION)) {
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.ATTR_REVO_INFO)) {
+ name = CertDBSchema.LDAP_ATTR_REVO_INFO;
+ value = "*;CRLReasonExtension=" + value + "*";
+ } else if (suffix.equalsIgnoreCase("nsExtension.SSLClient")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLClient=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLClient=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SSLServer")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLServer=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLServer=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SecureEmail")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*Email=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*Email=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SubordinateSSLCA")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLCA=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLCA=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SubordinateEmailCA")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*EmailCA=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*EmailCA=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("BasicConstraints.isCA")) {
+ // special case for Basic Constraints extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.5.29.19;*isCA=true*";
+ } else {
+ value = "2.5.29.19;*isCA=false*";
+ }
+ }
+ return name + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java b/pki/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java
new file mode 100644
index 000000000..aceb6f1bf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java
@@ -0,0 +1,159 @@
+// --- 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.cmscore.extensions;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+import netscape.security.x509.Extension;
+import netscape.security.util.ObjectIdentifier;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.extensions.*;
+
+
+/**
+ * Loads extension classes from configuration file and return
+ * for a given extension name or OID.
+ */
+public class CMSExtensionsMap implements ISubsystem {
+ public static String ID = "extensions";
+
+ private static CMSExtensionsMap mInstance = new CMSExtensionsMap();
+
+ public static final CMSExtensionsMap getInstance() {
+ return mInstance;
+ }
+
+ private CMSExtensionsMap() {
+ }
+
+ private static final String PROP_CLASS = "class";
+
+ private Hashtable mName2Ext = new Hashtable();
+ private Hashtable mOID2Ext = new Hashtable();
+ private ISubsystem mOwner = null;
+ private IConfigStore mConfig = null;
+
+ /**
+ * Create extensions from configuration store.
+ * @param config the configuration store.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOwner = owner;
+ mConfig = config;
+
+ Enumeration sstores = mConfig.getSubStoreNames();
+
+ while (sstores.hasMoreElements()) {
+ String name = (String) sstores.nextElement();
+ IConfigStore c = mConfig.getSubStore(name);
+
+ String className = c.getString(PROP_CLASS);
+ ICMSExtension ext = null;
+
+ try {
+ ext = (ICMSExtension) Class.forName(className).newInstance();
+ ext.init(this, c);
+ addExt(ext);
+ } catch (ClassNotFoundException e) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_CLASS_NOT_FOUND", className));
+ } catch (IllegalAccessException e) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_INSTANTIATE_ERROR",
+ className, e.toString()));
+ } catch (InstantiationException e) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_INSTANTIATE_ERROR",
+ className, e.toString()));
+ } catch (ClassCastException e) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_INVALID_IMPL", className));
+ }
+ }
+ }
+
+ public void addExt(ICMSExtension ext) throws EBaseException {
+ String name = ext.getName();
+ ObjectIdentifier oid = ext.getOID();
+
+ if (name == null || oid == null) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_INCORRECT_IMPL",
+ ext.getClass().getName()));
+ }
+ mName2Ext.put(name, ext);
+ mOID2Ext.put(oid.toString(), ext);
+ }
+
+ /**
+ * startup - does nothing.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * shutdown - does nothing.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * Get configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Returns subsystem ID
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * sets subsystem ID
+ */
+ public void setId(String Id) {
+ }
+
+ /**
+ * Get the extension class by name.
+ * @param name name of the extension
+ * @return the extension class.
+ */
+ public ICMSExtension getByName(String name) {
+ return (ICMSExtension) mName2Ext.get(name);
+ }
+
+ /**
+ * Get the extension class by its OID.
+ * @param oid - the OID of the extension.
+ * @return the extension class.
+ */
+ public ICMSExtension getByOID(ObjectIdentifier oid) {
+ return (ICMSExtension) mOID2Ext.get(oid.toString());
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java b/pki/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java
new file mode 100644
index 000000000..db618f6f0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java
@@ -0,0 +1,239 @@
+// --- 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.cmscore.extensions;
+
+
+import java.io.IOException;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.extensions.*;
+
+import netscape.security.x509.Extension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.DerOutputStream;
+
+import com.netscape.cmscore.util.*;
+
+
+public class KeyUsage implements ICMSExtension {
+ private final static String NAME = "KeyUsageExtension";
+ private final static ObjectIdentifier OID = PKIXExtensions.KeyUsage_Id;
+
+ private IConfigStore mConfig = null;
+ private boolean mSetDefault = false;
+
+ private ILogger mLogger;
+
+ public KeyUsage(boolean setDefault) {
+ mSetDefault = setDefault;
+ mLogger = CMS.getLogger();
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // nothing to do here.
+ mConfig = config;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public ObjectIdentifier getOID() {
+ return OID;
+ }
+
+ protected static final boolean[] DEF_BITS =
+ new boolean[KeyUsageExtension.NBITS];
+
+ static {
+ // set default bits used when request missing key usage info.
+ DEF_BITS[KeyUsageExtension.DIGITAL_SIGNATURE_BIT] = true;
+ DEF_BITS[KeyUsageExtension.NON_REPUDIATION_BIT] = false;
+ DEF_BITS[KeyUsageExtension.KEY_ENCIPHERMENT_BIT] = true;
+ DEF_BITS[KeyUsageExtension.DATA_ENCIPHERMENT_BIT] = true;
+ DEF_BITS[KeyUsageExtension.KEY_AGREEMENT_BIT] = false;
+ DEF_BITS[KeyUsageExtension.KEY_CERTSIGN_BIT] = false;
+ DEF_BITS[KeyUsageExtension.CRL_SIGN_BIT] = false;
+ DEF_BITS[KeyUsageExtension.ENCIPHER_ONLY_BIT] = false;
+ DEF_BITS[KeyUsageExtension.DECIPHER_ONLY_BIT] = false;
+ }
+
+ private static boolean getBoolean(Object value) {
+ String val = (String) value;
+
+ if (val != null &&
+ (val.equalsIgnoreCase("true") || val.equalsIgnoreCase("on")))
+ return true;
+ else
+ return false;
+ }
+
+ public Extension getExtension(IArgBlock args) throws EBaseException {
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+ Object[] values = new Object[KeyUsageExtension.NBITS];
+ int bit;
+
+ // check if no bits are set. If not set default bits.
+ bit = KeyUsageExtension.DIGITAL_SIGNATURE_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.NON_REPUDIATION_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.KEY_ENCIPHERMENT_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.DATA_ENCIPHERMENT_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.KEY_AGREEMENT_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.KEY_CERTSIGN_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.CRL_SIGN_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.ENCIPHER_ONLY_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+ bit = KeyUsageExtension.DECIPHER_ONLY_BIT;
+ values[bit] = args.get(KeyUsageExtension.names[bit]);
+
+ // if nothing is set, make one with default set of bits.
+ int i;
+
+ for (i = 0; i < KeyUsageExtension.NBITS; i++) {
+ if (values[i] != null && (values[i] instanceof String))
+ break;
+ }
+ if (i == KeyUsageExtension.NBITS && mSetDefault) {
+ // no key usage extension parameters are requested. set default.
+ CMS.debug(
+ "No Key usage bits requested. Setting default.");
+ bits = DEF_BITS;
+ } else {
+ bit = KeyUsageExtension.DIGITAL_SIGNATURE_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.NON_REPUDIATION_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.KEY_ENCIPHERMENT_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.DATA_ENCIPHERMENT_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.KEY_AGREEMENT_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.KEY_CERTSIGN_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.CRL_SIGN_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.ENCIPHER_ONLY_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ bit = KeyUsageExtension.DECIPHER_ONLY_BIT;
+ bits[bit] = getBoolean(values[bit]);
+ if (Debug.ON)
+ Debug.trace("Requested key usage bit " + bit + " " + bits[bit]);
+ }
+
+ try {
+ int j = 0;
+
+ for (j = 0; j < bits.length; j++) {
+ if (bits[j])
+ break;
+ }
+ if (j == bits.length) {
+ if (!mSetDefault)
+ return null;
+ else
+ bits = DEF_BITS;
+ }
+ return new KeyUsageExtension(bits);
+ } catch (IOException e) {
+ throw new EExtensionsException(
+ CMS.getUserMessage("CMS_EXTENSION_CREATING_EXT_ERROR", NAME));
+ }
+ }
+
+ public IArgBlock getFormParams(Extension extension)
+ throws EBaseException {
+ KeyUsageExtension ext = null;
+
+ if (!extension.getExtensionId().equals(PKIXExtensions.KeyUsage_Id)) {
+ return null;
+ }
+ if (extension instanceof KeyUsageExtension) {
+ ext = (KeyUsageExtension) extension;
+ } else {
+ try {
+ DerOutputStream der = new DerOutputStream();
+ byte[] value = extension.getExtensionValue();
+
+ ext = new KeyUsageExtension(new Boolean(true), value);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ IArgBlock params = CMS.createArgBlock();
+ boolean[] bits = ext.getBits();
+
+ params.set(KeyUsageExtension.DIGITAL_SIGNATURE,
+ String.valueOf(bits[KeyUsageExtension.DIGITAL_SIGNATURE_BIT]));
+ params.set(KeyUsageExtension.NON_REPUDIATION,
+ String.valueOf(bits[KeyUsageExtension.NON_REPUDIATION_BIT]));
+ params.set(KeyUsageExtension.KEY_ENCIPHERMENT,
+ String.valueOf(bits[KeyUsageExtension.KEY_ENCIPHERMENT_BIT]));
+ params.set(KeyUsageExtension.DATA_ENCIPHERMENT,
+ String.valueOf(bits[KeyUsageExtension.DATA_ENCIPHERMENT_BIT]));
+ params.set(KeyUsageExtension.KEY_AGREEMENT,
+ String.valueOf(bits[KeyUsageExtension.KEY_AGREEMENT_BIT]));
+ params.set(KeyUsageExtension.KEY_CERTSIGN,
+ String.valueOf(bits[KeyUsageExtension.KEY_CERTSIGN_BIT]));
+ params.set(KeyUsageExtension.CRL_SIGN,
+ String.valueOf(bits[KeyUsageExtension.CRL_SIGN_BIT]));
+ params.set(KeyUsageExtension.ENCIPHER_ONLY,
+ String.valueOf(bits[KeyUsageExtension.ENCIPHER_ONLY_BIT]));
+ params.set(KeyUsageExtension.DECIPHER_ONLY,
+ String.valueOf(bits[KeyUsageExtension.DECIPHER_ONLY_BIT]));
+ return params;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level, msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/jobs/CronItem.java b/pki/base/common/src/com/netscape/cmscore/jobs/CronItem.java
new file mode 100644
index 000000000..b97168163
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/jobs/CronItem.java
@@ -0,0 +1,167 @@
+// --- 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.cmscore.jobs;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+
+import java.util.*;
+
+
+/**
+ * class representing one Job cron item
+ * <p>here, an "item" refers to one of the 5 fields in a cron string;
+ * "element" refers to any comma-deliminated element in an
+ * "item"...which includes both numbers and '-' separated ranges.
+ * <p>
+ * for each of the 5 cron fields, it's represented as a CronItem
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CronItem {
+ protected static final String ALL = "*";
+ protected static final String DELIM = ",";
+ protected static final String RANGE = "-";
+ private ILogger mLogger = CMS.getLogger();
+
+ int mMin; // minimum
+ int mMax; // maximum
+
+ // store all elements in a field.
+ // elements can either be numbers or ranges (CronRange)
+ protected Vector mElements = new Vector();
+
+ public CronItem(int min, int max) {
+ mMin = min;
+ mMax = max;
+ }
+
+ /**
+ * parses and sets a string cron item
+ * @param sItem the string representing an item of a cron string.
+ * item can be potentially comma separated with ranges specified
+ * with '-'s
+ */
+ public void set(String sItem) throws EBaseException {
+
+ if (sItem.equals(ALL)) {
+ // System.out.println("CronItem set(): item is ALL");
+ CronRange cr = new CronRange();
+
+ cr.setBegin(mMin);
+ cr.setEnd(mMax);
+ mElements.addElement(cr);
+ } else {
+ // break comma-separated elements
+ StringTokenizer st = new StringTokenizer(sItem, DELIM);
+
+ while (st.hasMoreTokens()) {
+ String tok = (String) st.nextToken();
+ // elements could be ranges (separated by '-')
+ int r = tok.indexOf(RANGE);
+
+ if (r != -1) {
+ // potential range
+ String sBegin = tok.substring(0, r);
+ int begin = 0;
+ int end = 0;
+
+ try {
+ begin = Integer.parseInt(sBegin);
+ } catch (NumberFormatException e) {
+ // throw ...
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_INVALID_TOKEN", tok, e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ String sEnd = tok.substring(r + 1, tok.length());
+
+ try {
+ end = Integer.parseInt(sEnd);
+ } catch (NumberFormatException e) {
+ // throw ...
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_INVALID_TOKEN", tok, e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ // got both begin and end for range
+ CronRange cr = new CronRange();
+
+ cr.setBegin(begin);
+ cr.setEnd(end);
+ // check range
+ if (!cr.isValidRange(mMin, mMax)) {
+ // throw...
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_INVALID_RANGE",
+ tok));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ // System.out.println("CronItem set(): adding a range");
+ mElements.addElement(cr);
+ } else {
+ // number element, begin and end are the same
+ try {
+ CronRange cr = new CronRange();
+ int num = Integer.parseInt(tok);
+
+ cr.setBegin(num);
+ cr.setEnd(num);
+ // check range
+ if (!cr.isValidRange(mMin, mMax)) {
+ // throw...
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_INVALID_MIN_MAX_RANGE", Integer.toString(mMin), Integer.toString(mMax)));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ // System.out.println("CronItem set(): adding a number");
+ mElements.addElement(cr);
+ } catch (NumberFormatException e) {
+ // throw...
+ log(ILogger.LL_FAILURE,
+ "invalid item in cron: " + tok);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * get the vector stuffed with elements where each element is
+ * represented as CronRange
+ * @return a vector of CronRanges
+ */
+ public Vector getElements() {
+ return mElements;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ level, "jobs/CronItem: " + msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/jobs/CronRange.java b/pki/base/common/src/com/netscape/cmscore/jobs/CronRange.java
new file mode 100644
index 000000000..e8923eef8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/jobs/CronRange.java
@@ -0,0 +1,88 @@
+// --- 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.cmscore.jobs;
+
+
+import java.util.*;
+
+
+/**
+ * class representing one Job cron element
+ * <p>here, an "item" refers to one of the 5 fields in a cron string;
+ * "element" refers to any comma-deliminated element in an
+ * "item"...which includes both numbers and '-' separated ranges.
+ * <p>
+ * an Element can contain either an integer number or a range
+ * specified as CronRange. In case of integer numbers, begin
+ * and end are of the same value
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CronRange {
+ int mBegin = 0;
+ int mEnd = 0;
+
+ public CronRange () {
+ }
+
+ /**
+ * sets the lower boundary value of the range
+ */
+ public void setBegin(int i) {
+ mBegin = i;
+ }
+
+ /**
+ * gets the lower boundary value of the range
+ */
+ public int getBegin() {
+ return mBegin;
+ }
+
+ /**
+ * sets the higher boundary value of the range
+ */
+ public void setEnd(int i) {
+ mEnd = i;
+ }
+
+ /**
+ * gets the higher boundary value of the range
+ */
+ public int getEnd() {
+ return mEnd;
+ }
+
+ /**
+ * checks to see if the lower and higher boundary values are
+ * within the min/max.
+ * @param min the minimum value one can specify in this field
+ * @param max the maximum value one can specify in this field
+ * @return a boolean (true/false) on whether the begin/end values
+ * are within the min/max passed in the params
+ */
+ public boolean isValidRange(int min, int max) {
+ if ((mEnd < mBegin) ||
+ (mBegin < min) ||
+ (mEnd > max))
+ return false;
+ else
+ return true;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/jobs/JobCron.java b/pki/base/common/src/com/netscape/cmscore/jobs/JobCron.java
new file mode 100644
index 000000000..a52f37526
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/jobs/JobCron.java
@@ -0,0 +1,355 @@
+// --- 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.cmscore.jobs;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.certsrv.apps.*;
+
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * class representing one Job cron information
+ * <p>here, an "item" refers to one of the 5 fields in a cron string;
+ * "element" refers to any comma-deliminated element in an
+ * "item"...which includes both numbers and '-' separated ranges.
+ * A cron string in the configuration takes the following format:
+ * <i>minute (0-59),
+ * hour (0-23),
+ * day of the month (1-31),
+ * month of the year (1-12),
+ * day of the week (0-6 with 0=Sunday)</i>
+ * <p>
+ * e.g. jobsScheduler.job.rnJob1.cron=30 11,23 * * 1-5
+ * In this example, the job "rnJob1" will be executed from Monday
+ * through Friday, at 11:30am and 11:30pm.
+ * <p>
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class JobCron implements IJobCron {
+
+ /**
+ * CRON_MINUTE, CRON_HOUR, CRON_DAY_OF_MONTH, CRON_MONTH_OF_YEAR,
+ * and CRON_DAY_OF_WEEK are to be used in <b>getItem()</b> to
+ * retrieve the corresponding <b>CronItem</b>
+ */
+ public static final String CRON_MINUTE = "minute";
+ public static final String CRON_HOUR = "hour";
+ public static final String CRON_DAY_OF_MONTH = "dom";
+ public static final String CRON_MONTH_OF_YEAR = "moy";
+ public static final String CRON_DAY_OF_WEEK = "dow";
+ private ILogger mLogger = CMS.getLogger();
+
+ String mCronString = null;
+
+ CronItem cMinute = null;
+ CronItem cHour = null;
+ CronItem cDOM = null;
+ CronItem cMOY = null;
+ CronItem cDOW = null;
+
+ public JobCron(String cronString)
+ throws EBaseException {
+ mCronString = cronString;
+
+ // create all 5 items in the cron
+ cMinute = new CronItem(0, 59);
+ cHour = new CronItem(0, 23);
+ cDOM = new CronItem(1, 31);
+ cMOY = new CronItem(1, 12);
+ cDOW = new CronItem(0, 6); // 0=Sunday
+
+ cronToVals(mCronString);
+ }
+
+ private void cronToVals(String cronString)
+ throws EBaseException {
+ StringTokenizer st = new StringTokenizer(cronString);
+
+ String sMinute = null;
+ String sHour = null;
+ String sDayOMonth = null;
+ String sMonthOYear = null;
+ String sDayOWeek = null;
+
+ try {
+ if (st.hasMoreTokens()) {
+ sMinute = st.nextToken();
+ cMinute.set(sMinute);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_INVALID_MIN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+
+ try {
+ if (st.hasMoreTokens()) {
+ sHour = st.nextToken();
+ cHour.set(sHour);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_HOUR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+
+ if (st.hasMoreTokens()) {
+ sDayOMonth = st.nextToken();
+ // cDOM.set(sDayOMonth);
+ }
+
+ try {
+ if (st.hasMoreTokens()) {
+ sMonthOYear = st.nextToken();
+ cMOY.set(sMonthOYear);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_MONTH", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+
+ if (st.hasMoreTokens()) {
+ sDayOWeek = st.nextToken();
+ // cDOW.set(sDayOWeek);
+ }
+
+ /**
+ * day-of-month or day-of-week, or both?
+ * if only one of them is '*', the non '*' one prevails,
+ * the '*' one will remain empty (no elements)
+ */
+ // day-of-week
+ if ((sDayOMonth!= null) && sDayOMonth.equals(CronItem.ALL) && (sDayOWeek!= null) && !sDayOWeek.equals(CronItem.ALL)) {
+ try {
+ cDOW.set(sDayOWeek);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_DAY_OF_WEEK", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ } else
+ if ((sDayOMonth!= null) && !sDayOMonth.equals(CronItem.ALL) && (sDayOWeek!= null) && sDayOWeek.equals(CronItem.ALL)) {
+ try {
+ cDOM.set(sDayOMonth);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_DAY_OF_MONTH", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ } else { // if both '*', every day, if neither is '*', do both
+ try {
+ if (sDayOWeek!= null) {
+ cDOW.set(sDayOWeek);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_DAY_OF_WEEK", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ try {
+ if (sDayOMonth != null) {
+ cDOM.set(sDayOMonth);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INVALID_DAY_OF_MONTH", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_JOB_CRON"));
+ }
+ }
+ }
+
+ /**
+ * retrieves the cron item
+ * @param item name of the item. must be one of the <b>CRON_*</b>
+ * strings defined in this class
+ * @return an instance of the CronItem class which represents the
+ * requested cron item
+ */
+ public CronItem getItem(String item) {
+ if (item.equals(CRON_MINUTE)) {
+ return cMinute;
+ } else if (item.equals(CRON_HOUR)) {
+ return cHour;
+ } else if (item.equals(CRON_DAY_OF_MONTH)) {
+ return cDOM;
+ } else if (item.equals(CRON_MONTH_OF_YEAR)) {
+ return cMOY;
+ } else if (item.equals(CRON_DAY_OF_WEEK)) {
+ return cDOW;
+ } else {
+ // throw...
+ }
+
+ return null;
+ }
+
+ /**
+ * Does the element fit any element in the item
+ * @param element the element of "now" in cron format
+ * @param item the item consists of a vector of elements
+ * @return boolean (true/false) on whether the element is one of
+ * the elements in the item
+ */
+ boolean isElement(int element, Vector item) {
+ // loop through all of the elements of an item
+ for (Enumeration e = item.elements(); e.hasMoreElements();) {
+ CronRange cElement = (CronRange) e.nextElement();
+
+ // is a number
+ if (cElement.getBegin() == cElement.getEnd()) {
+ if (element == cElement.getBegin()) {
+ return true;
+ }
+ } else { // is a range
+ if ((element >= cElement.getBegin()) &&
+ (element <= cElement.getEnd())) {
+ return true;
+ }
+ }
+ }
+ // no fit
+ return false;
+ }
+
+ /**
+ * convert the day of the week representation from Calendar to
+ * cron
+ * @param time the Calendar value represents a moment of time
+ * @return an integer value that represents a cron Day-Of-Week
+ * element
+ */
+ public int DOW_cal2cron(Calendar time) {
+ int calDow = time.get(Calendar.DAY_OF_WEEK);
+ int cronDow = 0; // default should never be used
+
+ // convert the Calendar representation of dow to the cron one
+ switch (calDow) {
+ case Calendar.SUNDAY:
+ cronDow = 0;
+ break;
+
+ case Calendar.MONDAY:
+ cronDow = 1;
+ break;
+
+ case Calendar.TUESDAY:
+ cronDow = 2;
+ break;
+
+ case Calendar.WEDNESDAY:
+ cronDow = 3;
+ break;
+
+ case Calendar.THURSDAY:
+ cronDow = 4;
+ break;
+
+ case Calendar.FRIDAY:
+ cronDow = 5;
+ break;
+
+ case Calendar.SATURDAY:
+ cronDow = 6;
+ break;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return cronDow;
+ }
+
+ /**
+ * convert the month of year representation from Calendar to cron
+ * @param time the Calendar value represents a moment of time
+ * @return an integer value that represents a cron Month-Of-Year
+ * element
+ */
+ public int MOY_cal2cron(Calendar time) {
+ int calMoy = time.get(Calendar.MONTH);
+ int cronMoy = 0;
+
+ // convert the Calendar representation of moy to the cron one
+ switch (calMoy) {
+ case Calendar.JANUARY:
+ cronMoy = 1;
+ break;
+
+ case Calendar.FEBRUARY:
+ cronMoy = 2;
+ break;
+
+ case Calendar.MARCH:
+ cronMoy = 3;
+ break;
+
+ case Calendar.APRIL:
+ cronMoy = 4;
+ break;
+
+ case Calendar.MAY:
+ cronMoy = 5;
+ break;
+
+ case Calendar.JUNE:
+ cronMoy = 6;
+ break;
+
+ case Calendar.JULY:
+ cronMoy = 7;
+ break;
+
+ case Calendar.AUGUST:
+ cronMoy = 8;
+ break;
+
+ case Calendar.SEPTEMBER:
+ cronMoy = 9;
+ break;
+
+ case Calendar.OCTOBER:
+ cronMoy = 10;
+ break;
+
+ case Calendar.NOVEMBER:
+ cronMoy = 11;
+ break;
+
+ case Calendar.DECEMBER:
+ cronMoy = 12;
+ break;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return cronMoy;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ level, msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java b/pki/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java
new file mode 100644
index 000000000..f0b8c49c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java
@@ -0,0 +1,541 @@
+// --- 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.cmscore.jobs;
+
+
+import java.util.*;
+import java.io.*;
+import java.lang.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.jobs.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This is a daemon thread that handles scheduled jobs like cron would
+ * do with different jobs. This daemon wakes up at a pre-configured
+ * interval to see
+ * if there is any job to be done, if so, a thread is created to execute
+ * the job(s).
+ * <p>
+ * The interval <b>jobsScheduler.interval</b> in the configuration is
+ * specified as number of minutes. If not set, the default is 1 minute.
+ * Note that the cron specification for each job CAN NOT be finer than
+ * the granularity of the Scheduler daemon interval. For example, if
+ * the daemon interval is set to 5 minute, a job cron for every minute
+ * at 7am on each Tuesday (e.g. * 7 * * 2) will result in the
+ * execution of the job thread only once every 5 minutes during that
+ * hour. <b>The inteval value is recommended at 1 minute, setting it
+ * otherwise has the potential of forever missing the beat</b>. Use
+ * with caution.
+ *
+ * @author cfu
+ * @see JobCron
+ * @version $Revision$, $Date$
+ */
+public class JobsScheduler implements Runnable, IJobsScheduler {
+
+ protected static final long MINUTE_MILLI = 60000;
+ protected static final String DELIM = ",";
+
+ /**
+ * Scheduler thread doing job scheduling
+ */
+ protected String mId = ID;
+ protected Thread mScheduleThread = null;
+
+ public Hashtable mJobPlugins = new Hashtable();
+ public Hashtable mJobs = new Hashtable();
+ private Hashtable mJobThreads = new Hashtable();
+
+ private IConfigStore mConfig = null;
+ private ILogger mLogger = null;
+
+ // in milliseconds. daemon wakeup interval, default 1 minute.
+ private long mInterval = 0;
+
+ // singleton enforcement
+
+ private static JobsScheduler mInstance = new JobsScheduler();
+
+ public static JobsScheduler getInstance() {
+ return mInstance;
+ }
+
+ // end singleton enforcement.
+
+ private JobsScheduler() {
+ }
+
+ /**
+ * read from the config file all implementations of Jobs,
+ * register and initialize them
+ * <p>
+ * the config params have the following formats:
+ * jobScheduler.impl.[implementation name].class=[package name]
+ * jobScheduler.job.[job name].pluginName=[implementation name]
+ * jobScheduler.job.[job name].cron=[crontab format]
+ * jobScheduler.job.[job name].[any job specific params]=[values]
+ *
+ * @param config jobsScheduler configStore
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException, EJobsException {
+ mLogger = CMS.getLogger();
+
+ // read in config parameters and set variables
+ mConfig = config;
+
+ // getting/setting interval
+ int i;
+
+ try {
+ i = mConfig.getInteger(PROP_INTERVAL);
+ } catch (Exception e) {
+ i = 1; // default 1 minute
+ }
+ setInterval(i);
+
+ IConfigStore c = mConfig.getSubStore(PROP_IMPL);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ // register all job plugins
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+
+ JobPlugin plugin = new JobPlugin(id, pluginPath);
+
+ mJobPlugins.put(id, plugin);
+ }
+
+ // register all jobs
+ c = config.getSubStore(PROP_JOB);
+ Enumeration jobs = c.getSubStoreNames();
+
+ while (jobs.hasMoreElements()) {
+ String jobName = (String) jobs.nextElement();
+ String implName = c.getString(jobName + "." + PROP_PLUGIN);
+ JobPlugin plugin =
+ (JobPlugin) mJobPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_CLASS_NOT_FOUND",
+ implName));
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_PLUGIN_NOT_FOUND", implName));
+ }
+ String classPath = plugin.getClassPath();
+
+ // instantiate and init the job
+ IJob job = null;
+
+ try {
+ job = (IJob)
+ Class.forName(classPath).newInstance();
+ IConfigStore jconfig = c.getSubStore(jobName);
+
+ job.init(this, jobName, implName, jconfig);
+
+ // register the job
+ mJobs.put(jobName, job);
+ } catch (ClassNotFoundException e) {
+ String errMsg = "JobsScheduler:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INIT_ERROR", e.toString()));
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", classPath));
+ } catch (IllegalAccessException e) {
+ String errMsg = "JobsScheduler:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INIT_ERROR", e.toString()));
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", classPath));
+ } catch (InstantiationException e) {
+ String errMsg = "JobsScheduler: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INIT_ERROR", e.toString()));
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", classPath));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_JOBS_INIT_ERROR", e.toString()));
+ throw e;
+ }
+ }
+
+ // are we enabled?
+ if (mConfig.getBoolean(PROP_ENABLED, false) == true) {
+ // start the daemon thread
+ startDaemon();
+ }
+ }
+
+ public Hashtable getPlugins() {
+ return mJobPlugins;
+ }
+
+ public Hashtable getInstances() {
+ return mJobs;
+ }
+
+ /**
+ * when wake up:
+ * . execute the scheduled job(s)
+ * * if job still running from previous interval, skip it
+ * . figure out when is the next wakeup time (every interval). If
+ * current wakup time runs over the interval, skip the missed interval(s)
+ * . sleep till the next wakeup time
+ */
+ public void run() {
+ long wokeupTime = 0;
+
+ while (true) {
+ // get time now
+ Calendar cal = Calendar.getInstance();
+ long rightNow = cal.getTime().getTime();
+ long duration = 0;
+ long second = cal.get(Calendar.SECOND);
+
+ if (second != 1) { // scheduler needs adjustment
+ // adjust to wake up at 1st second
+ long milliSec = cal.get(Calendar.MILLISECOND);
+
+ // possible to be at exactly second 1, millisecond 0,
+ // just let it skip to next second, fine.
+ duration = (60 - second) * 1000 + 1000 - milliSec;
+ log(ILogger.LL_INFO,
+ "adjustment for cron behavior: sleep for " +
+ duration + " milliseconds");
+ } else {
+
+ // when is the next wakeup time for the JobsScheduler?
+ // reset next wakeup time - wake up every preset interval
+
+ duration = mInterval - rightNow + wokeupTime;
+
+ }
+
+ while (duration < 0) {
+ duration += mInterval;
+ }
+
+ if (duration != 0) {
+ try {
+ Thread.sleep(duration);
+ } catch (InterruptedException e) {
+ System.out.println(e.toString());
+ }
+ }
+ // if (duration == 0), it's time
+
+ // woke up...
+ try {
+ if (mConfig.getBoolean(PROP_ENABLED, false) == false) {
+ return;
+ }
+ } catch (Exception e) {
+ return;
+ }
+
+ // check to see if new jobs are registered
+ // ... later
+
+ // get time now
+ cal = Calendar.getInstance();
+
+ /**
+ * Get the current time outside the jobs while loop
+ * to make sure that the rightful jobs are run
+ * -- milliseconds from the epoch
+ */
+ wokeupTime = cal.getTime().getTime();
+
+ IJob job = null;
+
+ for (Enumeration e = mJobs.elements(); e.hasMoreElements();) {
+ job = (IJob) e.nextElement();
+
+ // is it enabled?
+ IConfigStore cs = job.getConfigStore();
+
+ try {
+ if (cs.getBoolean(PROP_ENABLED, false) == false)
+ continue;
+ } catch (Exception ex) {
+ continue; // ignore this job
+ }
+
+ // first, check to see if thread already running
+ // ...
+
+ // start the job thread if necessary
+ if (isShowTime(job, cal) == true) {
+ // log(ILogger.LL_INFO, "show time for: "+job.getId());
+
+ // if previous thread still alive, skip
+ Thread jthread = (Thread) mJobThreads.get(job.getId());
+
+ if ((jthread == null) || (!jthread.isAlive())) {
+ Thread jobThread = new Thread((Runnable) job, job.getId());
+
+ jobThread.start();
+ // put into job thread control
+ mJobThreads.put(job.getId(), jobThread);
+ } else {
+ // previous thread still alive, log it
+ log(ILogger.LL_INFO, "Job " + job.getId() +
+ " still running...skipping this round");
+ }
+ }
+ } // for
+
+ }
+ }
+
+ public IJobCron createJobCron(String cs) throws EBaseException {
+ return new JobCron(cs);
+ }
+
+ /**
+ * Is it time for the job?
+ */
+ protected boolean isShowTime(IJob job, Calendar now) {
+ JobCron jcron = (JobCron) job.getJobCron();
+
+ if (jcron == null) {
+ // the impossible has happened
+ log(ILogger.LL_INFO, "isShowTime(): jobcron null");
+ return false;
+ }
+
+ /**
+ * is it the right month?
+ */
+ Vector moy =
+ jcron.getItem(jcron.CRON_MONTH_OF_YEAR).getElements();
+
+ int cronMoy = jcron.MOY_cal2cron(now);
+
+ if (jcron.isElement(cronMoy, moy) == false) {
+ return false;
+ }
+ // is the right month!
+
+ /**
+ * is it the right date?
+ */
+ Vector dow = jcron.getItem(jcron.CRON_DAY_OF_WEEK).getElements();
+ Vector dom = jcron.getItem(jcron.CRON_DAY_OF_MONTH).getElements();
+
+ // can't be both empty
+ if ((dow.isEmpty()) && dom.isEmpty()) {
+ // throw... or return false?
+ }
+
+ int cronDow = jcron.DOW_cal2cron(now);
+
+ if ((jcron.isElement(cronDow, dow) == false) &&
+ (jcron.isElement(now.get(Calendar.DAY_OF_MONTH), dom) == false)) {
+ return false;
+ }
+ // is the right date!
+
+ /**
+ * is it the right hour?
+ */
+ Vector hour = jcron.getItem(jcron.CRON_HOUR).getElements();
+
+ if (jcron.isElement(now.get(Calendar.HOUR_OF_DAY), hour) == false) {
+ return false;
+ }
+ // is the right hour!
+
+ /**
+ * is it the right minute?
+ */
+ Vector minute = jcron.getItem(jcron.CRON_MINUTE).getElements();
+
+ if (jcron.isElement(now.get(Calendar.MINUTE), minute) == false) {
+ return false;
+ }
+ // is the right minute! We're on!
+
+ return true;
+ }
+
+ /**
+ * Retrieves id (name) of this subsystem.
+ * @return name of the Jobs Scheduler subsystem
+ */
+ public String getId() {
+ return (mId);
+ }
+
+ /**
+ * Sets id string to this subsystem.
+ * <p>
+ * Use with caution. Should not do it when sharing with others
+ * @param id name to be applied to an Jobs Scheduler subsystem
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * creates and starts the daemon thread
+ */
+ public void startDaemon() {
+ mScheduleThread = new Thread(this, "JobScheduler");
+ log(ILogger.LL_INFO, "started Jobs Scheduler daemon thread");
+ mScheduleThread.setDaemon(true);
+ mScheduleThread.start();
+ }
+
+ /**
+ * registers the administration servlet with the administration subsystem.
+ */
+ public void startup() throws EBaseException {
+ //remove, already logged from S_ADMIN
+ //String infoMsg = "Jobs Scheduler subsystem administration Servlet registered";
+ //log(ILogger.LL_INFO, infoMsg);
+ }
+
+ /**
+ * shuts down Jobs one by one.
+ * <P>
+ */
+ public void shutdown() {
+ mJobPlugins.clear();
+ mJobPlugins = null;
+ mJobs.clear();
+ mJobs = null;
+
+ Enumeration enums = mJobThreads.keys();
+ while (enums.hasMoreElements()) {
+ String id = (String)enums.nextElement();
+ Thread currthread = (Thread)mJobThreads.get(id);
+ if (currthread != null) {
+ currthread.destroy();
+ }
+ }
+
+ mJobThreads.clear();
+ mJobThreads = null;
+
+ if (mScheduleThread != null) {
+ mScheduleThread.destroy();
+ }
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Gets configuration parameters for the given
+ * job plugin.
+ * @param implName Name of the job plugin.
+ * @return Hashtable of required parameters.
+ */
+ public String[] getConfigParams(String implName)
+ throws EJobsException {
+ if (Debug.ON)
+ Debug.trace("in getCofigParams()");
+
+ // is this a registered implname?
+ JobPlugin plugin = (JobPlugin) mJobPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_CLASS_NOT_FOUND", implName));
+ if (Debug.ON)
+ Debug.trace("Job plugin " + implName + " not found.");
+ throw new EJobsException(CMS.getUserMessage("CMS_JOB_PLUGIN_NOT_FOUND",
+ implName));
+ }
+
+ // XXX can find an instance of this plugin in existing
+ // auth manager instantces to avoid instantiation just for this.
+
+ // a temporary instance
+ IJob jobInst = null;
+ String className = plugin.getClassPath();
+
+ if (Debug.ON)
+ Debug.trace("className = " + className);
+ try {
+ jobInst = (IJob)
+ Class.forName(className).newInstance();
+ if (Debug.ON)
+ Debug.trace("class instantiated");
+ return (jobInst.getConfigParams());
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_CREATE_NEW", e.toString()));
+ if (Debug.ON)
+ Debug.trace("class NOT instantiated: " + e.toString());
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_CREATE_NEW", e.toString()));
+ if (Debug.ON)
+ Debug.trace("class NOT instantiated: " + e.toString());
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_JOBS_CREATE_NEW", e.toString()));
+ if (Debug.ON)
+ Debug.trace("class NOT instantiated: " + e.toString());
+ throw new
+ EJobsException(CMS.getUserMessage("CMS_JOB_LOAD_CLASS_FAILED", className));
+ }
+ }
+
+ public void setInterval(int minutes) {
+ mInterval = minutes * MINUTE_MILLI;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ level, msg);
+ }
+
+ public Hashtable getJobPlugins() {
+ return mJobPlugins;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java
new file mode 100644
index 000000000..598ae198b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java
@@ -0,0 +1,75 @@
+// --- 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.cmscore.ldap;
+
+
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * This class represents an expression of the form
+ * <var1 op val1 AND var2 op va2>.
+ *
+ * Expressions are used as predicates for publishing rule selection.
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LdapAndExpression implements ILdapExpression {
+ private ILdapExpression mExp1;
+ private ILdapExpression mExp2;
+ public LdapAndExpression(ILdapExpression exp1, ILdapExpression exp2) {
+ mExp1 = exp1;
+ mExp2 = exp2;
+ }
+
+ public boolean evaluate(SessionContext sc)
+ throws ELdapException {
+ // If an expression is missing we assume applicability.
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(sc) && mExp2.evaluate(sc);
+ else if (mExp1 == null)
+ return mExp2.evaluate(sc);
+ else // (if mExp2 == null)
+ return mExp1.evaluate(sc);
+ }
+
+ public boolean evaluate(IRequest req)
+ throws ELdapException {
+ // If an expression is missing we assume applicability.
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(req) && mExp2.evaluate(req);
+ else if (mExp1 == null)
+ return mExp2.evaluate(req);
+ else // (if mExp2 == null)
+ return mExp1.evaluate(req);
+ }
+
+ public String toString() {
+ return mExp1.toString() + " AND " + mExp2.toString();
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java
new file mode 100644
index 000000000..273a21c96
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java
@@ -0,0 +1,141 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.util.Debug;
+
+
+public class LdapConnModule implements ILdapConnModule {
+ protected IConfigStore mConfig = null;
+ protected LdapBoundConnFactory mLdapConnFactory = null;
+ protected ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+
+ /**
+ * instantiate connection factory.
+ */
+
+ public static final String PROP_LDAP = "ldap";
+
+ public LdapConnModule() {
+ }
+
+ public LdapConnModule(LdapBoundConnFactory factory) {
+ mLdapConnFactory = factory;
+ mInited = true;
+ }
+
+ protected ISubsystem mPubProcessor;
+
+ public void init(ISubsystem p,
+ IConfigStore config)
+ throws EBaseException {
+
+ CMS.debug("LdapConnModule: init called");
+ if (mInited) {
+ CMS.debug("LdapConnModule: already initialized. return.");
+ return;
+ }
+ CMS.debug("LdapConnModule: init begins");
+
+ mPubProcessor = p;
+ mConfig = config;
+ /*
+ mLdapConnFactory = new LdapBoundConnFactory();
+ mLdapConnFactory.init(mConfig.getSubStore("ldap"));
+ */
+
+ // support publishing dirsrv with different pwd than internaldb
+ IConfigStore ldap = mConfig.getSubStore("ldap");
+
+ IConfigStore ldapconn = ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPCONNINFO);
+ IConfigStore authinfo = ldap.getSubStore(
+ ILdapBoundConnFactory.PROP_LDAPAUTHINFO);
+ ILdapConnInfo connInfo =
+ CMS.getLdapConnInfo(ldapconn);
+ LdapAuthInfo authInfo =
+ new LdapAuthInfo(authinfo, ldapconn.getString("host"),
+ ldapconn.getInteger("port"), connInfo.getSecure());
+
+ int minConns = mConfig.getInteger(ILdapBoundConnFactory.PROP_MINCONNS, 3);
+ int maxConns = mConfig.getInteger(ILdapBoundConnFactory.PROP_MAXCONNS, 15);
+ // must get authInfo from the config, don't default to internaldb!!!
+
+ CMS.debug("Creating LdapBoundConnFactory for LdapConnModule.");
+ mLdapConnFactory =
+ new LdapBoundConnFactory(minConns, maxConns, (LdapConnInfo)connInfo, authInfo);
+
+ mInited = true;
+
+ CMS.debug("LdapConnModule: init ends");
+ }
+
+ /**
+ * Returns the internal ldap connection factory.
+ * This can be useful to get a ldap connection to the
+ * ldap publishing directory without having to get it again from the
+ * config file. Note that this means sharing a ldap connection pool
+ * with the ldap publishing module so be sure to return connections to pool.
+ * Use ILdapConnFactory.getConn() to get a Ldap connection to the ldap
+ * publishing directory.
+ * Use ILdapConnFactory.returnConn() to return the connection.
+ *
+ * @see com.netscape.certsrv.ldap.ILdapBoundConnFactory
+ * @see com.netscape.certsrv.ldap.ILdapConnFactory
+ */
+ public ILdapConnFactory getLdapConnFactory() {
+ return mLdapConnFactory;
+ }
+
+ public LDAPConnection getConn() throws ELdapException {
+ return mLdapConnFactory.getConn();
+ }
+
+ public void returnConn(LDAPConnection conn) throws ELdapException {
+ mLdapConnFactory.returnConn(conn);
+ }
+
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_LDAP, level,
+ "LdapPublishModule: " + msg);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java
new file mode 100644
index 000000000..ae0e1a310
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java
@@ -0,0 +1,79 @@
+// --- 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.cmscore.ldap;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * This class represents an Or expression of the form
+ * (var1 op val1 OR var2 op val2).
+ *
+ * Expressions are used as predicates for publishing rule selection.
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LdapOrExpression implements ILdapExpression {
+ private ILdapExpression mExp1;
+ private ILdapExpression mExp2;
+ public LdapOrExpression(ILdapExpression exp1, ILdapExpression exp2) {
+ mExp1 = exp1;
+ mExp2 = exp2;
+ }
+
+ public boolean evaluate(SessionContext sc)
+ throws ELdapException {
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(sc) || mExp2.evaluate(sc);
+ else if (mExp1 != null && mExp2 == null)
+ return mExp1.evaluate(sc);
+ else // (mExp1 == null && mExp2 != null)
+ return mExp2.evaluate(sc);
+ }
+
+ public boolean evaluate(IRequest req)
+ throws ELdapException {
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(req) || mExp2.evaluate(req);
+ else if (mExp1 != null && mExp2 == null)
+ return mExp1.evaluate(req);
+ else // (mExp1 == null && mExp2 != null)
+ return mExp2.evaluate(req);
+ }
+
+ public String toString() {
+ if (mExp1 == null && mExp2 == null)
+ return "";
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.toString() + " OR " + mExp2.toString();
+ else if (mExp1 != null && mExp2 == null)
+ return mExp1.toString();
+ else // (mExp1 == null && mExp2 != null)
+ return mExp2.toString();
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java
new file mode 100644
index 000000000..b8e62d896
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java
@@ -0,0 +1,374 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Default implementation of predicate parser.
+ *
+ * Limitations:
+ *
+ * 1. Currently parentheses are not suported.
+ * 2. Only ==, != <, >, <= and >= operators are supported.
+ * 3. The only boolean operators supported are AND and OR. AND takes precedence
+ * over OR. Example: a AND b OR e OR c AND d
+ * is treated as (a AND b) OR e OR (c AND d)
+ * 4. If this is n't adequate, roll your own.
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LdapPredicateParser {
+ public static final int OP_AND = 1;
+ public static final int OP_OR = 2;
+ public static final int EXPRESSION = 0;
+
+ public static final String AND = "AND";
+ public static final String OR = "OR";
+
+ private static final char COMMA = ',';
+
+ /**
+ * Parse the predicate expression and return a vector of expressions.
+ *
+ * @param predicateExp The predicate expression as read from the config file.
+ * @return expVector The vector of expressions.
+ */
+ public static ILdapExpression parse(String predicateExpression)
+ throws ELdapException {
+ if (predicateExpression == null ||
+ predicateExpression.length() == 0)
+ return null;
+ PredicateTokenizer pt = new PredicateTokenizer(predicateExpression);
+
+ if (pt == null || !pt.hasMoreTokens())
+ return null;
+
+ // The first token cannot be an operator. We are not dealing with
+ // reverse-polish notation.
+ String token = pt.nextToken();
+ boolean opANDSeen;
+ boolean opORSeen;
+
+ if (getOP(token) != EXPRESSION) {
+ if (Debug.ON)
+ Debug.trace("Malformed expression: " + predicateExpression);
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_BAD_LDAP_EXPRESSION", predicateExpression));
+ }
+ ILdapExpression current = parseExpression(token);
+ boolean malformed = false;
+ Vector expSet = new Vector();
+ int prevType = EXPRESSION;
+
+ while (pt.hasMoreTokens()) {
+ token = pt.nextToken();
+ int curType = getOP(token);
+
+ if ((prevType != EXPRESSION && curType != EXPRESSION) ||
+ (prevType == EXPRESSION && curType == EXPRESSION)) {
+ malformed = true;
+ break;
+ }
+
+ // If an operator seen skip to the next token
+ if (curType != EXPRESSION) {
+ prevType = curType;
+ continue;
+ }
+
+ // If the previous type was an OR token, add the current expression to
+ // the expression set;
+ if (prevType == OP_OR) {
+ expSet.addElement(current);
+ current = parseExpression(token);
+ prevType = curType;
+ continue;
+ }
+
+ // If the previous type was an AND token, make an AND expression
+ if (prevType == OP_AND) {
+ current = new LdapAndExpression(current, parseExpression(token));
+ prevType = curType;
+ }
+ }
+ if (malformed) {
+ if (Debug.ON)
+ Debug.trace("Malformed expression: " + predicateExpression);
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_BAD_LDAP_EXPRESSION",
+ predicateExpression));
+ }
+
+ // Form an LdapOrExpression
+ if (current != null)
+ expSet.addElement(current);
+
+ int size = expSet.size();
+
+ if (size == 0)
+ return null;
+ LdapOrExpression orExp = new
+ LdapOrExpression((ILdapExpression) expSet.elementAt(0), null);
+
+ for (int i = 1; i < size; i++)
+ orExp = new LdapOrExpression(orExp,
+ (ILdapExpression) expSet.elementAt(i));
+ return orExp;
+ }
+
+ private static int getOP(String token) {
+ if (token.equalsIgnoreCase(AND))
+ return OP_AND;
+ else if (token.equalsIgnoreCase(OR))
+ return OP_OR;
+ else
+ return EXPRESSION;
+ }
+
+ private static ILdapExpression parseExpression(String input)
+ throws ELdapException {
+ // If the expression has multiple parts separated by commas
+ // we need to construct an AND expression. Else we will return a
+ // simple expression.
+ int commaIndex = input.indexOf(COMMA);
+
+ if (commaIndex < 0)
+ return LdapSimpleExpression.parse(input);
+ int currentIndex = 0;
+ Vector expVector = new Vector();
+
+ while (commaIndex > 0) {
+ LdapSimpleExpression exp = (LdapSimpleExpression)
+ LdapSimpleExpression.parse(input.substring(currentIndex,
+ commaIndex));
+
+ expVector.addElement(exp);
+ currentIndex = commaIndex + 1;
+ commaIndex = input.indexOf(COMMA, currentIndex);
+ }
+ if (currentIndex < (input.length() - 1)) {
+ LdapSimpleExpression exp = (LdapSimpleExpression)
+ LdapSimpleExpression.parse(input.substring(currentIndex));
+
+ expVector.addElement(exp);
+ }
+
+ int size = expVector.size();
+ LdapSimpleExpression exp1 = (LdapSimpleExpression) expVector.elementAt(0);
+ LdapSimpleExpression exp2 = (LdapSimpleExpression) expVector.elementAt(1);
+ LdapAndExpression andExp = new LdapAndExpression(exp1, exp2);
+
+ for (int i = 2; i < size; i++) {
+ andExp = new LdapAndExpression(andExp, (LdapSimpleExpression) expVector.elementAt(i));
+ }
+ return andExp;
+ }
+
+ public static void main(String[] args) {
+
+ /**
+ AttributeSet req = new AttributeSet();
+ try
+ {
+ req.set("ou", "people");
+ req.set("cn", "John Doe");
+ req.set("uid", "jdoes");
+ req.set("o", "airius.com");
+ req.set("certtype", "client");
+ req.set("request", "issuance");
+ req.set("id", new Integer(10));
+ req.set("dualcerts", new Boolean(true));
+
+ Vector v = new Vector();
+ v.addElement("one");
+ v.addElement("two");
+ v.addElement("three");
+ req.set("count", v);
+ }
+ catch (Exception e){e.printStackTrace();}
+ String[] array = { "ou == people AND certtype == client",
+ "ou == servergroup AND certtype == server",
+ "uid == jdoes, ou==people, o==airius.com OR ou == people AND certType == client OR certType == server AND cn == needles.mcom.com",
+ };
+ for (int i = 0; i < array.length; i++)
+ {
+ System.out.println();
+ System.out.println("String: " + array[i]);
+ ILdapExpression exp = null;
+ try
+ {
+ exp = parse(array[i]);
+ if (exp != null)
+ {
+ System.out.println("Parsed Expression: " + exp);
+ boolean result = exp.evaluate(req);
+ System.out.println("Result: " + result);
+ }
+ }
+ catch (Exception e) {e.printStackTrace(); }
+ }
+
+
+ try
+ {
+ BufferedReader rdr = new BufferedReader(
+ new FileReader(args[0]));
+ String line;
+ while((line=rdr.readLine()) != null)
+ {
+ System.out.println();
+ System.out.println("Line Read: " + line);
+ ILdapExpression exp = null;
+ try
+ {
+ exp = parse(line);
+ if (exp != null)
+ {
+ System.out.println(exp);
+ boolean result = exp.evaluate(req);
+ System.out.println("Result: " + result);
+ }
+
+ }catch (Exception e){e.printStackTrace();}
+ }
+ }
+ catch (Exception e){e.printStackTrace(); }
+
+ **/
+ }
+
+}
+
+
+class PredicateTokenizer {
+ String input;
+ int currentIndex;
+ int endOfString;
+ String nextToken;
+ boolean first;
+
+ public PredicateTokenizer(String predString) {
+ input = predString;
+ currentIndex = 0;
+ nextToken = null;
+ }
+
+ public boolean hasMoreTokens() {
+ return (currentIndex != -1);
+ }
+
+ public String nextToken() {
+ if (nextToken != null) {
+ String toReturn = nextToken;
+
+ nextToken = null;
+ return toReturn;
+ }
+
+ int andIndex = input.indexOf(" AND", currentIndex);
+
+ if (andIndex < 0)
+ andIndex = input.indexOf(" and", currentIndex);
+ int orIndex = input.indexOf(" OR", currentIndex);
+
+ if (orIndex < 0)
+ orIndex = input.indexOf(" or", currentIndex);
+ String toReturn = null;
+
+ if (andIndex == -1 && orIndex == -1) {
+ if (currentIndex == 0) {
+ currentIndex = -1;
+ toReturn = input;
+ } else {
+ int temp = currentIndex;
+
+ currentIndex = -1;
+ toReturn = input.substring(temp);
+ }
+ } else if (andIndex >= 0 && (andIndex < orIndex || orIndex == -1)) {
+ if (currentIndex != andIndex) {
+ toReturn = input.substring(currentIndex, andIndex);
+ nextToken = input.substring(andIndex + 1, andIndex + 4);
+ currentIndex = andIndex + 4;
+ } else {
+ toReturn = "AND";
+ currentIndex += 4;
+ }
+ } else if (orIndex >= 0 && (orIndex < andIndex || andIndex == -1)) {
+ if (currentIndex != orIndex) {
+ toReturn = input.substring(currentIndex, orIndex);
+ nextToken = input.substring(orIndex + 1, orIndex + 3);
+ currentIndex = orIndex + 3;
+ } else {
+ toReturn = "OR";
+ currentIndex += 3;
+ }
+ } else {
+ // Cannot happen; Assert here.
+ toReturn = null;
+ System.out.println("We shouldn't be here!");
+ }
+ if (toReturn == null)
+ return null;
+ else {
+ String trimmed = toReturn.trim();
+
+ if (trimmed == null || trimmed.length() == 0)
+ return nextToken();
+ else
+ return trimmed;
+ }
+ }
+}
+
+
+class AttributeSet implements IAttrSet {
+ Hashtable ht = new Hashtable();
+ public AttributeSet() {
+ }
+
+ public void delete(String name)
+ throws EBaseException {
+ Object ob = ht.get(name);
+
+ ht.remove(ob);
+ }
+
+ public Object get(String name)
+ throws EBaseException {
+ return ht.get(name);
+ }
+
+ public void set(String name, Object ob)
+ throws EBaseException {
+ ht.put(name, ob);
+ }
+
+ public Enumeration getElements() {
+ return ht.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java
new file mode 100644
index 000000000..0afd0ed43
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java
@@ -0,0 +1,796 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.authority.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.certsrv.apps.*;
+
+
+public class LdapPublishModule implements ILdapPublishModule {
+ protected IConfigStore mConfig = null;
+ protected LdapBoundConnFactory mLdapConnFactory = null;
+ protected ILogger mLogger = CMS.getLogger();
+ private boolean mInited = false;
+ protected ICertAuthority mAuthority = null;
+
+ /**
+ * hashtable of cert types to cert mappers and publishers.
+ * cert types are client, server, ca, subca, ra, crl, etc.
+ * XXX the cert types need to be consistently used.
+ * for each, the mapper may be null, in which case the full subject
+ * name is used to map the cert.
+ * for crl, if the mapper is null the ca mapper is used. if that
+ * is null, the full issuer name is used.
+ * XXX if we support crl issuing points the issuing point should be used
+ * to publish the crl.
+ * When publishers are null, the certs are not published.
+ */
+ protected Hashtable mMappers = new Hashtable();
+
+ /**
+ * handlers for request types (events)
+ * values implement IRequestListener
+ */
+ protected Hashtable mEventHandlers = new Hashtable();
+
+ /**
+ * instantiate connection factory.
+ */
+ public static final String ATTR_LDAPPUBLISH_STATUS = "LdapPublishStatus";
+ public static final String PROP_LDAP = "ldap";
+ public static final String PROP_MAPPER = "mapper";
+ public static final String PROP_PUBLISHER = "publisher";
+ public static final String PROP_CLASS = "class";
+ public static final String PROP_TYPE = "type";
+ public static final String PROP_TYPE_CA = "ca";
+ public static final String PROP_TYPE_CLIENT = "client";
+ public static final String PROP_TYPE_CRL = "crl";
+
+ public LdapPublishModule() {
+ }
+
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException
+ {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public LdapPublishModule(LdapBoundConnFactory factory) {
+ mLdapConnFactory = factory;
+ mInited = true;
+ }
+
+ protected IPublisherProcessor mPubProcessor;
+
+ public void init(ICertAuthority authority, IPublisherProcessor p,
+ IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+
+ mAuthority = authority;
+ mPubProcessor = p;
+ mConfig = config;
+ mLdapConnFactory = new LdapBoundConnFactory();
+ mLdapConnFactory.init(mConfig.getSubStore("ldap"));
+
+ // initMappers(config);
+ initHandlers();
+
+ mAuthority.registerRequestListener(this);
+ }
+
+ public void init(ICertAuthority authority, IConfigStore config)
+ throws EBaseException {
+ if (mInited)
+ return;
+
+ mAuthority = authority;
+ mConfig = config;
+ mLdapConnFactory = new LdapBoundConnFactory();
+ mLdapConnFactory.init(mConfig.getSubStore("ldap"));
+
+ initMappers(config);
+ initHandlers();
+
+ mAuthority.registerRequestListener(this);
+ }
+
+ /**
+ * Returns the internal ldap connection factory.
+ * This can be useful to get a ldap connection to the
+ * ldap publishing directory without having to get it again from the
+ * config file. Note that this means sharing a ldap connection pool
+ * with the ldap publishing module so be sure to return connections to pool.
+ * Use ILdapConnFactory.getConn() to get a Ldap connection to the ldap
+ * publishing directory.
+ * Use ILdapConnFactory.returnConn() to return the connection.
+ *
+ * @see com.netscape.certsrv.ldap.ILdapBoundConnFactory
+ * @see com.netscape.certsrv.ldap.ILdapConnFactory
+ */
+ public ILdapConnFactory getLdapConnFactory() {
+ return mLdapConnFactory;
+ }
+
+ /**
+ * Returns the connection factory to the publishing directory.
+ * Must return the connection once you return
+ */
+
+ protected LdapMappers getMappers(String certType) {
+ LdapMappers mappers = null;
+
+ if (certType == null) {
+ mappers = (LdapMappers) mMappers.get(PROP_TYPE_CLIENT);
+ } else {
+ mappers = (LdapMappers) mMappers.get(certType);
+ }
+ return mappers;
+ }
+
+ protected void initMappers(IConfigStore config)
+ throws EBaseException {
+ IConfigStore types = mConfig.getSubStore(PROP_TYPE);
+
+ if (types == null || types.size() <= 0) {
+ // nothing configured.
+ if (Debug.ON)
+ System.out.println("No ldap publishing configurations.");
+ return;
+ }
+ Enumeration substores = types.getSubStoreNames();
+
+ while (substores.hasMoreElements()) {
+ String certType = (String) substores.nextElement();
+ IConfigStore current = types.getSubStore(certType);
+
+ if (current == null || current.size() <= 0) {
+ CMS.debug(
+ "No ldap publish configuration for " + certType + " found.");
+ continue;
+ }
+ ILdapPlugin mapper = null, publisher = null;
+ IConfigStore mapperConf = null, publisherConf = null;
+ String mapperClassName = null, publisherClassName = null;
+
+ try {
+ mapperConf = current.getSubStore(PROP_MAPPER);
+ mapperClassName = mapperConf.getString(PROP_CLASS, null);
+ if (mapperClassName != null && mapperClassName.length() > 0) {
+ CMS.debug(
+ "mapper " + mapperClassName + " for " + certType);
+ mapper = (ILdapPlugin)
+ Class.forName(mapperClassName).newInstance();
+ mapper.init(mapperConf);
+ }
+ publisherConf = current.getSubStore(PROP_PUBLISHER);
+ publisherClassName = publisherConf.getString(PROP_CLASS, null);
+ if (publisherClassName != null &&
+ publisherClassName.length() > 0) {
+ CMS.debug(
+ "publisher " + publisherClassName + " for " + certType);
+ publisher = (ILdapPlugin)
+ Class.forName(publisherClassName).newInstance();
+ publisher.init(publisherConf);
+ }
+ mMappers.put(certType, new LdapMappers(mapper, publisher));
+ } catch (ClassNotFoundException e) {
+ String missingClass = mapperClassName +
+ ((publisherClassName == null) ? "" :
+ (" or " + publisherClassName));
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_FIND_CLASS", missingClass));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CLASS_NOT_FOUND", missingClass));
+ } catch (InstantiationException e) {
+ String badInstance = mapperClassName +
+ ((publisherClassName == null) ? "" :
+ (" or " + publisherClassName));
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_INST_CLASS",
+ badInstance ,certType));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INSTANTIATING_CLASS_FAILED", badInstance));
+ } catch (IllegalAccessException e) {
+ String badInstance = mapperClassName +
+ ((publisherClassName == null) ? "" :
+ (" or " + publisherClassName));
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_INSUFFICIENT_CREDENTIALS", badInstance, certType));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INSUFFICIENT_CREDENTIALS", certType));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_INIT_ERROR", certType, e.toString()));
+ throw e;
+ }
+ }
+ mInited = true;
+ }
+
+ protected void initHandlers() {
+ mEventHandlers.put(IRequest.ENROLLMENT_REQUEST,
+ new HandleEnrollment(this));
+ mEventHandlers.put(IRequest.RENEWAL_REQUEST,
+ new HandleRenewal(this));
+ mEventHandlers.put(IRequest.REVOCATION_REQUEST,
+ new HandleRevocation(this));
+ mEventHandlers.put(IRequest.UNREVOCATION_REQUEST,
+ new HandleUnrevocation(this));
+ }
+
+ public void accept(IRequest r) {
+ String type = r.getRequestType();
+ boolean error = false;
+
+ IRequestListener handler = (IRequestListener) mEventHandlers.get(type);
+
+ if (handler == null) {
+ CMS.debug(
+ "Nothing to publish for request type " + type);
+ return;
+ }
+ handler.accept(r);
+ }
+
+ public void publish(String certType, X509Certificate cert)
+ throws ELdapException {
+ // get mapper and publisher for cert type.
+ LdapMappers mappers = getMappers(certType);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug("publisher for " + certType + " is null");
+ return;
+ }
+ publish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, cert);
+
+ // set the ldap published flag.
+ setPublishedFlag(cert.getSerialNumber(), true);
+ }
+
+ public void unpublish(String certType, X509Certificate cert)
+ throws ELdapException {
+ // get mapper and publisher for cert type.
+ LdapMappers mappers = getMappers(certType);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug("publisher for " + certType + " is null");
+ return;
+ }
+ unpublish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, cert);
+
+ // set the ldap published flag.
+ setPublishedFlag(cert.getSerialNumber(), false);
+ }
+
+ /**
+ * set published flag - true when published, false when unpublished.
+ * not exist means not published.
+ */
+ public void setPublishedFlag(BigInteger serialNo, boolean published) {
+ if (!(mAuthority instanceof ICertificateAuthority))
+ return;
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ try {
+ ICertificateRepository certdb = (ICertificateRepository) ca.getCertificateRepository();
+ ICertRecord certRec = (ICertRecord) certdb.readCertificateRecord(serialNo);
+ MetaInfo metaInfo = certRec.getMetaInfo();
+
+ if (metaInfo == null) {
+ metaInfo = new MetaInfo();
+ }
+ metaInfo.set(
+ CertRecord.META_LDAPPUBLISH, String.valueOf(published));
+ ModificationSet modSet = new ModificationSet();
+
+ modSet.add(ICertRecord.ATTR_META_INFO,
+ Modification.MOD_REPLACE, metaInfo);
+ certdb.modifyCertificateRecord(serialNo, modSet);
+ } catch (EBaseException e) {
+ // not fatal. just log warning.
+ log(ILogger.LL_WARN,
+ "Cannot mark cert 0x" + serialNo.toString(16) + " published as " + published +
+ " in the ldap directory. Cert Record not found. Error: " +
+ e.getMessage());
+ }
+ }
+
+ public LDAPConnection getConn() throws ELdapException {
+ return mLdapConnFactory.getConn();
+ }
+
+ public void returnConn(LDAPConnection conn) throws ELdapException {
+ mLdapConnFactory.returnConn(conn);
+ }
+
+ public void publish(ILdapMapper mapper, ILdapPublisher publisher,
+ X509Certificate cert)
+ throws ELdapException {
+ LDAPConnection conn = null;
+
+ try {
+ String dirdn = null;
+ String result = null;
+
+ conn = mLdapConnFactory.getConn();
+ if (mapper == null) { // use the cert's subject name exactly
+ dirdn = cert.getSubjectDN().toString();
+ CMS.debug(
+ "no mapper found. Using subject name exactly." +
+ cert.getSubjectDN());
+ } else {
+ result = mapper.map(conn, cert);
+ dirdn = result;
+ if (dirdn == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_PUBLISH_NOT_MATCH",
+ cert.getSerialNumber().toString(16),
+ cert.getSubjectDN().toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH",
+ cert.getSubjectDN().toString()));
+ }
+ }
+ publisher.publish(conn, dirdn, cert);
+ } finally {
+ if (conn != null) {
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ }
+
+ public void unpublish(ILdapMapper mapper, ILdapPublisher publisher,
+ X509Certificate cert)
+ throws ELdapException {
+ LDAPConnection conn = null;
+
+ try {
+ String dirdn = null;
+ String result = null;
+
+ conn = mLdapConnFactory.getConn();
+ if (mapper == null) { // use the cert's subject name exactly
+ dirdn = cert.getSubjectDN().toString();
+ } else {
+ result = mapper.map(conn, cert);
+ dirdn = result;
+ if (dirdn == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_PUBLISH_NOT_MATCH",
+ cert.getSerialNumber().toString(16),
+ cert.getSubjectDN().toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH",
+ cert.getSubjectDN().toString()));
+ }
+ }
+ publisher.unpublish(conn, dirdn, cert);
+ } finally {
+ if (conn != null) {
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ }
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ */
+ public void publish(X509CRLImpl crl)
+ throws ELdapException {
+ ILdapCrlMapper mapper = null;
+ ILdapPublisher publisher = null;
+
+ LdapMappers mappers = getMappers(PROP_TYPE_CRL);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug("publisher for crl is null");
+ return;
+ }
+
+ LDAPConnection conn = null;
+ String dn = null;
+
+ try {
+ String result = null;
+
+ conn = mLdapConnFactory.getConn();
+ if (mappers.mapper == null) {
+ dn = ((X500Name) crl.getIssuerDN()).toLdapDNString();
+ } else {
+ result = ((ILdapMapper) mappers.mapper).map(conn, crl);
+ dn = result;
+ if (dn == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_CRL_NOT_MATCH"));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH",
+ crl.getIssuerDN().toString()));
+ }
+ }
+ ((ILdapPublisher) mappers.publisher).publish(conn, dn, crl);
+ } catch (ELdapException e) {
+ //e.printStackTrace();
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e);
+ throw e;
+ } catch (IOException e) {
+ CMS.debug("Error publishing CRL to " + dn + ": " + e);
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_ISSUER_FROM_CRL_FAILED", (String) ""));
+ } finally {
+ if (conn != null) {
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ }
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ */
+ public void publish(String dn, X509CRL crl)
+ throws ELdapException {
+ LdapMappers mappers = getMappers(PROP_TYPE_CRL);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug("publisher for crl is null");
+ return;
+ }
+
+ LDAPConnection conn = null;
+
+ try {
+ conn = mLdapConnFactory.getConn();
+ ((ILdapPublisher) mappers.publisher).publish(conn, dn, crl);
+ } catch (ELdapException e) {
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e.toString());
+ throw e;
+ } finally {
+ if (conn != null) {
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ }
+
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_LDAP, level,
+ "LdapPublishModule: " + msg);
+ }
+
+}
+
+
+class LdapMappers {
+ public LdapMappers(ILdapPlugin aMapper, ILdapPlugin aPublisher) {
+ mapper = aMapper;
+ publisher = aPublisher;
+ }
+ public ILdapPlugin mapper = null;
+ public ILdapPlugin publisher = null;
+}
+
+
+class HandleEnrollment implements IRequestListener {
+ LdapPublishModule mModule = null;
+
+ public HandleEnrollment(LdapPublishModule module) {
+ mModule = module;
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "handling publishing for enrollment request id " +
+ r.getRequestId());
+
+ // in case it's not meant for us
+ if (r.getExtDataInInteger(IRequest.RESULT) == null)
+ return;
+
+ // check if request failed.
+ if ((r.getExtDataInInteger(IRequest.RESULT)).equals(IRequest.RES_ERROR)) {
+ CMS.debug("Request errored. " +
+ "Nothing to publish for enrollment request id " +
+ r.getRequestId());
+ return;
+ }
+ CMS.debug("Checking publishing for request " +
+ r.getRequestId());
+ // check if issued certs is set.
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ CMS.debug(
+ "No certs to publish for request id " + r.getRequestId());
+ return;
+ }
+
+ // get mapper and publisher for client certs.
+ LdapMappers mappers =
+ mModule.getMappers(LdapPublishModule.PROP_TYPE_CLIENT);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug(
+ "In publishing: No publisher for type " +
+ LdapPublishModule.PROP_TYPE_CLIENT);
+ return;
+ }
+
+ // publish
+ Integer results[] = new Integer[certs.length];
+ X509CertImpl cert;
+
+ for (int i = 0; i < certs.length; i++) {
+ try {
+ if (certs[i] == null)
+ continue;
+ mModule.publish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, certs[i]);
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "Published cert serial no 0x" + certs[i].getSerialNumber().toString(16));
+ mModule.setPublishedFlag(certs[i].getSerialNumber(), true);
+ } catch (ELdapException e) {
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_PUBLISH",
+ certs[i].getSerialNumber().toString(16),e.toString()));
+ results[i] = IRequest.RES_ERROR;
+ }
+ r.setExtData("ldapPublishStatus", results);
+ }
+ }
+}
+
+
+class HandleRenewal implements IRequestListener {
+ private LdapPublishModule mModule = null;
+ public HandleRenewal(LdapPublishModule module) {
+ mModule = module;
+ }
+
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException
+ {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ // Note we do not remove old certs from directory during renewal
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs == null || certs.length == 0) {
+ CMS.debug("no certs to publish for renewal " +
+ "request " + r.getRequestId());
+ return;
+ }
+ Integer results[] = new Integer[certs.length];
+ X509CertImpl cert = null;
+
+ // get mapper and publisher for cert type.
+ LdapMappers mappers =
+ mModule.getMappers(LdapPublishModule.PROP_TYPE_CLIENT);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug(
+ "publisher for " + LdapPublishModule.PROP_TYPE_CLIENT + " is null");
+ return;
+ }
+
+ boolean error = false;
+
+ for (int i = 0; i < certs.length; i++) {
+ cert = (X509CertImpl) certs[i];
+ if (cert == null)
+ continue; // there was an error issuing this cert.
+ try {
+ mModule.publish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, cert);
+ results[i] = IRequest.RES_SUCCESS;
+ mModule.log(ILogger.LL_INFO,
+ "Published cert serial no 0x" + cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_PUBLISH",
+ cert.getSerialNumber().toString(16), e.getMessage()));
+ results[i] = IRequest.RES_ERROR;
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
+
+class HandleRevocation implements IRequestListener {
+ private LdapPublishModule mModule = null;
+ public HandleRevocation(LdapPublishModule module) {
+ mModule = module;
+ }
+
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException
+ {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "Handle publishing for revoke request id " + r.getRequestId());
+
+ // get fields in request.
+ X509CertImpl[] revcerts = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (revcerts == null || revcerts.length == 0 || revcerts[0] == null) {
+ // no certs in revoke.
+ CMS.debug(
+ "Nothing to unpublish for revocation " +
+ "request " + r.getRequestId());
+ return;
+ }
+
+ // get mapper and publisher for cert type.
+ LdapMappers mappers =
+ mModule.getMappers(LdapPublishModule.PROP_TYPE_CLIENT);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug(
+ "publisher for " + LdapPublishModule.PROP_TYPE_CLIENT + " is null");
+ return;
+ }
+
+ boolean error = false;
+ Integer results[] = new Integer[revcerts.length];
+
+ for (int i = 0; i < revcerts.length; i++) {
+ X509CertImpl cert = revcerts[i];
+
+ results[i] = IRequest.RES_ERROR;
+ try {
+ mModule.unpublish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, cert);
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "Unpublished cert serial no 0x" + cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_UNPUBLISH",
+ cert.getSerialNumber().toString(16), e.getMessage()));
+ } catch (EBaseException e) {
+ error = true;
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_FIND",
+ cert.getSerialNumber().toString(16), e.getMessage()));
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
+
+class HandleUnrevocation implements IRequestListener {
+ private LdapPublishModule mModule = null;
+ public HandleUnrevocation(LdapPublishModule module) {
+ mModule = module;
+ }
+
+ public void set(String name, String val)
+ {
+ }
+ public void init(ISubsystem sub, IConfigStore config) throws EBaseException
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "Handle publishing for unrevoke request id " + r.getRequestId());
+
+ // get fields in request.
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ // no certs in unrevoke.
+ CMS.debug(
+ "Nothing to publish for unrevocation " +
+ "request " + r.getRequestId());
+ return;
+ }
+
+ // get mapper and publisher for cert type.
+ LdapMappers mappers =
+ mModule.getMappers(LdapPublishModule.PROP_TYPE_CLIENT);
+
+ if (mappers == null || mappers.publisher == null) {
+ CMS.debug(
+ "publisher for " + LdapPublishModule.PROP_TYPE_CLIENT + " is null");
+ return;
+ }
+
+ boolean error = false;
+ Integer results[] = new Integer[certs.length];
+
+ for (int i = 0; i < certs.length; i++) {
+ results[i] = IRequest.RES_ERROR;
+ try {
+ mModule.publish((ILdapMapper) mappers.mapper,
+ (ILdapPublisher) mappers.publisher, certs[i]);
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "Unpublished cert serial no 0x" + certs[i].getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_UNPUBLISH",
+ certs[i].getSerialNumber().toString(16), e.getMessage()));
+ } catch (EBaseException e) {
+ error = true;
+ mModule.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_FIND",
+ certs[i].getSerialNumber().toString(16), e.getMessage()));
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java
new file mode 100644
index 000000000..d467bd957
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java
@@ -0,0 +1,531 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.math.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.publish.*;
+import java.security.cert.*;
+import java.io.IOException;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+
+public class LdapRequestListener implements IRequestListener {
+ private boolean mInited = false;
+
+ /**
+ * handlers for request types (events)
+ * each handler implement IRequestListener
+ */
+ private Hashtable mRequestListeners = new Hashtable();
+
+ private IPublisherProcessor mPublisherProcessor = null;
+
+ public LdapRequestListener() {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void init(ISubsystem sys, IConfigStore config) throws EBaseException {
+ if (mInited) return;
+
+ mPublisherProcessor = (IPublisherProcessor)sys;
+
+ mRequestListeners.put(IRequest.ENROLLMENT_REQUEST,
+ new LdapEnrollmentListener(mPublisherProcessor));
+ mRequestListeners.put(IRequest.RENEWAL_REQUEST,
+ new LdapRenewalListener(mPublisherProcessor));
+ mRequestListeners.put(IRequest.REVOCATION_REQUEST,
+ new LdapRevocationListener(mPublisherProcessor));
+ mRequestListeners.put(IRequest.UNREVOCATION_REQUEST,
+ new LdapUnrevocationListener(mPublisherProcessor));
+ mInited = true;
+ }
+
+ public PublishObject getPublishObject(IRequest r) {
+ String type = r.getRequestType();
+ PublishObject obj = new PublishObject();
+
+ if (type.equals(IRequest.ENROLLMENT_REQUEST)) {
+ // in case it's not meant for us
+ if (r.getExtDataInInteger(IRequest.RESULT) == null)
+ return null;
+
+ // check if request failed.
+ if ((r.getExtDataInInteger(IRequest.RESULT)).equals(IRequest.RES_ERROR)) {
+ CMS.debug("Request errored. " +
+ "Nothing to publish for enrollment request id " +
+ r.getRequestId());
+ return null;
+ }
+ CMS.debug("Checking publishing for request " +
+ r.getRequestId());
+ // check if issued certs is set.
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ CMS.debug(
+ "No certs to publish for request id " +
+ r.getRequestId());
+ return null;
+ }
+ obj.setCerts(certs);
+ return obj;
+ } else if (type.equals(IRequest.RENEWAL_REQUEST)) {
+ // Note we do not remove old certs from directory during renewal
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs == null || certs.length == 0) {
+ CMS.debug("no certs to publish for renewal " +
+ "request " + r.getRequestId());
+ return null;
+ }
+ obj.setCerts(certs);
+ return obj;
+ } else if (type.equals(IRequest.REVOCATION_REQUEST)) {
+ X509CertImpl[] revcerts = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (revcerts == null || revcerts.length == 0 || revcerts[0] == null) {
+ // no certs in revoke.
+ CMS.debug(
+ "Nothing to unpublish for revocation " +
+ "request " + r.getRequestId());
+ return null;
+ }
+ obj.setCerts(revcerts);
+ return obj;
+ } else if (type.equals(IRequest.UNREVOCATION_REQUEST)) {
+ X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ // no certs in unrevoke.
+ CMS.debug(
+ "Nothing to publish for unrevocation " +
+ "request " + r.getRequestId());
+ return null;
+ }
+ obj.setCerts(certs);
+ return obj;
+ } else {
+ CMS.debug("Request errored. " +
+ "Nothing to publish for request id " +
+ r.getRequestId());
+ return null;
+ }
+
+ }
+
+ public void accept(IRequest r) {
+ String type = r.getRequestType();
+
+ IRequestListener handler = (IRequestListener) mRequestListeners.get(type);
+
+ if (handler == null) {
+ CMS.debug(
+ "Nothing to publish for request type " + type);
+ return;
+ }
+ handler.accept(r);
+ }
+
+}
+
+
+class LdapEnrollmentListener implements IRequestListener {
+ IPublisherProcessor mProcessor = null;
+
+ public LdapEnrollmentListener(IPublisherProcessor processor) {
+ mProcessor = processor;
+ }
+
+ public void init(ISubsystem sys, IConfigStore config) throws EBaseException {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "LdapRequestListener handling publishing for enrollment request id " +
+ r.getRequestId());
+
+ String profileId = r.getExtDataInString("profileId");
+
+ if (profileId == null) {
+ // in case it's not meant for us
+ if (r.getExtDataInInteger(IRequest.RESULT) == null)
+ return;
+
+ // check if request failed.
+ if ((r.getExtDataInInteger(IRequest.RESULT)).equals(IRequest.RES_ERROR)) {
+ CMS.debug("Request errored. " +
+ "Nothing to publish for enrollment request id " +
+ r.getRequestId());
+ return;
+ }
+ }
+ CMS.debug("Checking publishing for request " +
+ r.getRequestId());
+ // check if issued certs is set.
+ Certificate[] certs = null;
+ if (profileId == null) {
+ certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ } else {
+ certs = new Certificate[1];
+ certs[0] = r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ }
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ CMS.debug(
+ "No certs to publish for request id " + r.getRequestId());
+ return;
+ }
+
+ if (certs[0] instanceof X509CertImpl)
+ acceptX509(r, certs);
+ }
+
+ public void acceptX509(IRequest r, Certificate[] certs) {
+ Integer results[] = new Integer[certs.length];
+ boolean error = false;
+
+ for (int i = 0; i < certs.length; i++) {
+ X509CertImpl xcert = (X509CertImpl) certs[i];
+
+ if (xcert == null)
+ continue;
+ try {
+ mProcessor.publishCert(xcert, r);
+
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "acceptX509: Published cert serial no 0x" +
+ xcert.getSerialNumber().toString(16));
+ //mProcessor.setPublishedFlag(xcert.getSerialNumber(), true);
+ } catch (ELdapException e) {
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_PUBLISH",
+ xcert.getSerialNumber().toString(16), e.toString()));
+ results[i] = IRequest.RES_ERROR;
+ error = true;
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
+
+class LdapRenewalListener implements IRequestListener {
+ private IPublisherProcessor mProcessor = null;
+
+ public LdapRenewalListener(IPublisherProcessor processor) {
+ mProcessor = processor;
+ }
+ public void init(ISubsystem sys, IConfigStore config) throws EBaseException {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ // Note we do not remove old certs from directory during renewal
+ Certificate[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ if (certs == null || certs.length == 0) {
+ CMS.debug("no certs to publish for renewal " +
+ "request " + r.getRequestId());
+ return;
+ }
+
+ if (certs[0] instanceof X509CertImpl)
+ acceptX509(r, certs);
+ }
+
+ public void acceptX509(IRequest r, Certificate[] certs) {
+ X509CertImpl cert = null;
+
+ Integer results[] = new Integer[certs.length];
+ boolean error = false;
+
+ for (int i = 0; i < certs.length; i++) {
+ cert = (X509CertImpl) certs[i];
+ if (cert == null)
+ continue; // there was an error issuing this cert.
+ try {
+ mProcessor.publishCert(cert, r);
+ results[i] = IRequest.RES_SUCCESS;
+ mProcessor.log(ILogger.LL_INFO,
+ "Published cert serial no 0x" +
+ cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_PUBLISH",
+ cert.getSerialNumber().toString(16), e.toString()));
+ results[i] = IRequest.RES_ERROR;
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
+
+class LdapRevocationListener implements IRequestListener {
+ private IPublisherProcessor mProcessor = null;
+
+ public LdapRevocationListener(IPublisherProcessor processor) {
+ mProcessor = processor;
+ }
+ public void init(ISubsystem sys, IConfigStore config) throws EBaseException {
+ }
+
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "Handle publishing for revoke request id " + r.getRequestId());
+
+ // get fields in request.
+ Certificate[] certs = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ // no certs in revoke.
+ CMS.debug(
+ "Nothing to unpublish for revocation " +
+ "request " + r.getRequestId());
+ return;
+ }
+
+ if (certs[0] instanceof X509CertImpl)
+ acceptX509(r, certs);
+ }
+
+ public void acceptX509(IRequest r, Certificate[] revcerts) {
+ boolean error = false;
+ Integer results[] = new Integer[revcerts.length];
+
+ error = false;
+ for (int i = 0; i < revcerts.length; i++) {
+ X509CertImpl cert = (X509CertImpl) revcerts[i];
+
+ results[i] = IRequest.RES_ERROR;
+ try {
+ // We need the enrollment request to sort out predicate
+ BigInteger serial = cert.getSerialNumber();
+ ICertRecord certRecord = null;
+ IAuthority auth = (IAuthority)mProcessor.getAuthority();
+
+ if (auth == null ||
+ !(auth instanceof ICertificateAuthority)) {
+ mProcessor.log(ILogger.LL_WARN,
+ "Trying to get a certificate from non certificate authority.");
+ } else {
+ ICertificateRepository certdb =
+ (ICertificateRepository) ((ICertificateAuthority) auth).getCertificateRepository();
+
+ if (certdb == null) {
+ mProcessor.log(ILogger.LL_WARN, "Cert DB is null for " + auth);
+ } else {
+ try {
+ certRecord = (ICertRecord) certdb.readCertificateRecord(serial);
+ } catch (EBaseException e) {
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_GET_CERT_RECORD",
+ serial.toString(16), e.toString()));
+ }
+ }
+ }
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ if (certRecord != null)
+ metaInfo =
+ (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ mProcessor.log(ILogger.LL_FAILURE,
+ "failed getting CertRecord.ATTR_META_INFO for cert serial number 0x" +
+ serial.toString(16));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest req = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ req = auth.getRequestQueue().findRequest(rid);
+ }
+ mProcessor.unpublishCert(cert, req);
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "Unpublished cert serial no 0x" +
+ cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_UNPUBLISH",
+ cert.getSerialNumber().toString(16), e.toString()));
+ } catch (EBaseException e) {
+ error = true;
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_FIND",
+ cert.getSerialNumber().toString(16), e.toString()));
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
+
+class LdapUnrevocationListener implements IRequestListener {
+ private IPublisherProcessor mProcessor = null;
+
+ public LdapUnrevocationListener(IPublisherProcessor processor) {
+ mProcessor = processor;
+ }
+ public void init(ISubsystem sys, IConfigStore config) throws EBaseException {
+ }
+ public void set(String name, String val)
+ {
+ }
+
+ public void accept(IRequest r) {
+ CMS.debug(
+ "Handle publishing for unrevoke request id " + r.getRequestId());
+
+ // get fields in request.
+ Certificate[] certs = r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ // no certs in unrevoke.
+ CMS.debug(
+ "Nothing to publish for unrevocation " +
+ "request " + r.getRequestId());
+ return;
+ }
+
+ if (certs[0] instanceof X509CertImpl)
+ acceptX509(r, certs);
+ }
+
+ public void acceptX509(IRequest r, Certificate[] certs) {
+ boolean error = false;
+ Integer results[] = new Integer[certs.length];
+ X509CertImpl xcert = null;
+
+ for (int i = 0; i < certs.length; i++) {
+ results[i] = IRequest.RES_ERROR;
+ xcert = (X509CertImpl) certs[i];
+ try {
+ // We need the enrollment request to sort out predicate
+ BigInteger serial = xcert.getSerialNumber();
+ ICertRecord certRecord = null;
+ IAuthority auth = (IAuthority)mProcessor.getAuthority();
+
+ if (auth == null ||
+ !(auth instanceof ICertificateAuthority)) {
+ mProcessor.log(ILogger.LL_WARN,
+ "Trying to get a certificate from non certificate authority.");
+ } else {
+ ICertificateRepository certdb = (ICertificateRepository)
+ ((ICertificateAuthority) auth).getCertificateRepository();
+
+ if (certdb == null) {
+ mProcessor.log(ILogger.LL_WARN, "Cert DB is null for " + auth);
+ } else {
+ try {
+ certRecord = (ICertRecord) certdb.readCertificateRecord(serial);
+ } catch (EBaseException e) {
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_GET_CERT_RECORD", serial.toString(16), e.toString()));
+ }
+ }
+ }
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ if (certRecord != null)
+ metaInfo =
+ (MetaInfo) certRecord.get(CertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ mProcessor.log(ILogger.LL_FAILURE,
+ "Failed getting CertRecord.ATTR_META_INFO for cert serial number 0x" +
+ serial.toString(16));
+ } else {
+ ridString = (String) metaInfo.get(CertRecord.META_REQUEST_ID);
+ }
+
+ IRequest req = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ req = auth.getRequestQueue().findRequest(rid);
+ }
+ mProcessor.publishCert(xcert, req);
+ results[i] = IRequest.RES_SUCCESS;
+ CMS.debug(
+ "Published cert serial no 0x" +
+ xcert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ error = true;
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_PUBLISH",
+ xcert.getSerialNumber().toString(16), e.toString()));
+ } catch (EBaseException e) {
+ error = true;
+ mProcessor.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_CERT_NOT_FIND",
+ xcert.getSerialNumber().toString(16), e.toString()));
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapRule.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapRule.java
new file mode 100644
index 000000000..d3872740e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapRule.java
@@ -0,0 +1,297 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * The publishing rule that links mapper and publisher together.
+ */
+public class LdapRule implements ILdapRule, IExtendedPluginInfo {
+ public final static String NOMAPPER = "<NONE>";
+
+ private IConfigStore mConfig = null;
+ protected ILdapExpression mFilterExp = null;
+ private String mInstanceName = null;
+
+ private IPublisherProcessor mProcessor = null;
+
+ private static String[] epi_params = null; // extendedpluginInfo
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ //dont know why it's null here.
+ //if (mProcessor == null) System.out.println("p null");
+
+ if (Debug.ON) {
+ Debug.trace("LdapRule: getExtendedPluginInfo() - returning epi_params:");
+ for (int i = 0; i < epi_params.length; i++) {
+ Debug.trace("[" + i + "] " + epi_params[i]);
+ }
+ }
+ return epi_params;
+ }
+
+ public void init(IPublisherProcessor processor, IConfigStore config) throws EBaseException {
+ mConfig = config;
+
+ mProcessor = processor;
+ Enumeration mappers = mProcessor.getMapperInsts().keys();
+ Enumeration publishers = mProcessor.getPublisherInsts().keys();
+
+ String map = NOMAPPER;
+
+ for (; mappers.hasMoreElements();) {
+ String name = (String) mappers.nextElement();
+
+ map = map + "," + name;
+ }
+ String publish = "";
+
+ for (; publishers.hasMoreElements();) {
+ String name = (String) publishers.nextElement();
+
+ publish = publish + "," + name;
+ }
+
+ epi_params = new String[] {
+ "type;choice(cacert,crl, certs);The publishing object type",
+ "mapper;choice(" + map + ");Use the mapper to find the ldap dn \nto publish the certificate or crl",
+ "publisher;choice(" + publish + ");Use the publisher to publish the certificate or crl a directory etc",
+ "enable;boolean;Enable this publishing rule",
+ "predicate;string;Filter describing when this publishing rule shoule be used"
+ };
+
+ // Read the predicate expression if any associated
+ // with the rule
+ String exp = config.getString(IPublisherProcessor.PROP_PREDICATE, null);
+
+ if (exp != null)
+ exp = exp.trim();
+ if (exp != null && exp.length() > 0) {
+ ILdapExpression filterExp = LdapPredicateParser.parse(exp);
+
+ setPredicate(filterExp);
+ }
+ //if (mProcessor == null) System.out.println("null");
+
+ }
+
+ /**
+ * The init method in ILdapPlugin
+ * It can not set set mapper,publisher choice for console dynamicly
+ * Should not use this method to init.
+ */
+ public void init(IConfigStore config) throws EBaseException {
+ mConfig = config;
+
+ epi_params = new String[] {
+ "type;choice(cacert, crl, certs);The publishing object type",
+ "mapper;choice(null,LdapUserCertMap,LdapServerCertMap,LdapCrlMap,LdapCaCertMap);Use the mapper to find the ldap dn to publish the certificate or crl",
+ "publisher;choice(LdapUserCertPublisher,LdapServerCertPublisher,LdapCrlPublisher,LdapCaCertPublisher);Use the publisher to publish the certificate or crl a directory etc",
+ "enable;boolean;",
+ "predicate;string;"
+ };
+
+ // Read the predicate expression if any associated
+ // with the rule
+ String exp = config.getString(IPublisherProcessor.PROP_PREDICATE, null);
+
+ if (exp != null)
+ exp = exp.trim();
+ if (exp != null && exp.length() > 0) {
+ ILdapExpression filterExp = LdapPredicateParser.parse(exp);
+
+ setPredicate(filterExp);
+ }
+
+ }
+
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName() {
+ return "LdapRule";
+ }
+
+ /**
+ * Returns the description of the ldap publisher.
+ */
+ public String getDescription() {
+ return "LdapRule";
+ }
+
+ /**
+ * Set the instance name
+ */
+ public void setInstanceName(String insName) {
+ mInstanceName = insName;
+ }
+
+ /**
+ * Returns the instance name
+ */
+ public String getInstanceName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams() {
+ //if (mProcessor == null) System.out.println("xxxxnull");
+ //dont know why the processor was null in getExtendedPluginInfo()
+ Enumeration mappers = mProcessor.getMapperInsts().keys();
+ Enumeration publishers = mProcessor.getPublisherInsts().keys();
+ String map = NOMAPPER;
+
+ for (; mappers.hasMoreElements();) {
+ String name = (String) mappers.nextElement();
+
+ map = map + "," + name;
+ }
+ String publish = "";
+
+ for (; publishers.hasMoreElements();) {
+ String name = (String) publishers.nextElement();
+
+ publish = publish + "," + name;
+ }
+
+ /*
+ mExtendedPluginInfo = new NameValuePairs();
+ mExtendedPluginInfo.add("type","choice(client,server,objSignClient,smime,ca,crl);The publishing object type");
+ mExtendedPluginInfo.add("mapper","choice("+map+");Use the mapper to find the ldap dn \nto publish the certificate or crl");
+ mExtendedPluginInfo.add("publisher","choice("+publish+");Use the publisher to publish the certificate or crl a directory etc");
+ mExtendedPluginInfo.add("enable","boolean;");
+ mExtendedPluginInfo.add("predicate","string;");
+ */
+
+ Vector v = new Vector();
+
+ try {
+ v.addElement(IPublisherProcessor.PROP_TYPE + "=" +
+ mConfig.getString(IPublisherProcessor.PROP_TYPE, ""));
+ v.addElement(IPublisherProcessor.PROP_PREDICATE + "=" +
+ mConfig.getString(IPublisherProcessor.PROP_PREDICATE,
+ ""));
+ v.addElement(IPublisherProcessor.PROP_ENABLE + "=" +
+ mConfig.getString(IPublisherProcessor.PROP_ENABLE,
+ ""));
+ v.addElement(IPublisherProcessor.PROP_MAPPER + "=" +
+ mConfig.getString(IPublisherProcessor.PROP_MAPPER,
+ ""));
+ v.addElement(IPublisherProcessor.PROP_PUBLISHER + "=" +
+ mConfig.getString(IPublisherProcessor.PROP_PUBLISHER,
+ ""));
+ } catch (EBaseException e) {
+ }
+ return v;
+ }
+
+ /**
+ * Sets a predicate expression for rule matching.
+ * <P>
+ *
+ * @param exp The predicate expression for the rule.
+ */
+ public void setPredicate(ILdapExpression exp) {
+ mFilterExp = exp;
+ }
+
+ /**
+ * Returns the predicate expression for the rule.
+ * <P>
+ *
+ * @return The predicate expression for the rule.
+ */
+ public ILdapExpression getPredicate() {
+ return mFilterExp;
+ }
+
+ public String getMapper() {
+ try {
+ String map =
+ mConfig.getString(IPublisherProcessor.PROP_MAPPER, "");
+
+ if (map != null)
+ map = map.trim();
+ if (map == null || map.equals(""))
+ return null;
+ else if (map.equals(NOMAPPER))
+ return null;
+ else
+ return map;
+ } catch (EBaseException e) {
+ }
+ return null;
+ }
+
+ public String getPublisher() {
+ try {
+ return mConfig.getString(IPublisherProcessor.PROP_PUBLISHER, "");
+ } catch (EBaseException e) {
+ }
+ return null;
+ }
+
+ public String getType() {
+ try {
+ return mConfig.getString(IPublisherProcessor.PROP_TYPE, "");
+ } catch (EBaseException e) {
+ }
+ return null;
+ }
+
+ public boolean enabled() {
+ try {
+ boolean enable =
+ mConfig.getBoolean(IPublisherProcessor.PROP_ENABLE, false);
+
+ //System.out.println(enable);
+ return enable;
+ } catch (EBaseException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ v.addElement(IPublisherProcessor.PROP_TYPE + "=");
+ v.addElement(IPublisherProcessor.PROP_PREDICATE + "=");
+ v.addElement(IPublisherProcessor.PROP_ENABLE + "=true");
+ v.addElement(IPublisherProcessor.PROP_MAPPER + "=");
+ v.addElement(IPublisherProcessor.PROP_PUBLISHER + "=");
+ return v;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java b/pki/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java
new file mode 100644
index 000000000..d3646c7b8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java
@@ -0,0 +1,475 @@
+// --- 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.cmscore.ldap;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * This class represents an expression of the form var = val,
+ * var != val, var < val, var > val, var <= val, var >= val.
+ *
+ * Expressions are used as predicates for publishing rule selection.
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LdapSimpleExpression implements ILdapExpression {
+ private String mPfx;
+ private String mVar;
+ private String mVal;
+ private String mPartialMatch;
+ private int mOp;
+ private boolean hasWildCard;
+ public static final char WILDCARD_CHAR = '*';
+
+ // This is just for indicating a null expression.
+ public static LdapSimpleExpression NULL_EXPRESSION = new LdapSimpleExpression("null", OP_EQUAL, "null");
+
+ public static ILdapExpression parse(String input)
+ throws ELdapException {
+ // Get the index of operator
+ // Debug.trace("LdapSimpleExpression::input: " + input);
+ String var = null;
+ int op = -1;
+ String val = null;
+
+ // XXX - Kanda - Need to change this parsing code eventually.
+ ExpressionComps comps = parseForEquality(input);
+
+ if (comps == null)
+ comps = parseForInEquality(input);
+ if (comps == null)
+ comps = parseForGE(input);
+ if (comps == null)
+ comps = parseForLE(input);
+ if (comps == null)
+ comps = parseForGT(input);
+ if (comps == null)
+ comps = parseForLT(input);
+ if (comps == null)
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_BAD_LDAP_EXPRESSION", input));
+
+ String pfx = null;
+ String rawVar = comps.getAttr();
+ int dotIdx = rawVar.indexOf('.');
+
+ if (dotIdx != -1) {
+ pfx = rawVar.substring(0, dotIdx).trim();
+ var = rawVar.substring(dotIdx + 1).trim();
+ } else {
+ var = rawVar;
+ }
+ op = comps.getOp();
+ val = comps.getVal();
+ return new LdapSimpleExpression(pfx, var, op, val);
+ }
+
+ public LdapSimpleExpression(String var, int op, String val) {
+ this(null, var, op, val);
+ }
+
+ public LdapSimpleExpression(String prefix, String var, int op, String val) {
+ // Assert that op has to be either ILdapExpression.OP_EQUAL or
+ // ILdapExpression.OP_NEQUAL.
+ // If val or var is null throw an exception!
+ mPfx = prefix;
+ mVar = var;
+ mOp = op;
+ mVal = val;
+ int firstIndex;
+
+ if ((firstIndex = mVal.indexOf(WILDCARD_CHAR)) >= 0) {
+ hasWildCard = true;
+ int nextIndex = mVal.indexOf(WILDCARD_CHAR, firstIndex + 1);
+
+ if (nextIndex == -1) {
+ if (firstIndex == 0)
+ mPartialMatch = mVal.substring(1);
+ else
+ mPartialMatch = mVal.substring(0, firstIndex);
+ } else
+ mPartialMatch = mVal.substring(firstIndex + 1, nextIndex);
+ } else
+ hasWildCard = false;
+ }
+
+ public boolean evaluate(SessionContext sc)
+ throws ELdapException {
+ Object givenVal;
+
+ try {
+ // Try exact case first.
+ givenVal = (String) sc.get(mVar);
+ }catch (Exception e) {
+ givenVal = (String) null;
+ }
+
+ // It is kind of a problem here if all letters are in
+ // lowercase or in upperCase - for example in the case
+ // of directory attributes.
+ if (givenVal == null) {
+ try {
+ givenVal = (String) sc.get(mVar.toLowerCase());
+ }catch (Exception e) {
+ givenVal = (String) null;
+ }
+ }
+
+ if (givenVal == null) {
+ try {
+ givenVal = (String) sc.get(mVar.toUpperCase());
+ }catch (Exception e) {
+ givenVal = (String) null;
+ }
+ }
+
+ // Debug.trace("mVar: " + mVar + ",Given Value: " + givenVal + ", Value to compare with: " + mVal);
+ boolean result = false;
+
+ result = matchValue(givenVal);
+
+ return result;
+
+ }
+
+ public boolean evaluate(IRequest req)
+ throws ELdapException {
+ boolean result = false;
+ // mPfx and mVar are looked up case-indendently
+ if (mPfx != null) {
+ result = matchValue(req.getExtDataInString(mPfx, mVar));
+ } else {
+ result = matchValue(req.getExtDataInString(mVar));
+ }
+ return result;
+ }
+
+ private boolean matchVector(Vector value)
+ throws ELdapException {
+ boolean result = false;
+ Enumeration e = (Enumeration) value.elements();
+
+ for (; e.hasMoreElements();) {
+ result = matchValue(e.nextElement());
+ if (result)
+ break;
+ }
+ return result;
+ }
+
+ private boolean matchStringArray(String[] value)
+ throws ELdapException {
+ boolean result = false;
+
+ for (int i = 0; i < value.length; i++) {
+ result = matchValue((Object) value[i]);
+ if (result)
+ break;
+ }
+ return result;
+ }
+
+ private boolean matchValue(Object value)
+ throws ELdapException {
+ boolean result;
+
+ // There is nothing to compare with!
+ if (value == null)
+ return false;
+
+ if (value instanceof String)
+ result = matchStringValue((String) value);
+ else if (value instanceof Integer)
+ result = matchIntegerValue((Integer) value);
+ else if (value instanceof Boolean)
+ result = matchBooleanValue((Boolean) value);
+ else if (value instanceof Vector)
+ result = matchVector((Vector) value);
+ else if (value instanceof String[])
+ result = matchStringArray((String[]) value);
+ else
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_INVALID_ATTR_VALUE",
+ value.getClass().getName()));
+ return result;
+ }
+
+ private boolean matchStringValue(String givenVal)
+ throws ELdapException {
+ boolean result;
+
+ switch (mOp) {
+ case OP_EQUAL:
+ if (hasWildCard)
+ result = (givenVal.indexOf(mPartialMatch) >= 0);
+ else
+ result = givenVal.equalsIgnoreCase(mVal);
+ break;
+
+ case OP_NEQUAL:
+ if (hasWildCard)
+ result = (givenVal.indexOf(mPartialMatch) < 0);
+ else
+ result = !givenVal.equalsIgnoreCase(mVal);
+ break;
+
+ case OP_LT:
+ result = (givenVal.compareTo(mVal) < 0);
+ break;
+
+ case OP_GT:
+ result = (givenVal.compareTo(mVal) > 0);
+ break;
+
+ case OP_GE:
+ result = (givenVal.compareTo(mVal) >= 0);
+ break;
+
+ case OP_LE:
+ result = (givenVal.compareTo(mVal) >= 0);
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ private boolean matchIntegerValue(Integer intVal)
+ throws ELdapException {
+ boolean result;
+ int storedVal;
+ int givenVal = intVal.intValue();
+
+ try {
+ storedVal = new Integer(mVal).intValue();
+ } catch (Exception e) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_INVALID_ATTR_VALUE", mVal));
+
+ }
+ switch (mOp) {
+ case OP_EQUAL:
+ result = (givenVal == storedVal);
+ break;
+
+ case OP_NEQUAL:
+ result = (givenVal != storedVal);
+ break;
+
+ case OP_LT:
+ result = (givenVal < storedVal);
+ break;
+
+ case OP_GT:
+ result = (givenVal > storedVal);
+ break;
+
+ case OP_GE:
+ result = (givenVal >= storedVal);
+ break;
+
+ case OP_LE:
+ result = (givenVal >= storedVal);
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ private boolean matchBooleanValue(Boolean givenVal)
+ throws ELdapException {
+ boolean result;
+ Boolean storedVal;
+
+ if (!(mVal.equalsIgnoreCase("true") ||
+ mVal.equalsIgnoreCase("false")))
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_INVALID_ATTR_VALUE",
+ mVal));
+ storedVal = new Boolean(mVal);
+ switch (mOp) {
+ case OP_EQUAL:
+ result = (givenVal.equals(storedVal));
+ break;
+
+ case OP_NEQUAL:
+ case OP_LT:
+ case OP_GT:
+ case OP_GE:
+ case OP_LE:
+ result = (!givenVal.equals(storedVal));
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ public String toString() {
+ String op = null;
+
+ switch (mOp) {
+ case ILdapExpression.OP_EQUAL:
+ op = ILdapExpression.EQUAL_STR;
+ break;
+
+ case ILdapExpression.OP_NEQUAL:
+ op = ILdapExpression.NEQUAL_STR;
+ break;
+
+ case ILdapExpression.OP_GT:
+ op = ILdapExpression.GT_STR;
+ break;
+
+ case ILdapExpression.OP_LT:
+ op = ILdapExpression.LT_STR;
+ break;
+
+ case ILdapExpression.OP_GE:
+ op = ILdapExpression.GE_STR;
+ break;
+
+ case ILdapExpression.OP_LE:
+ op = ILdapExpression.LE_STR;
+ break;
+ }
+ if (mPfx != null && mPfx.length() > 0)
+ return mPfx + "." + mVar + " " + op + " " + mVal;
+ else
+ return mVar + " " + op + " " + mVal;
+ }
+
+ private static ExpressionComps parseForEquality(String expression) {
+ int index = expression.indexOf(ILdapExpression.EQUAL_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_EQUAL;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForInEquality(String expression) {
+ int index = expression.indexOf(ILdapExpression.NEQUAL_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_NEQUAL;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForGT(String expression) {
+ int index = expression.indexOf(ILdapExpression.GT_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_GT;
+ String val = expression.substring(index + 1).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForLT(String expression) {
+ int index = expression.indexOf(ILdapExpression.LT_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_LT;
+ String val = expression.substring(index + 1).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForGE(String expression) {
+ int index = expression.indexOf(ILdapExpression.GE_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_GE;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForLE(String expression) {
+ int index = expression.indexOf(ILdapExpression.LE_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_LE;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+}
+
+
+class ExpressionComps {
+ String attr;
+ int op;
+ String val;
+
+ public ExpressionComps(String a, int o, String v) {
+ attr = a;
+ op = o;
+ val = v;
+ }
+
+ public String getAttr() {
+ return attr;
+ }
+
+ public int getOp() {
+ return op;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/PublishObject.java b/pki/base/common/src/com/netscape/cmscore/ldap/PublishObject.java
new file mode 100644
index 000000000..6818a48bf
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/PublishObject.java
@@ -0,0 +1,92 @@
+// --- 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.cmscore.ldap;
+
+
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * The object to publish or unpublish: a certificate or a CRL
+ */
+public class PublishObject {
+ public static final String CERT = "cert";
+ public static final String CERTS = "certs";
+ public static final String CRL = "crl";
+ private String mObjectType = null;
+ private X509CertImpl mCert = null;
+ private X509CertImpl[] mCerts = null;
+ private X509CRLImpl mCRL = null;
+ private int mIndex = 0;
+
+ public PublishObject() {
+ }
+
+ public String getType() {
+ return mObjectType;
+ }
+
+ public void setCert(X509CertImpl cert) {
+ mObjectType = CERT;
+ mCert = cert;
+ mCerts = null;
+ mCRL = null;
+ }
+
+ public X509CertImpl getCert() {
+ return mCert;
+ }
+
+ public void setCerts(X509CertImpl[] certs) {
+ mObjectType = CERTS;
+ mCerts = certs;
+ mCert = null;
+ mCRL = null;
+ }
+
+ public X509CertImpl[] getCerts() {
+ return mCerts;
+ }
+
+ public void setIndex(int index) {
+ mIndex = index;
+ }
+
+ public int getIndex() {
+ return mIndex;
+ }
+
+ public void setCRL(X509CRLImpl crl) {
+ mObjectType = CRL;
+ mCert = null;
+ mCerts = null;
+ mCRL = crl;
+ }
+
+ public X509CRLImpl getCRL() {
+ return mCRL;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java b/pki/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java
new file mode 100644
index 000000000..7d7b8e9b5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java
@@ -0,0 +1,1504 @@
+// --- 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.cmscore.ldap;
+
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.Debug;
+
+
+public class PublisherProcessor implements
+ IPublisherProcessor, IXcertPublisherProcessor {
+
+ public Hashtable mPublisherPlugins = new Hashtable();
+ public Hashtable mPublisherInsts = new Hashtable();
+ public Hashtable mMapperPlugins = new Hashtable();
+ public Hashtable mMapperInsts = new Hashtable();
+ public Hashtable mRulePlugins = new Hashtable();
+ public Hashtable mRuleInsts = new Hashtable();
+
+ /**
+ protected PublishRuleSet mRuleSet = null;
+ **/
+ protected LdapConnModule mLdapConnModule = null;
+
+ private IConfigStore mConfig = null;
+ private IConfigStore mLdapConfig = null;
+ private String mId = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ protected ICertAuthority mAuthority = null;
+ protected LdapRequestListener mLdapRequestListener = null;
+ private boolean mCreateOwnDNEntry = false;
+ private boolean mInited = false;
+
+ public PublisherProcessor(String id) {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void init(ISubsystem authority, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ mAuthority = (ICertAuthority) authority;
+
+ // load publisher implementation
+ IConfigStore publisherConfig = config.getSubStore("publisher");
+ IConfigStore c = publisherConfig.getSubStore(PROP_IMPL);
+ mCreateOwnDNEntry = mConfig.getBoolean("createOwnDNEntry", false);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+ PublisherPlugin plugin = new PublisherPlugin(id, pluginPath);
+
+ mPublisherPlugins.put(id, plugin);
+ }
+ if (Debug.ON)
+ Debug.trace("loaded publisher plugins");
+
+ // load publisher instances
+ c = publisherConfig.getSubStore(PROP_INSTANCE);
+ Enumeration instances = c.getSubStoreNames();
+
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." +
+ PROP_PLUGIN);
+ PublisherPlugin plugin =
+ (PublisherPlugin) mPublisherPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_PLUGIN_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+ String className = plugin.getClassPath();
+
+ // Instantiate and init the publisher.
+ boolean isEnable = false;
+ ILdapPublisher publisherInst = null;
+
+ try {
+ publisherInst = (ILdapPublisher)
+ Class.forName(className).newInstance();
+ IConfigStore pConfig =
+ c.getSubStore(insName);
+
+ publisherInst.init(pConfig);
+ isEnable = true;
+
+ } catch (ClassNotFoundException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (InstantiationException e) {
+ String errMsg = "PublisherProcessor: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (Throwable e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_SKIP_PUBLISHER", insName, e.toString()));
+ // Let the server continue if it is a
+ // mis-configuration. But the instance
+ // will be skipped. This give another
+ // chance to the user to re-configure
+ // the server via console.
+ }
+
+ if (publisherInst == null) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+
+ if (insName == null) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", insName));
+ }
+
+ // add publisher instance to list.
+ mPublisherInsts.put(insName, new
+ PublisherProxy(isEnable, publisherInst));
+ log(ILogger.LL_INFO, "publisher instance " + insName + " added");
+ if (Debug.ON)
+ Debug.trace("loaded publisher instance " + insName + " impl " + implName);
+ }
+
+ // load mapper implementation
+ IConfigStore mapperConfig = config.getSubStore("mapper");
+
+ c = mapperConfig.getSubStore(PROP_IMPL);
+ mImpls = c.getSubStoreNames();
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+ MapperPlugin plugin = new MapperPlugin(id, pluginPath);
+
+ mMapperPlugins.put(id, plugin);
+ }
+ if (Debug.ON)
+ Debug.trace("loaded mapper plugins");
+
+ // load mapper instances
+ c = mapperConfig.getSubStore(PROP_INSTANCE);
+ instances = c.getSubStoreNames();
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." +
+ PROP_PLUGIN);
+ MapperPlugin plugin =
+ (MapperPlugin) mMapperPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_MAPPER_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+ String className = plugin.getClassPath();
+
+ if (Debug.ON)
+ Debug.trace("loaded mapper className=" + className);
+
+ // Instantiate and init the mapper
+ boolean isEnable = false;
+ ILdapMapper mapperInst = null;
+
+ try {
+ mapperInst = (ILdapMapper)
+ Class.forName(className).newInstance();
+ IConfigStore mConfig =
+ c.getSubStore(insName);
+
+ mapperInst.init(mConfig);
+ isEnable = true;
+ } catch (ClassNotFoundException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (InstantiationException e) {
+ String errMsg = "PublisherProcessor: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (Throwable e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_SKIP_MAPPER", insName, e.toString()));
+ // Let the server continue if it is a
+ // mis-configuration. But the instance
+ // will be skipped. This give another
+ // chance to the user to re-configure
+ // the server via console.
+ }
+
+ if (mapperInst == null) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+
+ // add manager instance to list.
+ mMapperInsts.put(insName, new MapperProxy(
+ isEnable, mapperInst));
+
+ log(ILogger.LL_INFO, "mapper instance " + insName + " added");
+ if (Debug.ON)
+ Debug.trace("loaded mapper instance " + insName + " impl " + implName);
+ }
+
+ // load rule implementation
+ IConfigStore ruleConfig = config.getSubStore("rule");
+
+ c = ruleConfig.getSubStore(PROP_IMPL);
+ mImpls = c.getSubStoreNames();
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+ RulePlugin plugin = new RulePlugin(id, pluginPath);
+
+ mRulePlugins.put(id, plugin);
+ }
+ if (Debug.ON)
+ Debug.trace("loaded rule plugins");
+
+ // load rule instances
+ c = ruleConfig.getSubStore(PROP_INSTANCE);
+ instances = c.getSubStoreNames();
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." +
+ PROP_PLUGIN);
+ RulePlugin plugin =
+ (RulePlugin) mRulePlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_RULE_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+ String className = plugin.getClassPath();
+
+ if (Debug.ON)
+ Debug.trace("loaded rule className=" + className);
+
+ // Instantiate and init the rule
+ IConfigStore mConfig = null;
+
+ try {
+ ILdapRule ruleInst = null;
+
+ ruleInst = (ILdapRule)
+ Class.forName(className).newInstance();
+ mConfig = c.getSubStore(insName);
+ ruleInst.init(this, mConfig);
+ ruleInst.setInstanceName(insName);
+
+ // add manager instance to list.
+ if (Debug.ON)
+ Debug.trace("ADDING RULE " + insName + " " + ruleInst);
+ mRuleInsts.put(insName, ruleInst);
+ log(ILogger.LL_INFO, "rule instance " +
+ insName + " added");
+ } catch (ClassNotFoundException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ String errMsg = "PublisherProcessor:: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (InstantiationException e) {
+ String errMsg = "PublisherProcessor: init()-" + e.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_PUBLISHER_INIT_FAILED", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (Throwable e) {
+ if (mConfig == null) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+ mConfig.putString(ILdapRule.PROP_ENABLE,
+ "false");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_SKIP_RULE", insName, e.toString()));
+ // Let the server continue if it is a
+ // mis-configuration. But the instance
+ // will be skipped. This give another
+ // chance to the user to re-configure
+ // the server via console.
+ }
+ if (Debug.ON)
+ Debug.trace("loaded rule instance " + insName + " impl " + implName);
+ }
+
+ startup();
+ mInited = true;
+ log(ILogger.LL_INFO, "publishing initialization done");
+ }
+
+ /**
+ * Retrieves LDAP connection module.
+ * <P>
+ *
+ * @return LDAP connection instance
+ */
+ public ILdapConnModule getLdapConnModule() {
+ return mLdapConnModule;
+ }
+
+ public void setLdapConnModule(ILdapConnModule m) {
+ mLdapConnModule = (LdapConnModule)m;
+ }
+
+ /**
+ * init ldap connection
+ */
+ private void initLdapConn(IConfigStore ldapConfig)
+ throws EBaseException {
+ IConfigStore c = ldapConfig;
+
+ try {
+ //c = authConfig.getSubStore(PROP_LDAP_PUBLISH_SUBSTORE);
+ if (c != null && c.size() > 0) {
+ mLdapConnModule = new LdapConnModule();
+ mLdapConnModule.init(this, c);
+ CMS.debug("LdapPublishing connection inited");
+ } else {
+ log(ILogger.LL_FAILURE,
+ "No Ldap Module configuration found");
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_NO_LDAP_PUBLISH_CONFIG_FOUND"));
+ }
+
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE,
+ "Ldap Publishing Module failed with " + e);
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_INIT_LDAP_PUBLISH_MODULE_FAILED", e.toString()));
+ }
+ }
+
+ public void startup() throws EBaseException {
+ CMS.debug("PublisherProcessor: startup()");
+ mLdapConfig = mConfig.getSubStore(PROP_LDAP_PUBLISH_SUBSTORE);
+ if (mLdapConfig.getBoolean(PROP_ENABLE, false)) {
+ CMS.debug("PublisherProcessor: about to initLdapConn");
+ initLdapConn(mLdapConfig);
+ } else {
+ CMS.debug("No LdapPublishing enabled");
+ }
+
+ if (mConfig.getBoolean(PROP_ENABLE, false)) {
+ mLdapRequestListener = new LdapRequestListener();
+ mLdapRequestListener.init(this, mLdapConfig);
+ mAuthority.registerRequestListener(mLdapRequestListener);
+ IConfigStore queueConfig = mConfig.getSubStore(PROP_QUEUE_PUBLISH_SUBSTORE);
+ if (queueConfig != null) {
+ boolean isPublishingQueueEnabled = queueConfig.getBoolean("enable", false);
+ int publishingQueuePriorityLevel = queueConfig.getInteger("priorityLevel", 0);
+ int maxNumberOfPublishingThreads = queueConfig.getInteger("maxNumberOfThreads", 1);
+ int publishingQueuePageSize = queueConfig.getInteger("pageSize", 100);
+ int savePublishingStatus = queueConfig.getInteger("saveStatus", 0);
+ CMS.debug("PublisherProcessor: startup: Publishing Queue Enabled: " + isPublishingQueueEnabled +
+ " Priority Level: " + publishingQueuePriorityLevel +
+ " Maximum Number of Threads: " + maxNumberOfPublishingThreads +
+ " Page Size: "+ publishingQueuePageSize);
+ IRequestNotifier reqNotifier = ((ICertificateAuthority)mAuthority).getRequestNotifier();
+ reqNotifier.setPublishingQueue (isPublishingQueueEnabled,
+ publishingQueuePriorityLevel,
+ maxNumberOfPublishingThreads,
+ publishingQueuePageSize,
+ savePublishingStatus);
+ }
+ }
+ }
+
+ public void shutdown() {
+ CMS.debug("Shuting down publishing.");
+ try {
+ if (mLdapConnModule != null) {
+ mLdapConnModule.getLdapConnFactory().reset();
+ }
+ if (mLdapRequestListener != null) {
+ //mLdapRequestListener.shutdown();
+ mAuthority.removeRequestListener(mLdapRequestListener);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ public Hashtable getRulePlugins() {
+ return mRulePlugins;
+ }
+
+ public Hashtable getRuleInsts() {
+ return mRuleInsts;
+ }
+
+ public Hashtable getMapperPlugins() {
+ return mMapperPlugins;
+ }
+
+ public Hashtable getPublisherPlugins() {
+ return mPublisherPlugins;
+ }
+
+ public Hashtable getMapperInsts() {
+ return mMapperInsts;
+ }
+
+ public Hashtable getPublisherInsts() {
+ return mPublisherInsts;
+ }
+
+ //certType can be client,server,ca,crl,smime
+ //XXXshould make it static to make it faster
+ public Enumeration getRules(String publishingType) {
+ Vector rules = new Vector();
+ Enumeration e = mRuleInsts.keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name == null) {
+ if (Debug.ON)
+ Debug.trace("rule name is " + "null");
+ return null;
+ } else {
+ if (Debug.ON)
+ Debug.trace("rule name is " + name);
+ }
+
+ //this is the only rule we support now
+ LdapRule rule = (LdapRule) (mRuleInsts.get(name));
+
+ if (rule.enabled() && rule.getType().equals(publishingType)) {
+ // check if the predicate match
+ ILdapExpression exp = rule.getPredicate();
+
+ try {
+ SessionContext sc = SessionContext.getContext();
+
+ if (exp != null && !exp.evaluate(sc))
+ continue;
+ } catch (Exception ex) {
+ // do nothing
+ }
+ rules.addElement(rule);
+ if (Debug.ON)
+ Debug.trace("added rule " + name + " for " + publishingType);
+ }
+ }
+ return rules.elements();
+ }
+
+ public Enumeration getRules(String publishingType, IRequest req) {
+ if (req == null) {
+ return getRules(publishingType);
+ }
+
+ Vector rules = new Vector();
+ Enumeration e = mRuleInsts.keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name == null) {
+ if (Debug.ON)
+ Debug.trace("rule name is " + "null");
+ return null;
+ } else {
+ if (Debug.ON)
+ Debug.trace("rule name is " + name);
+ }
+
+ //this is the only rule we support now
+ LdapRule rule = (LdapRule) (mRuleInsts.get(name));
+
+ if (rule.enabled() && rule.getType().equals(publishingType)) {
+ // check if the predicate match
+ ILdapExpression exp = rule.getPredicate();
+
+ try {
+ if (exp != null && !exp.evaluate(req))
+ continue;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ rules.addElement(rule);
+ if (Debug.ON)
+ Debug.trace("added rule " + name + " for " + publishingType +
+ " request: " + req.getRequestId());
+ }
+ }
+ return rules.elements();
+ }
+
+ /**
+ public PublishRuleSet getPublishRuleSet()
+ {
+ return mRuleSet;
+ }
+ **/
+
+ public Vector getMapperDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ MapperPlugin plugin = (MapperPlugin)
+ mMapperPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_MAPPER_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+
+ // XXX can find an instance of this plugin in existing
+ // mapper instances to avoid instantiation just for this.
+
+ // a temporary instance
+ ILdapMapper mapperInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ mapperInst = (ILdapMapper)
+ Class.forName(className).newInstance();
+ Vector v = mapperInst.getDefaultParams();
+
+ return v;
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_MAPPER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_MAPPER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_MAPPER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+ }
+
+ public Vector getMapperInstanceParams(String insName) throws
+ ELdapException {
+ ILdapMapper mapperInst = null;
+ MapperProxy proxy = (MapperProxy) mMapperInsts.get(insName);
+
+ if (proxy == null) {
+ return null;
+ }
+ mapperInst = proxy.getMapper();
+ if (mapperInst == null) {
+ return null;
+ }
+ Vector v = mapperInst.getInstanceParams();
+
+ return v;
+ }
+
+ public Vector getPublisherDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ PublisherPlugin plugin = (PublisherPlugin)
+ mPublisherPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_PLUGIN_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+
+ // XXX can find an instance of this plugin in existing
+ // publisher instantces to avoid instantiation just for this.
+
+ // a temporary instance
+ ILdapPublisher publisherInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ publisherInst = (ILdapPublisher)
+ Class.forName(className).newInstance();
+ Vector v = publisherInst.getDefaultParams();
+
+ return v;
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_PUBLISHER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_PUBLISHER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_PUBLISHER", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+ }
+
+ public boolean isMapperInstanceEnable(String insName) {
+ MapperProxy proxy = (MapperProxy)
+ mMapperInsts.get(insName);
+
+ if (proxy == null) {
+ return false;
+ }
+ return proxy.isEnable();
+ }
+
+ public ILdapMapper getActiveMapperInstance(String insName) {
+ MapperProxy proxy = (MapperProxy) mMapperInsts.get(insName);
+
+ if (proxy == null)
+ return null;
+ if (proxy.isEnable())
+ return proxy.getMapper();
+ else
+ return null;
+ }
+
+ public ILdapMapper getMapperInstance(String insName) {
+ MapperProxy proxy = (MapperProxy) mMapperInsts.get(insName);
+
+ if (proxy == null)
+ return null;
+ return proxy.getMapper();
+ }
+
+ public boolean isPublisherInstanceEnable(String insName) {
+ PublisherProxy proxy = (PublisherProxy)
+ mPublisherInsts.get(insName);
+
+ if (proxy == null) {
+ return false;
+ }
+ return proxy.isEnable();
+ }
+
+ public ILdapPublisher getActivePublisherInstance(String insName) {
+ PublisherProxy proxy = (PublisherProxy)
+ mPublisherInsts.get(insName);
+
+ if (proxy == null) {
+ return null;
+ }
+ if (proxy.isEnable())
+ return proxy.getPublisher();
+ else
+ return null;
+ }
+
+ public ILdapPublisher getPublisherInstance(String insName) {
+ PublisherProxy proxy = (PublisherProxy)
+ mPublisherInsts.get(insName);
+
+ if (proxy == null) {
+ return null;
+ }
+ return proxy.getPublisher();
+ }
+
+ public Vector getPublisherInstanceParams(String insName) throws
+ ELdapException {
+ ILdapPublisher publisherInst = getPublisherInstance(insName);
+
+ if (publisherInst == null) {
+ return null;
+ }
+ Vector v = publisherInst.getInstanceParams();
+
+ return v;
+ }
+
+ public Vector getRuleDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ RulePlugin plugin = (RulePlugin)
+ mRulePlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_RULE_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+
+ // XXX can find an instance of this plugin in existing
+ // rule instantces to avoid instantiation just for this.
+
+ // a temporary instance
+ ILdapRule ruleInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ ruleInst = (ILdapRule)
+ Class.forName(className).newInstance();
+
+ Vector v = ruleInst.getDefaultParams();
+
+ return v;
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+ }
+
+ public Vector getRuleInstanceParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ RulePlugin plugin = (RulePlugin)
+ mRulePlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAP_RULE_NOT_FIND", implName));
+ throw new ELdapException(implName);
+ }
+
+ // XXX can find an instance of this plugin in existing
+ // rule instantces to avoid instantiation just for this.
+
+ // a temporary instance
+ ILdapRule ruleInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ ruleInst = (ILdapRule)
+ Class.forName(className).newInstance();
+ Vector v = ruleInst.getInstanceParams();
+ IConfigStore rc = ruleInst.getConfigStore();
+
+ return v;
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_NEW_RULE", e.toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_FAIL_LOAD_CLASS", className));
+ }
+ }
+
+ /**
+ * set published flag - true when published, false when unpublished.
+ * not exist means not published.
+ */
+ public void setPublishedFlag(BigInteger serialNo, boolean published) {
+ if (!(mAuthority instanceof ICertificateAuthority))
+ return;
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ try {
+ ICertificateRepository certdb = (ICertificateRepository) ca.getCertificateRepository();
+ ICertRecord certRec = (ICertRecord) certdb.readCertificateRecord(serialNo);
+ MetaInfo metaInfo = certRec.getMetaInfo();
+
+ if (metaInfo == null) {
+ metaInfo = new MetaInfo();
+ }
+ metaInfo.set(
+ CertRecord.META_LDAPPUBLISH, String.valueOf(published));
+ ModificationSet modSet = new ModificationSet();
+
+ modSet.add(ICertRecord.ATTR_META_INFO,
+ Modification.MOD_REPLACE, metaInfo);
+ certdb.modifyCertificateRecord(serialNo, modSet);
+ } catch (EBaseException e) {
+ // not fatal. just log warning.
+ log(ILogger.LL_WARN,
+ "Cannot mark cert 0x" + serialNo.toString(16) + " published as " + published +
+ " in the ldap directory. Cert Record not found. Error: " +
+ e.toString() +
+ " Don't be alarmed if it's a subordinate ca or clone's ca siging cert. Otherwise your internal db may be corrupted.");
+ }
+ }
+
+ /**
+ * Publish ca cert, UpdateDir.java, jobs, request listeners
+ */
+ public void publishCACert(X509Certificate cert)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+
+ CMS.debug("PublishProcessor::publishCACert");
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules(PROP_LOCAL_CA);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ if (isClone()) {
+ log(ILogger.LL_WARN, "No rule is found for publishing: " + PROP_LOCAL_CA + " in this clone.");
+ return;
+ } else {
+ Debug.trace(CMS.getLogMessage("CMSCORE_LDAP_NO_RULE_FOUND", PROP_LOCAL_CA));
+ //log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_RULE_FOUND", PROP_LOCAL_CA));
+ //throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED", PROP_LOCAL_CA));
+ return;
+ }
+ }
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ if( rule == null ) {
+ CMS.debug( "PublisherProcessor::publishCACert() - "
+ + "rule is null!" );
+ throw new ELdapException( "rule is null" );
+ }
+
+ log(ILogger.LL_INFO, "publish certificate type=" + PROP_LOCAL_CA +
+ " rule=" + rule.getInstanceName() + " publisher=" +
+ rule.getPublisher());
+
+ try {
+ ILdapMapper mapper = null;
+
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null &&
+ !mapperName.trim().equals("")) {
+ mapper = getActiveMapperInstance(mapperName);
+ }
+
+ publishNow(mapper, getActivePublisherInstance(rule.getPublisher()), null/* NO REQUEsT */, cert);
+ log(ILogger.LL_INFO, "published certificate using rule=" +
+ rule.getInstanceName());
+ } catch (Exception e) {
+ // continue publishing even publisher has errors
+ //log(ILogger.LL_WARN, e.toString());
+ CMS.debug("PublisherProcessor::publishCACert returned error: " + e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName() +
+ " error:" + e.toString();
+ }
+ }
+ // set the ldap published flag.
+ if (!error) {
+ setPublishedFlag(cert.getSerialNumber(), true);
+ } else {
+ throw new
+ ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_FAILED", errorRule));
+ }
+ }
+
+ /**
+ * This function is never called. CMS does not unpublish
+ * CA certificate.
+ */
+ public void unpublishCACert(X509Certificate cert)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules(PROP_LOCAL_CA);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ if (isClone()) {
+ log(ILogger.LL_WARN, "No rule is found for unpublishing: " + PROP_LOCAL_CA + " in this clone.");
+ return;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_UNPUBLISHING_RULE_FOUND", PROP_LOCAL_CA));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED", PROP_LOCAL_CA));
+ }
+ }
+
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ if( rule == null ) {
+ CMS.debug( "PublisherProcessor::unpublishCACert() - "
+ + "rule is null!" );
+ throw new ELdapException( "rule is null" );
+ }
+
+ try {
+ log(ILogger.LL_INFO, "unpublish certificate type=" +
+ PROP_LOCAL_CA + " rule=" + rule.getInstanceName() +
+ " publisher=" + rule.getPublisher());
+
+ ILdapMapper mapper = null;
+
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null &&
+ !mapperName.trim().equals("")) {
+ mapper = getActiveMapperInstance(mapperName);
+ }
+
+ unpublishNow(mapper, getActivePublisherInstance(rule.getPublisher()), null/* NO REQUEST */, cert);
+ log(ILogger.LL_INFO, "unpublished certificate using rule=" +
+ rule.getInstanceName());
+ } catch (Exception e) {
+ // continue publishing even publisher has errors
+ //log(ILogger.LL_WARN, e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+ }
+ }
+
+ // set the ldap published flag.
+ if (!error) {
+ setPublishedFlag(cert.getSerialNumber(), false);
+ } else {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_FAILED", errorRule));
+ }
+ }
+
+ /**
+ * Publish crossCertificatePair
+ */
+ public void publishXCertPair(byte[] pair)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+ CMS.debug("PublisherProcessor: in publishXCertPair()");
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules(PROP_XCERT);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ if (isClone()) {
+ log(ILogger.LL_WARN, "No rule is found for publishing: " + PROP_LOCAL_CA + " in this clone.");
+ return;
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_RULE_FOUND", PROP_XCERT));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED", PROP_XCERT));
+ }
+ }
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ if( rule == null ) {
+ CMS.debug( "PublisherProcessor::publishXCertPair() - "
+ + "rule is null!" );
+ throw new ELdapException( "rule is null" );
+ }
+
+ log(ILogger.LL_INFO, "publish certificate type=" + PROP_XCERT +
+ " rule=" + rule.getInstanceName() + " publisher=" +
+ rule.getPublisher());
+ try {
+ ILdapMapper mapper = null;
+
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null &&
+ !mapperName.trim().equals("")) {
+ mapper = getActiveMapperInstance(mapperName);
+ }
+
+ publishNow(mapper, getActivePublisherInstance(rule.getPublisher()), null/* NO REQUEsT */, pair);
+ log(ILogger.LL_INFO, "published Xcertificates using rule=" +
+ rule.getInstanceName());
+ } catch (Exception e) {
+ // continue publishing even publisher has errors
+ //log(ILogger.LL_WARN, e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName() +
+ " error:" + e.toString();
+
+ CMS.debug("PublisherProcessor::publishXCertPair: error: " + e.toString());
+ }
+ }
+ }
+
+ /**
+ * Publishs regular user certificate based on the criteria
+ * set in the request.
+ */
+ public void publishCert(X509Certificate cert, IRequest req)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ CMS.debug("In PublisherProcessor::publishCert");
+ if (!enabled())
+ return;
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules("certs", req);
+
+ // Bugscape #52306 - Remove superfluous log messages on failure
+ if (rules == null || !rules.hasMoreElements()) {
+ CMS.debug("Publishing: can't find publishing rule,bailing.");
+ return;
+ }
+
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ try {
+ log(ILogger.LL_INFO,
+ "publish certificate (with request) type=" +
+ "certs" + " rule=" + rule.getInstanceName() +
+ " publisher=" + rule.getPublisher());
+ ILdapPublisher p = getActivePublisherInstance(rule.getPublisher());
+ ILdapMapper m = null;
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null) {
+ m = getActiveMapperInstance(mapperName);
+ }
+ publishNow(m, p, req, cert);
+ log(ILogger.LL_INFO, "published certificate using rule=" +
+ rule.getInstanceName());
+ } catch (Exception e) {
+ // continue publishing even publisher has errors
+ //log(ILogger.LL_WARN, e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+ }
+ }
+ // set the ldap published flag.
+ if (!error) {
+ setPublishedFlag(cert.getSerialNumber(), true);
+ } else {
+ CMS.debug("PublishProcessor::publishCert : " + CMS.getUserMessage("CMS_LDAP_PUBLISH_FAILED",errorRule));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_FAILED", errorRule));
+ }
+ }
+
+ /**
+ * Unpublish user certificate. This is used by
+ * UnpublishExpiredJob.
+ */
+ public void unpublishCert(X509Certificate cert, IRequest req)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules("certs", req);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_UNPUBLISHING_RULE_FOUND_FOR_REQUEST", "certs", req.getRequestId().toString()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED",
+ req.getRequestId().toString()));
+ }
+
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ if( rule == null ) {
+ CMS.debug( "PublisherProcessor::unpublishCert() - "
+ + "rule is null!" );
+ throw new ELdapException( "rule is null" );
+ }
+
+ try {
+ log(ILogger.LL_INFO,
+ "unpublish certificate (with request) type=" +
+ "certs" + " rule=" + rule.getInstanceName() +
+ " publisher=" + rule.getPublisher());
+
+ ILdapMapper mapper = null;
+
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null &&
+ !mapperName.trim().equals("")) {
+ mapper = getActiveMapperInstance(mapperName);
+ }
+
+ unpublishNow(mapper, getActivePublisherInstance(rule.getPublisher()),
+ req, cert);
+ log(ILogger.LL_INFO, "unpublished certificate using rule=" +
+ rule.getInstanceName());
+ } catch (Exception e) {
+ // continue publishing even publisher has errors
+ //log(ILogger.LL_WARN, e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+ }
+ }
+
+ // set the ldap published flag.
+ if (!error) {
+ setPublishedFlag(cert.getSerialNumber(), false);
+ } else {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_UNPUBLISH_FAILED", errorRule));
+ }
+ }
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ * Note that this is used by cmsgateway/cert/UpdateDir.java
+ */
+ public void publishCRL(X509CRLImpl crl, String crlIssuingPointId)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+
+ if (!enabled())
+ return;
+ ILdapMapper mapper = null;
+ ILdapPublisher publisher = null;
+
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules(PROP_LOCAL_CRL);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_RULE_FOR_CRL"));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED",
+ PROP_LOCAL_CRL));
+ }
+
+ LDAPConnection conn = null;
+ String dn = null;
+
+ try {
+ if (mLdapConnModule != null) {
+ conn = mLdapConnModule.getConn();
+ }
+ while (rules.hasMoreElements()) {
+ mapper = null;
+ dn = null;
+ String result = null;
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ log(ILogger.LL_INFO, "publish crl rule=" +
+ rule.getInstanceName() + " publisher=" +
+ rule.getPublisher());
+ try {
+ String mapperName = rule.getMapper();
+
+ if (mapperName != null &&
+ !mapperName.trim().equals("")) {
+ mapper = getActiveMapperInstance(mapperName);
+ }
+ if (mapper == null || mapper.getImplName().equals("NoMap")) {
+ dn = ((X500Name) crl.getIssuerDN()).toLdapDNString();
+ }else {
+
+ result = ((ILdapMapper) mapper).map(conn, crl);
+ dn = result;
+ if (!mCreateOwnDNEntry) {
+ if (dn == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_MAPPER_NOT_MAP", rule.getMapper()));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH",
+ crl.getIssuerDN().toString()));
+
+ }
+ }
+ }
+ publisher = getActivePublisherInstance(rule.getPublisher());
+ if (publisher != null) {
+ if(publisher instanceof com.netscape.cms.publish.publishers.FileBasedPublisher)
+ ((com.netscape.cms.publish.publishers.FileBasedPublisher)publisher).setIssuingPointId(crlIssuingPointId);
+ publisher.publish(conn, dn, crl);
+ log(ILogger.LL_INFO, "published crl using rule=" + rule.getInstanceName());
+ }
+ // continue publishing even publisher has errors
+ }catch (Exception e) {
+ //e.printStackTrace();
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e);
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+
+ CMS.debug("PublisherProcessor::publishCRL: error: " + e.toString());
+ }
+ }
+ }catch (ELdapException e) {
+ //e.printStackTrace();
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e);
+ throw e;
+ } finally {
+ if (conn != null) {
+ mLdapConnModule.returnConn(conn);
+ }
+ }
+ if (error)
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_FAILED", errorRule));
+ }
+
+ /**
+ * publishes a crl by mapping the issuer name in the crl to an entry
+ * and publishing it there. entry must be a certificate authority.
+ */
+ public void publishCRL(String dn, X509CRL crl)
+ throws ELdapException {
+ boolean error = false;
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+ // get mapper and publisher for cert type.
+ Enumeration rules = getRules(PROP_LOCAL_CRL);
+
+ if (rules == null || !rules.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAP_NO_RULE_FOR_CRL"));
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_RULE_MATCHED",
+ PROP_LOCAL_CRL));
+ }
+
+ LDAPConnection conn = null;
+ ILdapPublisher publisher = null;
+
+ try {
+ if (mLdapConnModule != null) {
+ conn = mLdapConnModule.getConn();
+ }
+ while (rules.hasMoreElements()) {
+ LdapRule rule = (LdapRule) rules.nextElement();
+
+ log(ILogger.LL_INFO, "publish crl dn=" + dn + " rule=" +
+ rule.getInstanceName() + " publisher=" +
+ rule.getPublisher());
+ try {
+ publisher = getActivePublisherInstance(rule.getPublisher());
+ if (publisher != null) {
+ publisher.publish(conn, dn, crl);
+ log(ILogger.LL_INFO, "published crl using rule=" + rule.getInstanceName());
+ }
+ }catch (Exception e) {
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e.toString());
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+ CMS.debug("PublisherProcessor::publishCRL: error: " + e.toString());
+ }
+ }
+ } catch (ELdapException e) {
+ CMS.debug(
+ "Error publishing CRL to " + dn + ": " + e.toString());
+ throw e;
+ } finally {
+ if (conn != null) {
+ mLdapConnModule.returnConn(conn);
+ }
+ }
+ if (error)
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_FAILED", errorRule));
+ }
+
+ private void publishNow(ILdapMapper mapper, ILdapPublisher publisher,
+ IRequest r, Object obj) throws ELdapException {
+ if (!enabled())
+ return;
+ CMS.debug("PublisherProcessor: in publishNow()");
+ LDAPConnection conn = null;
+
+ try {
+ Object dirdn = null;
+
+ if (mapper != null) {
+ LdapCertMapResult result = null;
+
+ if (mLdapConnModule != null) {
+ try {
+ conn = mLdapConnModule.getConn();
+ } catch(ELdapException e) {
+ throw e;
+ }
+ }
+ try {
+ if ((mapper instanceof com.netscape.cms.publish.mappers.LdapCertSubjMap) &&
+ ((com.netscape.cms.publish.mappers.LdapCertSubjMap)mapper).useAllEntries()) {
+ dirdn = ((com.netscape.cms.publish.mappers.LdapCertSubjMap)mapper).mapAll(conn, r, obj);
+ } else {
+ dirdn = mapper.map(conn, r, obj);
+ }
+ } catch (Throwable e1) {
+ CMS.debug("Error mapping: mapper=" + mapper + " error=" + e1.toString());
+ throw e1;
+ }
+ }
+
+ X509Certificate cert = (X509Certificate) obj;
+
+ try {
+ if (dirdn instanceof Vector) {
+ int n = ((Vector)dirdn).size();
+ for (int i = 0; i < n; i++) {
+ publisher.publish(conn, (String)(((Vector)dirdn).elementAt(i)), cert);
+ }
+ } else if (dirdn instanceof String ||
+ publisher instanceof com.netscape.cms.publish.publishers.FileBasedPublisher) {
+ publisher.publish(conn, (String)dirdn, cert);
+ }
+ } catch (Throwable e1) {
+ CMS.debug("PublisherProcessor::publishNow : publisher=" + publisher + " error=" + e1.toString());
+ throw e1;
+ }
+ log(ILogger.LL_INFO, "published certificate serial number: 0x" +
+ cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ throw e;
+ } catch (Throwable e) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH", e.toString()));
+ } finally {
+ if (conn != null) {
+ mLdapConnModule.returnConn(conn);
+ }
+ }
+ }
+
+ // for crosscerts
+ private void publishNow(ILdapMapper mapper, ILdapPublisher publisher,
+ IRequest r, byte[] bytes) throws ELdapException {
+ if (!enabled())
+ return;
+ CMS.debug("PublisherProcessor: in publishNow() for xcerts");
+
+ // use ca cert publishing map and rule
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+ X509Certificate caCert = (X509Certificate) ca.getCACert();
+
+ LDAPConnection conn = null;
+
+ try {
+ String dirdn = null;
+
+ if (mapper != null) {
+ LdapCertMapResult result = null;
+
+ if (mLdapConnModule != null) {
+ conn = mLdapConnModule.getConn();
+ }
+ try {
+ dirdn = mapper.map(conn, r, (Object) caCert);
+ CMS.debug("PublisherProcessor: dirdn="+dirdn);
+
+ } catch (Throwable e1) {
+ CMS.debug("Error mapping: mapper=" + mapper + " error=" + e1.toString());
+ throw e1;
+ }
+ }
+
+ try {
+ CMS.debug("PublisherProcessor: publisher impl name="+publisher.getImplName());
+
+ publisher.publish(conn, dirdn, bytes);
+ } catch (Throwable e1) {
+ CMS.debug("Error publishing: publisher=" + publisher + " error=" + e1.toString());
+ throw e1;
+ }
+ log(ILogger.LL_INFO, "published crossCertPair");
+ } catch (ELdapException e) {
+ throw e;
+ } catch (Throwable e) {
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_NO_MATCH", e.toString()));
+ } finally {
+ if (conn != null) {
+ mLdapConnModule.returnConn(conn);
+ }
+ }
+ }
+
+ private void unpublishNow(ILdapMapper mapper, ILdapPublisher publisher,
+ IRequest r, Object obj) throws ELdapException {
+ if (!enabled())
+ return;
+ LDAPConnection conn = null;
+
+ try {
+ String dirdn = null;
+
+ if (mapper != null) {
+ LdapCertMapResult result = null;
+
+ if (mLdapConnModule != null) {
+ conn = mLdapConnModule.getConn();
+ }
+ dirdn = mapper.map(conn, r, obj);
+ }
+ X509Certificate cert = (X509Certificate) obj;
+
+ publisher.unpublish(conn, dirdn, cert);
+ log(ILogger.LL_INFO, "unpublished certificate serial number: 0x" +
+ cert.getSerialNumber().toString(16));
+ } catch (ELdapException e) {
+ throw e;
+ } finally {
+ if (conn != null) {
+ mLdapConnModule.returnConn(conn);
+ }
+ }
+ }
+
+ public boolean ldapEnabled() {
+ try {
+ if (mInited)
+ return mLdapConfig.getBoolean(PROP_ENABLE, false);
+ else
+ return false;
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+
+ public boolean enabled() {
+ try {
+ if (mInited)
+ return mConfig.getBoolean(PROP_ENABLE, false);
+ else
+ return false;
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+
+ public ISubsystem getAuthority() {
+ return mAuthority;
+ }
+
+ public boolean isClone() {
+ if ((mAuthority instanceof ICertificateAuthority) &&
+ ((ICertificateAuthority) mAuthority).isClone())
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_LDAP, level, "Publishing: " + msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java
new file mode 100644
index 000000000..fbc99608a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java
@@ -0,0 +1,468 @@
+// --- 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.cmscore.ldapconn;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Factory for getting LDAP Connections to a LDAP server
+ * each connection is a seperate thread that can be bound to a different
+ * authentication dn and password.
+ */
+public class LdapAnonConnFactory implements ILdapConnFactory {
+ protected int mMinConns = 5;
+ protected int mMaxConns = 1000;
+ protected LdapConnInfo mConnInfo = null;
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public static final String PROP_MINCONNS = "minConns";
+ public static final String PROP_MAXCONNS = "maxConns";
+ public static final String PROP_LDAPCONNINFO = "ldapconn";
+
+ public static final String PROP_ERROR_IF_DOWN = "errorIfDown";
+
+ private int mNumConns = 0; // number of available conns in array
+ private int mTotal = 0; // total num conns
+ private AnonConnection mConns[] = null;
+
+ private boolean mInited = false;
+
+ private boolean mErrorIfDown;
+ private boolean mDefErrorIfDown = false;
+
+ /**
+ * Constructor for initializing from the config store.
+ * must be followed by init(IConfigStore)
+ */
+ public LdapAnonConnFactory() {
+ }
+
+ public LdapAnonConnFactory(boolean defErrorIfDown) {
+ mDefErrorIfDown = defErrorIfDown;
+ }
+
+ /**
+ * Constructor for LdapAnonConnFactory
+ * @param minConns minimum number of connections to have available
+ * @param maxConns max number of connections to have available. This is
+ * the maximum number of clones of this connection one wants to allow.
+ * @param serverInfo server connection info - host, port, etc.
+ */
+ public LdapAnonConnFactory(int minConns, int maxConns,
+ LdapConnInfo connInfo) throws ELdapException {
+ init(minConns, maxConns, connInfo);
+ }
+
+ public int totalConn() {
+ return mTotal;
+ }
+
+ public int freeConn() {
+ return mNumConns;
+ }
+
+ public int maxConn() {
+ return mMaxConns;
+ }
+
+ /**
+ * init routine to be called when initialize from config store.
+ */
+ public void init(IConfigStore config) throws EBaseException, ELdapException {
+ String minStr = config.getString(PROP_MINCONNS, "");
+ String maxStr = config.getString(PROP_MAXCONNS, "");
+ int minConns = mMinConns;
+ int maxConns = mMaxConns;
+
+ // if it is "", use the default value
+ if (!minStr.equals("")) {
+ try {
+ minConns = Integer.parseInt(minStr);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_MIN_CONN"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_NUMBER_FORMAT_1", PROP_MINCONNS));
+ }
+ }
+
+ // if it is "", use the default value
+ if (!maxStr.equals("")) {
+ try {
+ maxConns = Integer.parseInt(maxStr);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_MAX_CONN"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_NUMBER_FORMAT_1", PROP_MAXCONNS));
+ }
+ }
+
+ mErrorIfDown = config.getBoolean(PROP_ERROR_IF_DOWN, mDefErrorIfDown);
+
+ init(minConns, maxConns,
+ new LdapConnInfo(config.getSubStore(PROP_LDAPCONNINFO)));
+ }
+
+ /**
+ * initialize routine from parameters.
+ */
+ protected void init(int minConns, int maxConns, LdapConnInfo connInfo)
+ throws ELdapException {
+ if (mInited)
+ return; // XXX should throw exception here ?
+
+ if (minConns <= 0 || maxConns <= 0 || minConns > maxConns)
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INVALID_NUMCONN_PARAMETERS"));
+ if (connInfo == null)
+ throw new IllegalArgumentException("connInfo is Null!");
+
+ mMinConns = minConns;
+ mMaxConns = maxConns;
+ mConnInfo = connInfo;
+
+ mConns = new AnonConnection[mMaxConns];
+
+ log(ILogger.LL_INFO,
+ "Created: min " + minConns + " max " + maxConns +
+ " host " + connInfo.getHost() + " port " + connInfo.getPort() +
+ " secure " + connInfo.getSecure());
+
+ // initalize minimum number of connection handles available.
+ makeMinimum(mErrorIfDown);
+ mInited = true;
+ }
+
+ /**
+ * make the mininum configured connections
+ */
+ protected void makeMinimum(boolean errorIfDown) throws ELdapException {
+ try {
+ if (mNumConns < mMinConns && mTotal < mMaxConns) {
+ int increment = Math.min(mMinConns - mNumConns, mMaxConns - mTotal);
+
+ CMS.debug(
+ "increasing minimum number of connections by " + increment);
+ for (int i = increment - 1; i >= 0; i--) {
+ mConns[i] = new AnonConnection(mConnInfo);
+ }
+ mTotal += increment;
+ mNumConns += increment;
+ CMS.debug(
+ "new total number of connections " + mTotal);
+ CMS.debug(
+ "new total available connections " + mNumConns);
+ }
+ } catch (LDAPException e) {
+ // XXX errorCodeToString() used here so users won't see message.
+ // though why are messages from exceptions being displayed to
+ // users ?
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ "Cannot connect to Ldap server. Error: " +
+ "Ldap Server host " + mConnInfo.getHost() +
+ " int " + mConnInfo.getPort() + " is unavailable.");
+ if (errorIfDown) {
+ throw new ELdapServerDownException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE",
+ mConnInfo.getHost(), "" + mConnInfo.getPort()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ "Cannot connect to ldap server. error: " + e.toString());
+ String errmsg = e.errorCodeToString();
+
+ if (errmsg == null)
+ errmsg = e.toString();
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CONNECT_TO_LDAP_SERVER_FAILED",
+ mConnInfo.getHost(), "" + (Integer.valueOf(mConnInfo.getPort())), errmsg));
+ }
+ }
+ }
+
+ /**
+ * Gets connection from this factory.
+ * All connections gotten from this factory must be returned.
+ * If not the max number of connections may be reached prematurely.
+ * The best thing to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public LDAPConnection getConn()
+ throws ELdapException {
+ return getConn(true);
+ }
+
+ /**
+ * Returns a LDAP connection - a clone of the master connection.
+ * All connections should be returned to the factory using returnConn()
+ * to recycle connection objects.
+ * If not returned the limited max number is affected but if that
+ * number is large not much harm is done.
+ * Returns null if maximum number of connections reached.
+ * <p>
+ * The best thing to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized LDAPConnection getConn(boolean waitForConn)
+ throws ELdapException {
+ boolean waited = false;
+
+ CMS.debug("LdapAnonConnFactory::getConn");
+ if (mNumConns == 0)
+ makeMinimum(true);
+ if (mNumConns == 0) {
+ if (!waitForConn)
+ return null;
+ try {
+ CMS.debug("getConn(): out of ldap connections");
+ log(ILogger.LL_WARN,
+ "Ran out of ldap connections available " +
+ "in ldap connection pool to " +
+ mConnInfo.getHost() + ":" + mConnInfo.getPort() + ". " +
+ "This could be a temporary condition or an indication of " +
+ "something more serious that can cause the server to " +
+ "hang.");
+ waited = true;
+ while (mNumConns == 0) {
+ wait();
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ mNumConns--;
+ AnonConnection conn = mConns[mNumConns];
+
+ mConns[mNumConns] = null;
+ if (waited) {
+ log(ILogger.LL_WARN,
+ "Ldap connections are available again in ldap connection pool " +
+ "to " + mConnInfo.getHost() + ":" + mConnInfo.getPort());
+ }
+ CMS.debug("LdapAnonConnFactory.getConn(): num avail conns now " + mNumConns);
+ //Beginning of fix for Bugzilla #630176
+ boolean isConnected = false;
+ if(conn != null) {
+ isConnected = conn.isConnected();
+ }
+
+ if(!isConnected) {
+ CMS.debug("LdapAnonConnFactory.getConn(): selected conn is down, try to reconnect...");
+ conn = null;
+ try {
+ conn = new AnonConnection(mConnInfo);
+ } catch (LDAPException e) {
+ CMS.debug("LdapAnonConnFactory.getConn(): error when trying to bring back a down connection.");
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CONNECT_TO_LDAP_SERVER_FAILED",
+ mConnInfo.getHost(), "" + (Integer.valueOf(mConnInfo.getPort())), e.toString()));
+ }
+ }
+ //This is the end of the fix for Bugzilla #630176
+
+ return conn;
+ }
+
+ /**
+ * Returns a connection to the factory for recycling.
+ * All connections gotten from this factory must be returned.
+ * If not the max number of connections may be reached prematurely.
+ * <p>
+ * The best thing to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized void returnConn(LDAPConnection conn) {
+ if (conn == null) {
+ return;
+ }
+ // check if conn is valid and from this factory.
+ AnonConnection anon = (AnonConnection) conn;
+
+ if (anon.getFacId() != mConns) {
+ // returning a connection not from this factory.
+ log(ILogger.LL_WARN, "returnConn: unknown connection.");
+
+ /* swallow this error but see who's doing it. */
+ ELdapException e =
+ new ELdapException(CMS.getUserMessage("CMS_LDAP_UNKNOWN_RETURNED_CONN"));
+ }
+ // check if conn has already been returned.
+ for (int i = 0; i < mNumConns; i++) {
+ // returning connection already returned.
+ if (mConns[i] == anon) {
+
+ /* swallow this error but see who's doing it. */
+ log(ILogger.LL_WARN,
+ "returnConn: previously returned connection.");
+ ELdapException e =
+ new ELdapException(CMS.getUserMessage("CMS_LDAP_BAD_RETURNED_CONN"));
+ }
+ }
+
+ // this returned connection might authenticate as someone other than
+ // anonymonus. Reset it to anonymous first before it returns
+ // to the pool.
+ try {
+ anon.authenticate(null, null);
+
+ // return conn.
+ CMS.debug("returnConn: mNumConns now " + mNumConns);
+ } catch (LDAPException e) {
+ log(ILogger.LL_WARN,
+ "Could not re-authenticate ldap connection to anonymous." +
+ " Error " + e);
+ }
+ // return the connection even if can't reauthentication anon.
+ // most likely server was down.
+ mConns[mNumConns++] = anon;
+
+ notify();
+ }
+
+ protected void finalize()
+ throws Exception {
+ reset();
+ }
+
+ /**
+ * returns connection info.
+ */
+ public LdapConnInfo getConnInfo() {
+ return mConnInfo;
+ }
+
+ /**
+ * resets this factory - if no connections outstanding,
+ * disconnections all connections and resets everything to 0 as if
+ * no connections were ever made. intended to be called just before
+ * shutdown or exit to disconnection & cleanup connections.
+ */
+ // ok only if no connections outstanding.
+ public synchronized void reset()
+ throws ELdapException {
+ if (mNumConns == mTotal) {
+ for (int i = 0; i < mNumConns; i++) {
+ try {
+ CMS.debug("disconnecting connection " + i);
+ mConns[i].disconnect();
+ } catch (LDAPException e) {
+ log(ILogger.LL_INFO,
+ "exception during disconnect: " + e.toString());
+ }
+ mConns[i] = null;
+ }
+ mTotal = 0;
+ mNumConns = 0;
+ } else {
+ log(ILogger.LL_INFO,
+ "Cannot reset() while connections not all returned");
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CANNOT_RESET_CONNFAC"));
+ }
+ }
+
+ /**
+ * handy routine for logging in this class.
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "In Ldap (anonymous) connection pool to" +
+ " host " + mConnInfo.getHost() +
+ " port " + mConnInfo.getPort() + ", " + msg);
+ }
+
+ /**
+ * used to keep track of connections from this factory.
+ */
+ public class AnonConnection extends LdapAnonConnection {
+ public AnonConnection(LdapConnInfo connInfo)
+ throws LDAPException {
+ super(connInfo);
+ }
+
+ public AnonConnection(String host, int port, int version,
+ LDAPSocketFactory fac)
+ throws LDAPException {
+ super(host, port, version, fac);
+ }
+
+ /**
+ * instantiates a non-secure connection to a ldap server
+ */
+ public AnonConnection(String host, int port, int version)
+ throws LDAPException {
+ super(host, port, version);
+ }
+
+ /**
+ * used only to identify the factory from which this came.
+ * mConns to identify factory.
+ */
+ public AnonConnection[] getFacId() {
+ return mConns;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java
new file mode 100644
index 000000000..4be6bc33b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java
@@ -0,0 +1,87 @@
+// --- 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.cmscore.ldapconn;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * A LDAP connection that is bound to a server host, port and secure type.
+ * Makes a LDAP connection when instantiated.
+ * Cannot establish another LDAP connection after construction.
+ * LDAPConnection connect methods are overridden to prevent this.
+ */
+public class LdapAnonConnection extends LDAPConnection {
+
+ /**
+ * instantiates a connection to a ldap server
+ */
+ public LdapAnonConnection(LdapConnInfo connInfo)
+ throws LDAPException {
+ super(connInfo.getSecure() ? new LdapJssSSLSocketFactory() : null);
+
+ // Set option to automatically follow referrals.
+ // rebind info is also anonymous.
+ boolean followReferrals = connInfo.getFollowReferrals();
+
+ setOption(LDAPv2.REFERRALS, new Boolean(followReferrals));
+
+ super.connect(connInfo.getVersion(),
+ connInfo.getHost(), connInfo.getPort(), null, null);
+ }
+
+ /**
+ * instantiates a connection to a ldap server
+ */
+ public LdapAnonConnection(String host, int port, int version,
+ LDAPSocketFactory fac)
+ throws LDAPException {
+ super(fac);
+ super.connect(version, host, port, null, null);
+ }
+
+ /**
+ * instantiates a non-secure connection to a ldap server
+ */
+ public LdapAnonConnection(String host, int port, int version)
+ throws LDAPException {
+ super();
+ super.connect(version, host, port, null, null);
+ }
+
+ /**
+ * overrides superclass connect.
+ * does not allow reconnect.
+ */
+ public void connect(String host, int port) throws LDAPException {
+ throw new RuntimeException(
+ "this LdapAnonConnection already connected: connect(h,p)");
+ }
+
+ /**
+ * overrides superclass connect.
+ * does not allow reconnect.
+ */
+ public void connect(int version, String host, int port,
+ String dn, String pw) throws LDAPException {
+ throw new RuntimeException(
+ "this LdapAnonConnection already connected: connect(v,h,p)");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
new file mode 100644
index 000000000..667e68a85
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
@@ -0,0 +1,299 @@
+// --- 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.cmscore.ldapconn;
+
+
+import java.util.Hashtable;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.cmsutil.password.*;
+
+
+/**
+ * class for reading ldap authentication info from config store
+ */
+public class LdapAuthInfo implements ILdapAuthInfo {
+
+ protected int mType = -1;
+ protected String[] mParms = null;
+
+ private boolean mInited = false;
+
+ private static Hashtable passwords = new Hashtable();
+
+ /**
+ * must call init(config) after this constructor.
+ */
+ public LdapAuthInfo() {
+ }
+
+ /**
+ * constructs ldap auth info directly from config store.
+ */
+ public LdapAuthInfo(IConfigStore config) throws EBaseException {
+ init(config);
+ }
+
+ /**
+ * constructs ldap auth info directly from config store, and verifies
+ * the password by attempting to connect to the server.
+ */
+ public LdapAuthInfo(IConfigStore config, String host, int port, boolean secure)
+ throws EBaseException {
+ init(config, host, port, secure);
+ }
+
+ public String getPasswordFromStore (String prompt) {
+ String pwd = null;
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: try to get it from password store");
+
+// hey - should use password store interface to allow different implementations
+// but the problem is, other parts of the system just go directly to the file
+// so calling CMS.getPasswordStore() will give you an outdated one
+/*
+ IConfigStore mainConfig = CMS.getConfigStore();
+ String pwdFile = mainConfig.getString("passwordFile");
+ FileConfigStore pstore = new FileConfigStore(pwdFile);
+*/
+ IPasswordStore pwdStore = CMS.getPasswordStore();
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: about to get from passwored store: "+prompt);
+
+ // support publishing dirsrv with different pwd than internaldb
+
+ // Finally, interactively obtain the password from the user
+ if (pwdStore != null) {
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: password store available");
+ pwd = pwdStore.getPassword(prompt);
+// pwd = pstore.getString(prompt);
+ if ( pwd == null) {
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: password for "+prompt+
+ " not found, trying internaldb");
+
+// pwd = pstore.getString("internaldb");
+
+ pwd = pwdStore.getPassword("internaldb"); // last resort
+ } else
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: password found for prompt in password store");
+ } else
+ CMS.debug("LdapAuthInfo: getPasswordFromStore: password store not available: pwdStore is null");
+
+ return pwd;
+ }
+
+ /**
+ * initialize this class from the config store.
+ */
+ public void init(IConfigStore config) throws EBaseException {
+ init(config, null, 0, true);
+ }
+
+ /**
+ * initialize this class from the config store, and verify the password.
+ *
+ * @param host The host that the directory server is running on.
+ * This will be used to verify the password by attempting to connect.
+ * If it is <code>null</code>, the password will not be verified.
+ * @param port The port that the directory server is running on.
+ */
+ public void init(IConfigStore config, String host, int port, boolean secure)
+ throws EBaseException {
+
+ CMS.debug("LdapAuthInfo: init()");
+ if (mInited) {
+ CMS.debug("LdapAuthInfo: already initialized");
+ return; // XXX throw exception here ?
+ }
+ CMS.debug("LdapAuthInfo: init begins");
+
+ String authTypeStr = config.getString(PROP_LDAPAUTHTYPE);
+
+ if (authTypeStr.equals(LDAP_BASICAUTH_STR)) {
+ // is the password found in memory?
+ boolean inMem = false;
+ mType = LDAP_AUTHTYPE_BASICAUTH;
+ mParms = new String[2];
+ mParms[0] = config.getString(PROP_BINDDN);
+
+ // Passwords should only be written to the file for testing,
+ // never in production
+ mParms[1] = config.getString(PROP_BINDPW, null);
+
+ // Next, see if this password has been requested before
+ String prompt = config.getString(PROP_BINDPW_PROMPT, null);
+
+ if (prompt == null) {
+ prompt = "LDAP Authentication";
+ CMS.debug("LdapAuthInfo: init: prompt is null, change to "+prompt);
+ } else
+ CMS.debug("LdapAuthInfo: init: prompt is "+prompt);
+
+ if (mParms[1] == null) {
+ CMS.debug("LdapAuthInfo: init: try getting from memory cache");
+ mParms[1] = (String) passwords.get(prompt);
+if (mParms[1] != null) {
+ inMem = true;
+CMS.debug("LdapAuthInfo: init: got password from memory");
+} else
+CMS.debug("LdapAuthInfo: init: password not in memory");
+ } else
+CMS.debug("LdapAuthInfo: init: found password from config");
+
+ if (mParms[1] == null) {
+ mParms[1] = getPasswordFromStore(prompt);
+ } else {
+ CMS.debug("LdapAuthInfo: init: password found for prompt.");
+ }
+
+ // verify the password
+ if ((mParms[1]!= null) && (!mParms[1].equals("")) && (host == null ||
+ authInfoOK(host, port, secure, mParms[0], mParms[1]))) {
+ // The password is OK or uncheckable
+ CMS.debug("LdapAuthInfo: password ok: store in memory cache");
+ passwords.put(prompt, mParms[1]);
+ } else {
+ if (mParms[1] == null)
+ CMS.debug("LdapAuthInfo: password not found");
+ else {
+ CMS.debug("LdapAuthInfo: password does not work");
+/* what do you know? Our IPasswordStore does not have a remove function.
+ pstore.remove("internaldb");
+*/
+ if (inMem) {
+ // this is for the case when admin changes pwd
+ // from console
+ mParms[1] = getPasswordFromStore(prompt);
+ if(authInfoOK(host, port, secure, mParms[0], mParms[1])) {
+ CMS.debug("LdapAuthInfo: password ok: store in memory cache");
+ passwords.put(prompt, mParms[1]);
+ }
+ }
+ }
+ }
+
+ } else if (authTypeStr.equals(LDAP_SSLCLIENTAUTH_STR)) {
+ mType = LDAP_AUTHTYPE_SSLCLIENTAUTH;
+ mParms = new String[1];
+ mParms[0] = config.getString(PROP_CLIENTCERTNICKNAME, null);
+ } else {
+ throw new IllegalArgumentException(
+ "Unknown Ldap authentication type " + authTypeStr);
+ }
+ mInited = true;
+ CMS.debug("LdapAuthInfo: init ends");
+ }
+
+ public void reset() {
+ try {
+ conn.disconnect();
+ } catch (LDAPException e) {
+ }
+ }
+
+ /**
+ * Verifies the distinguished name and password by attempting to
+ * authenticate to the server. If we connect to the server but cannot
+ * authenticate, we conclude that the DN or password is invalid. If
+ * we cannot connect at all, we don't know, so we return true
+ * (there's no sense asking for the password again since we can't verify
+ * it anyway). If we connect and authenticate successfully, we know
+ * the DN and password are correct, so we return true.
+ */
+ private static LDAPConnection conn = new LDAPConnection();
+ private static boolean
+ authInfoOK(String host, int port, boolean secure, String dn, String pw) {
+
+ // We dont perform auth checking if we are in SSL mode.
+ if (secure)
+ return true;
+
+ boolean connected = false, authenticated = false;
+
+ try {
+ conn.connect(host, port);
+ connected = true;
+ conn.authenticate(dn, pw);
+ authenticated = true;
+ } catch (LDAPException e) {
+ }
+
+ /**
+ * There is a bug in LDAP SDK. VM will crash on NT if
+ * we connect and disconnect too many times.
+ **/
+
+ /**
+ if( connected ) {
+ try {
+ conn.disconnect();
+ } catch( LDAPException e ) { }
+ }
+ **/
+
+ if (connected && !authenticated) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * get authentication type.
+ * @return one of: <br>
+ * LdapAuthInfo.LDAP_AUTHTYPE_BASICAUTH or
+ * LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH
+ */
+ public int getAuthType() {
+ return mType;
+ }
+
+ /**
+ * get params for authentication
+ * @return array of parameters for this authentication.
+ */
+ public String[] getParms() {
+ return (String[]) mParms.clone();
+ }
+
+ /**
+ * add password
+ */
+ public void addPassword(String prompt, String pw) {
+ try {
+ passwords.put(prompt, pw);
+ }catch (Exception e) {
+ }
+ }
+
+ /**
+ * remove password
+ */
+ public void removePassword(String prompt) {
+ try {
+ passwords.remove(prompt);
+ }catch (Exception e) {
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java
new file mode 100644
index 000000000..31e3dca1c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java
@@ -0,0 +1,530 @@
+// --- 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.cmscore.ldapconn;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Factory for getting LDAP Connections to a LDAP server with the same
+ * LDAP authentication.
+ * XXX not sure how useful this is given that LDAPConnection itself can
+ * be shared by multiple threads and cloned.
+ */
+public class LdapBoundConnFactory implements ILdapBoundConnFactory {
+ protected int mMinConns = 5;
+ protected int mMaxConns = 1000;
+ protected LdapConnInfo mConnInfo = null;
+ protected LdapAuthInfo mAuthInfo = null;
+
+ private ILogger mLogger = CMS.getLogger();
+
+ public static final String PROP_MINCONNS = "minConns";
+ public static final String PROP_MAXCONNS = "maxConns";
+ public static final String PROP_LDAPCONNINFO = "ldapconn";
+ public static final String PROP_LDAPAUTHINFO = "ldapauth";
+
+ public static final String PROP_ERROR_IF_DOWN = "errorIfDown";
+
+ private int mNumConns = 0; // number of available conns in array
+ private int mTotal = 0; // total num conns
+
+ private boolean doCloning=true;
+ private LdapBoundConnection mMasterConn = null; // master connection object.
+ private BoundConnection mConns[];
+
+ /**
+ * return error if server is down at creation time.
+ */
+ private boolean mErrorIfDown;
+
+ /**
+ * default value for the above at init time.
+ */
+ private boolean mDefErrorIfDown = false;
+
+ /**
+ * Constructor for initializing from the config store.
+ * must be followed by init(IConfigStore)
+ */
+ public LdapBoundConnFactory() {
+ }
+
+ public LdapBoundConnFactory(boolean defErrorIfDown) {
+ mDefErrorIfDown = defErrorIfDown;
+ }
+
+ public int totalConn() {
+ return mTotal;
+ }
+
+ public int freeConn() {
+ return mNumConns;
+ }
+
+ public int maxConn() {
+ return mMaxConns;
+ }
+
+ /**
+ * Constructor for LdapBoundConnFactory
+ * @param minConns minimum number of connections to have available
+ * @param maxConns max number of connections to have available. This is
+ * the maximum number of clones of this connection or separate connections one wants to allow.
+ * @param serverInfo server connection info - host, port, etc.
+ */
+ public LdapBoundConnFactory(int minConns, int maxConns,
+ LdapConnInfo connInfo, LdapAuthInfo authInfo) throws ELdapException {
+ init(minConns, maxConns, connInfo, authInfo);
+ }
+
+ /**
+ * Constructor for initialize
+ */
+ public void init(IConfigStore config)
+ throws ELdapException, EBaseException {
+
+ CMS.debug("LdapBoundConnFactory: init ");
+ LdapConnInfo connInfo =
+ new LdapConnInfo(config.getSubStore(PROP_LDAPCONNINFO));
+
+ mErrorIfDown = config.getBoolean(PROP_ERROR_IF_DOWN, mDefErrorIfDown);
+
+ doCloning = config.getBoolean("doCloning",true);
+
+ CMS.debug("LdapBoundConnFactory:doCloning " + doCloning);
+ init(config.getInteger(PROP_MINCONNS, mMinConns),
+ config.getInteger(PROP_MAXCONNS, mMaxConns),
+ connInfo,
+ new LdapAuthInfo(config.getSubStore(PROP_LDAPAUTHINFO),
+ connInfo.getHost(), connInfo.getPort(), connInfo.getSecure()));
+ }
+
+ /**
+ * initialize parameters obtained from either constructor or
+ * config store
+ * @param minConns minimum number of connection handls to have available.
+ * @param maxConns maximum total number of connections to ever have.
+ * @param connInfo ldap connection info.
+ * @param authInfo ldap authentication info.
+ * @exception ELdapException if any error occurs.
+ */
+ private void init(int minConns, int maxConns,
+ LdapConnInfo connInfo, LdapAuthInfo authInfo)
+ throws ELdapException {
+ if (minConns <= 0 || maxConns <= 0 || minConns > maxConns)
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_INVALID_NUMCONN_PARAMETERS"));
+ if (connInfo == null || authInfo == null)
+ throw new IllegalArgumentException("connInfo or authInfo is null!");
+
+ mMinConns = minConns;
+ mMaxConns = maxConns;
+ mConnInfo = connInfo;
+ mAuthInfo = authInfo;
+
+ mConns = new BoundConnection[mMaxConns];
+
+ // Create connection handle and make initial connection
+ CMS.debug(
+ "init: before makeConnection errorIfDown is " + mErrorIfDown);
+ makeConnection(mErrorIfDown);
+
+ CMS.debug(
+ "initializing with mininum " + mMinConns + " and maximum " + mMaxConns +
+ " connections to " +
+ "host " + mConnInfo.getHost() + " port " + mConnInfo.getPort() +
+ ", secure connection, " + mConnInfo.getSecure() +
+ ", authentication type " + mAuthInfo.getAuthType());
+
+ // initalize minimum number of connection handles available.
+ makeMinimum();
+ }
+
+ /**
+ * makes the initial master connection used to clone others..
+ * @exception ELdapException if any error occurs.
+ */
+ protected void makeConnection(boolean errorIfDown) throws ELdapException {
+ CMS.debug("makeConnection: errorIfDown " + errorIfDown);
+ try {
+ mMasterConn = new BoundConnection(mConnInfo, mAuthInfo);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_CONNECT_SERVER",
+ mConnInfo.getHost(),
+ Integer.toString(mConnInfo.getPort())));
+ if (errorIfDown) {
+ throw new ELdapServerDownException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE",
+ mConnInfo.getHost(), "" + mConnInfo.getPort()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_FAILED_SERVER", e.toString()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CONNECT_TO_LDAP_SERVER_FAILED",
+ mConnInfo.getHost(), "" + (Integer.valueOf(mConnInfo.getPort())), e.toString()));
+ }
+ }
+ }
+
+
+ /**
+ * makes subsequent connections if cloning is not used .
+ * @exception ELdapException if any error occurs.
+ */
+ private LdapBoundConnection makeNewConnection(boolean errorIfDown) throws ELdapException {
+ CMS.debug("LdapBoundConnFactory:In makeNewConnection: errorIfDown " + errorIfDown);
+ LdapBoundConnection conn = null;
+ try {
+ conn = new BoundConnection(mConnInfo, mAuthInfo);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ // need to intercept this because message from LDAP is
+ // "DSA is unavailable" which confuses with DSA PKI.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_CONNECT_SERVER",
+ mConnInfo.getHost(),
+ Integer.toString(mConnInfo.getPort())));
+ if (errorIfDown) {
+ throw new ELdapServerDownException(
+ CMS.getUserMessage("CMS_LDAP_SERVER_UNAVAILABLE",
+ mConnInfo.getHost(), "" + mConnInfo.getPort()));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_FAILED_SERVER", e.toString()));
+ throw new ELdapException(
+ CMS.getUserMessage("CMS_LDAP_CONNECT_TO_LDAP_SERVER_FAILED",
+ mConnInfo.getHost(), "" + (Integer.valueOf(mConnInfo.getPort())), e.toString()));
+ }
+ }
+
+ return conn;
+ }
+ /**
+ * makes the minumum number of connections
+ */
+ private void makeMinimum() throws ELdapException {
+ if (mMasterConn == null || mMasterConn.isConnected() == false)
+ return;
+ int increment;
+
+ if (mNumConns < mMinConns && mTotal <= mMaxConns) {
+ increment = Math.min(mMinConns - mNumConns, mMaxConns - mTotal);
+ CMS.debug(
+ "increasing minimum connections by " + increment);
+ for (int i = increment - 1; i >= 0; i--) {
+
+ if(doCloning == true) {
+ mConns[i] = (BoundConnection) mMasterConn.clone();
+ }
+ else {
+ mConns[i] = (BoundConnection) makeNewConnection(true);
+ }
+
+ }
+ mTotal += increment;
+ mNumConns += increment;
+ CMS.debug("new total available connections " + mTotal);
+ CMS.debug("new number of connections " + mNumConns);
+ }
+ }
+
+ /**
+ * gets a conenction from this factory.
+ * All connections obtained from the factory must be returned by
+ * returnConn() method.
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public LDAPConnection getConn()
+ throws ELdapException {
+ return getConn(true);
+ }
+
+ /**
+ * Returns a LDAP connection - a clone of the master connection.
+ * All connections should be returned to the factory using returnConn()
+ * to recycle connection objects.
+ * If not returned the limited max number is affected but if that
+ * number is large not much harm is done.
+ * Returns null if maximum number of connections reached.
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized LDAPConnection getConn(boolean waitForConn)
+ throws ELdapException {
+ boolean waited = false;
+
+ CMS.debug("In LdapBoundConnFactory::getConn()");
+ if(mMasterConn != null)
+ CMS.debug("masterConn is connected: " + mMasterConn.isConnected());
+ else
+ CMS.debug("masterConn is null.");
+
+ if (mMasterConn == null || !mMasterConn.isConnected()) {
+ try {
+ makeConnection(true);
+ } catch (ELdapException e) {
+ mMasterConn = null;
+ CMS.debug("Can't create master connection in LdapBoundConnFactory::getConn! " + e.toString());
+ throw e;
+ }
+ }
+
+ if (mNumConns == 0)
+ makeMinimum();
+ if (mNumConns == 0) {
+ if (!waitForConn)
+ return null;
+ try {
+ CMS.debug("getConn: out of ldap connections");
+ log(ILogger.LL_WARN,
+ "Ran out of ldap connections available " +
+ "in ldap connection pool to " +
+ mConnInfo.getHost() + ":" + mConnInfo.getPort() + ". " +
+ "This could be a temporary condition or an indication of " +
+ "something more serious that can cause the server to " +
+ "hang.");
+ waited = true;
+ while (mNumConns == 0)
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ mNumConns--;
+ LDAPConnection conn = mConns[mNumConns];
+
+ boolean isConnected = false;
+ if(conn != null) {
+ isConnected = conn.isConnected();
+ }
+
+ CMS.debug("getConn: conn is connected " + isConnected);
+
+ //If masterConn is still alive, lets try to bring this one
+ //back to life
+
+ if((isConnected == false) && (mMasterConn != null)
+ && (mMasterConn.isConnected() == true)) {
+ CMS.debug("Attempt to bring back down connection.");
+
+ if(doCloning == true) {
+ mConns[mNumConns] = (BoundConnection) mMasterConn.clone();
+ }
+ else {
+ try {
+ mConns[mNumConns] = (BoundConnection) makeNewConnection(true);
+ }
+ catch (ELdapException e) {
+ mConns[mNumConns] = null;
+ }
+ }
+ conn = mConns[mNumConns];
+
+ CMS.debug("Re-animated connection: " + conn);
+ }
+
+ mConns[mNumConns] = null;
+
+ if (waited) {
+ log(ILogger.LL_WARN,
+ "Ldap connections are available again in ldap connection pool " +
+ "to " + mConnInfo.getHost() + ":" + mConnInfo.getPort());
+ }
+ CMS.debug("getConn: mNumConns now " + mNumConns);
+
+ return conn;
+ }
+
+ /**
+ * Teturn connection to the factory.
+ * This is mandatory after a getConn().
+ * The best thing to do is to put returnConn in a finally clause so it
+ * always gets called. For example,
+ * <pre>
+ * LDAPConnection c = null;
+ * try {
+ * c = factory.getConn();
+ * myclass.do_something_with_c(c);
+ * }
+ * catch (ELdapException e) {
+ * handle_error_here();
+ * }
+ * finally {
+ * factory.returnConn(c);
+ * }
+ * </pre>
+ */
+ public synchronized void returnConn(LDAPConnection conn) {
+ if (conn == null) {
+ return;
+ }
+ BoundConnection boundconn = (BoundConnection) conn;
+
+ if (boundconn.getFacId() != mConns) {
+ log(ILogger.LL_WARN, "returnConn: unknown connection.");
+
+ /* swallow this exception but see who's doing it. */
+ ELdapException e =
+ new ELdapException(CMS.getUserMessage("CMS_LDAP_UNKNOWN_RETURNED_CONN"));
+ }
+ for (int i = 0; i < mNumConns; i++) {
+ if (mConns[i] == conn) {
+ CMS.debug(
+ "returnConn: previously returned connection.");
+
+ /* swallow this exception but see who's doing it */
+ ELdapException e =
+ new ELdapException(CMS.getUserMessage("CMS_LDAP_BAD_RETURNED_CONN"));
+ }
+ }
+ mConns[mNumConns++] = boundconn;
+ CMS.debug("returnConn: mNumConns now " + mNumConns);
+ notify();
+ }
+
+ /**
+ * handy routine for logging in this class.
+ */
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_LDAP, level,
+ "In Ldap (bound) connection pool to" +
+ " host " + mConnInfo.getHost() +
+ " port " + mConnInfo.getPort() + ", " + msg);
+ }
+
+ protected void finalize()
+ throws Exception {
+ reset();
+ }
+
+ /**
+ * used for disconnecting all connections and reset everything to 0
+ * as if connections were never made. used just before a subsystem
+ * shutdown or process exit.
+ * useful only if no connections are outstanding.
+ */
+ public synchronized void reset()
+ throws ELdapException {
+ if (mNumConns == mTotal) {
+ for (int i = 0; i < mNumConns; i++) {
+ try {
+ mConns[i].disconnect();
+ } catch (LDAPException e) {
+ }
+ mConns[i] = null;
+ }
+ if (mMasterConn != null) {
+ try {
+ log(ILogger.LL_INFO, "disconnecting masterConn");
+ mMasterConn.disconnect();
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_CANNOT_RESET",
+ e.toString()));
+ }
+ }
+ mMasterConn = null;
+ mTotal = 0;
+ mNumConns = 0;
+ } else {
+ CMS.debug(
+ "Cannot reset factory: connections not all returned");
+ throw new ELdapException(CMS.getUserMessage("CMS_LDAP_CANNOT_RESET_CONNFAC"));
+ }
+
+ if (mAuthInfo != null) {
+ mAuthInfo.reset();
+ }
+ }
+
+ /**
+ * return ldap connection info
+ */
+ public LdapConnInfo getConnInfo() {
+ return mConnInfo;
+ }
+
+ /**
+ * return ldap authentication info
+ */
+ public LdapAuthInfo getAuthInfo() {
+ return mAuthInfo;
+ }
+
+ /**
+ * used to keep track of connections from this factory.
+ */
+ public class BoundConnection extends LdapBoundConnection {
+ public BoundConnection(LdapConnInfo connInfo, LdapAuthInfo authInfo)
+ throws LDAPException {
+ super(connInfo, authInfo);
+ }
+
+ public BoundConnection(String host, int port, int version,
+ LDAPSocketFactory fac,
+ String bindDN, String bindPW)
+ throws LDAPException {
+ super(host, port, version, fac, bindDN, bindPW);
+ }
+
+ /**
+ * used only to identify the factory from which this came.
+ */
+ public BoundConnection[] getFacId() {
+ return mConns;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java
new file mode 100644
index 000000000..8a6b98fc3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java
@@ -0,0 +1,214 @@
+// --- 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.cmscore.ldapconn;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * A LDAP connection that is bound to a server host, port, secure type.
+ * and authentication.
+ * Makes a LDAP connection and authentication when instantiated.
+ * Cannot establish another LDAP connection or authentication after
+ * construction. LDAPConnection connect and authentication methods are
+ * overridden to prevent this.
+ */
+public class LdapBoundConnection extends LDAPConnection {
+ // LDAPConnection calls authenticate so must set this for first
+ // authenticate call.
+ private boolean mAuthenticated = false;
+
+ /**
+ * Instantiates a connection to a ldap server, secure or non-secure
+ * connection with Ldap basic bind dn & pw authentication.
+ */
+ public LdapBoundConnection(
+ LdapConnInfo connInfo, LdapAuthInfo authInfo)
+ throws LDAPException {
+ // this LONG line to satisfy super being the first call. (yuk)
+ super(
+ authInfo.getAuthType() == LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH ?
+ new LdapJssSSLSocketFactory(authInfo.getParms()[0]) :
+ (connInfo.getSecure() ? new LdapJssSSLSocketFactory() : null));
+
+ // Set option to automatically follow referrals.
+ // Use the same credentials to follow referrals; this is the easiest
+ // thing to do without any complicated configuration using
+ // different hosts.
+ // If client auth is used don't have dn and pw to follow referrals.
+
+ boolean followReferrals = connInfo.getFollowReferrals();
+
+ setOption(LDAPv2.REFERRALS, new Boolean(followReferrals));
+ if (followReferrals &&
+ authInfo.getAuthType() != LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH) {
+ LDAPRebind rebindInfo =
+ new ARebindInfo(authInfo.getParms()[0],
+ authInfo.getParms()[1]);
+
+ setOption(LDAPv2.REFERRALS_REBIND_PROC, rebindInfo);
+ }
+
+ if (authInfo.getAuthType() == LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH) {
+ // will be bound to client auth cert mapped entry.
+ super.connect(connInfo.getHost(), connInfo.getPort());
+ CMS.debug(
+ "Established LDAP connection with SSL client auth to " +
+ connInfo.getHost() + ":" + connInfo.getPort());
+ } else { // basic auth
+ String binddn = authInfo.getParms()[0];
+ String bindpw = authInfo.getParms()[1];
+
+ super.connect(connInfo.getVersion(),
+ connInfo.getHost(), connInfo.getPort(), binddn, bindpw);
+ CMS.debug(
+ "Established LDAP connection using basic authentication to" +
+ " host " + connInfo.getHost() +
+ " port " + connInfo.getPort() +
+ " as " + binddn);
+ }
+ }
+
+ /**
+ * Instantiates a connection to a ldap server, secure or non-secure
+ * connection with Ldap basic bind dn & pw authentication.
+ */
+ public LdapBoundConnection(String host, int port, int version,
+ LDAPSocketFactory fac,
+ String bindDN, String bindPW)
+ throws LDAPException {
+ super(fac);
+ if (bindDN != null) {
+ super.connect(version, host, port, bindDN, bindPW);
+ CMS.debug(
+ "Established LDAP connection using basic authentication " +
+ " as " + bindDN + " to " + host + ":" + port);
+ } else {
+ if (fac == null && bindDN == null) {
+ throw new IllegalArgumentException(
+ "Ldap bound connection must have authentication info.");
+ }
+ // automatically authenticated if it's ssl client auth.
+ super.connect(version, host, port, null, null);
+ CMS.debug(
+ "Established LDAP connection using SSL client authentication " +
+ "to " + host + ":" + port);
+ }
+ }
+
+ /**
+ * Overrides same method in LDAPConnection to do prevent re-authentication.
+ */
+ public void authenticate(int version, String dn, String pw)
+ throws LDAPException {
+
+ /**
+ if (mAuthenticated) {
+ throw new RuntimeException(
+ "this LdapBoundConnection already authenticated: auth(v,dn,pw)");
+ }
+ **/
+ super.authenticate(version, dn, pw);
+ mAuthenticated = true;
+ }
+
+ /**
+ * Overrides same method in LDAPConnection to do prevent re-authentication.
+ */
+ public void authenticate(String dn, String pw)
+ throws LDAPException {
+
+ /**
+ if (mAuthenticated) {
+ throw new RuntimeException(
+ "this LdapBoundConnection already authenticated: auth(dn,pw)");
+ }
+ **/
+ super.authenticate(3, dn, pw);
+ mAuthenticated = true;
+ }
+
+ /**
+ * Overrides same method in LDAPConnection to do prevent re-authentication.
+ */
+ public void authenticate(String dn, String mech, String packageName,
+ Properties props, Object getter)
+ throws LDAPException {
+
+ /**
+ if (mAuthenticated) {
+ throw new RuntimeException(
+ "this LdapBoundConnection already authenticated: auth(mech)");
+ }
+ **/
+ super.authenticate(dn, mech, packageName, props, getter);
+ mAuthenticated = true;
+ }
+
+ /**
+ * Overrides same method in LDAPConnection to do prevent re-authentication.
+ */
+ public void authenticate(String dn, String mechs[], String packageName,
+ Properties props, Object getter)
+ throws LDAPException {
+
+ /**
+ if (mAuthenticated) {
+ throw new RuntimeException(
+ "this LdapBoundConnection is already authenticated: auth(mechs)");
+ }
+ **/
+ super.authenticate(dn, mechs, packageName, props, getter);
+ mAuthenticated = true;
+ }
+
+ /**
+ * overrides parent's connect to prevent re-connect.
+ */
+ public void connect(String host, int port) throws LDAPException {
+ throw new RuntimeException(
+ "this LdapBoundConnection is already connected: conn(host,port)");
+ }
+
+ /**
+ * overrides parent's connect to prevent re-connect.
+ */
+ public void connect(int version, String host, int port,
+ String dn, String pw) throws LDAPException {
+ throw new RuntimeException(
+ "this LdapBoundConnection is already connected: conn(version,h,p)");
+ }
+}
+
+
+class ARebindInfo implements LDAPRebind {
+ private LDAPRebindAuth mRebindAuthInfo = null;
+
+ public ARebindInfo(String binddn, String pw) {
+ mRebindAuthInfo = new LDAPRebindAuth(binddn, pw);
+ }
+
+ public LDAPRebindAuth getRebindAuthentication(String host, int port) {
+ return mRebindAuthInfo;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java
new file mode 100644
index 000000000..ba037d854
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java
@@ -0,0 +1,118 @@
+// --- 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.cmscore.ldapconn;
+
+
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * class for reading ldap connection from the config store.
+ * ldap connection info: host, port, secure connection
+ */
+public class LdapConnInfo implements ILdapConnInfo {
+
+ private String mHost = null;
+ private int mPort = -1;
+ private boolean mSecure = false;
+ private int mVersion = LDAPv2.PROTOCOL_VERSION;
+ private boolean mFollowReferrals = true;
+
+ /**
+ * default constructor. must be followed by init(IConfigStore)
+ */
+ public LdapConnInfo(IConfigStore config) throws EBaseException, ELdapException {
+ init(config);
+ }
+
+ /**
+ * initializes an instance from a config store.
+ * required parms: host, port
+ * optional parms: secure connection, authentication method & info.
+ */
+ public void init(IConfigStore config) throws EBaseException, ELdapException {
+ mHost = config.getString(PROP_HOST);
+ mPort = config.getInteger(PROP_PORT);
+ String version = (String) config.get(PROP_PROTOCOL);
+
+ if (version != null && version.equals("")) {
+ // provide a default when this field is blank from the
+ // configuration.
+ mVersion = LDAP_VERSION_3;
+ } else {
+ mVersion = config.getInteger(PROP_PROTOCOL, LDAP_VERSION_3);
+ if (mVersion != LDAP_VERSION_2 && mVersion != LDAP_VERSION_3) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY", PROP_PROTOCOL));
+ }
+ }
+ if (mHost == null || (mHost.length() == 0) || (mHost.trim().equals(""))) {
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", PROP_HOST));
+ }
+ if (mPort <= 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY", PROP_PORT));
+ }
+ mSecure = config.getBoolean(PROP_SECURE, false);
+ mFollowReferrals = config.getBoolean(PROP_FOLLOW_REFERRALS, true);
+ }
+
+ public LdapConnInfo(String host, int port, boolean secure) {
+ mHost = host;
+ mPort = port;
+ mSecure = secure;
+ if (mHost == null || mPort <= 0) {
+ // XXX log something here
+ throw new IllegalArgumentException("LDAP host or port is null");
+ }
+ }
+
+ public LdapConnInfo(String host, int port) {
+ mHost = host;
+ mPort = port;
+ if (mHost == null || mPort <= 0) {
+ // XXX log something here
+ throw new IllegalArgumentException("LDAP host or port is null");
+ }
+ }
+
+ public String getHost() {
+ return mHost;
+ }
+
+ public int getPort() {
+ return mPort;
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public boolean getSecure() {
+ return mSecure;
+ }
+
+ public boolean getFollowReferrals() {
+ return mFollowReferrals;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java
new file mode 100644
index 000000000..b9f7d78eb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java
@@ -0,0 +1,104 @@
+// --- 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.cmscore.ldapconn;
+
+
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import org.mozilla.jss.ssl.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+
+
+/**
+ * Uses HCL ssl socket.
+ * @author Lily Hsiao lhsiao@netscape.com
+ */
+public class LdapJssSSLSocketFactory implements LDAPSSLSocketFactoryExt {
+ private String mClientAuthCertNickname = null;
+ private boolean mClientAuth = false;
+
+ public LdapJssSSLSocketFactory() {
+ }
+
+ public LdapJssSSLSocketFactory(String certNickname) {
+ mClientAuthCertNickname = certNickname;
+ }
+
+ public Socket makeSocket(String host, int port) throws LDAPException {
+ SSLSocket s = null;
+
+ try {
+ SSLSocket.enableSSL2Default(false);
+ s = new SSLSocket(host, port);
+ s.setUseClientMode(true);
+ s.enableSSL2(false);
+ s.enableSSL2Default(false);
+ s.enableV2CompatibleHello(false);
+
+ SSLHandshakeCompletedListener listener = null;
+
+ listener = new ClientHandshakeCB(this);
+ s.addHandshakeCompletedListener(listener);
+
+ if (mClientAuthCertNickname != null) {
+ mClientAuth = true;
+ CMS.debug(
+ "LdapJssSSLSocket set client auth cert nickname" +
+ mClientAuthCertNickname);
+ s.setClientCertNickname(mClientAuthCertNickname);
+ }
+ s.forceHandshake();
+ } catch (UnknownHostException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_LDAPCONN_UNKNOWN_HOST"));
+ throw new LDAPException(
+ "Cannot Create JSS SSL Socket - Unknown host");
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_LDAPCONN_IO_ERROR", e.toString()));
+ throw new LDAPException("IO Error creating JSS SSL Socket");
+ }
+ return s;
+ }
+
+ public boolean isClientAuth() {
+ return mClientAuth;
+ }
+
+ public Object getCipherSuites() {
+ return null;
+ }
+
+ public void log(int level, String msg) {
+ }
+
+ class ClientHandshakeCB implements SSLHandshakeCompletedListener {
+ Object sc;
+
+ public ClientHandshakeCB(Object sc) {
+ this.sc = sc;
+ }
+
+ public void handshakeCompleted(SSLHandshakeCompletedEvent event) {
+ CMS.debug("SSL handshake happened");
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java b/pki/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java
new file mode 100644
index 000000000..a7961e207
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java
@@ -0,0 +1,57 @@
+// --- 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.cmscore.listeners;
+
+
+import com.netscape.certsrv.base.*;
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * This class represents a registered listener plugin.
+ * <P>
+ *
+ * @author stevep
+ * @version $Revision$, $Date$
+ */
+public class ListenerPlugin {
+ protected String mId = null;
+ protected String mClassPath = null;
+ protected Class mClass = null;
+
+ /**
+ * Constructs a Listener plugin.
+ * @param id listener implementation name
+ * @param classPath class path
+ */
+ public ListenerPlugin(String id, String classPath) {
+ // if (id == null || classPath == null)
+ // throw new AssertionException("Listener id or classpath can't be null");
+ mId = id;
+ mClassPath = classPath;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public String getClassPath() {
+ return mClassPath;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java b/pki/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java
new file mode 100644
index 000000000..e8c7032d1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java
@@ -0,0 +1,97 @@
+// --- 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.cmscore.logging;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A log event object for handling audit messages
+ * <P>
+ *
+ * @author mikep
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class AuditEventFactory implements ILogEventFactory {
+
+ /**
+ * List of supported properties.
+ */
+ public static final String PROP_BUNDLE = "bundleName";
+
+ /**
+ * Constructs a audit event factory.
+ */
+ public AuditEventFactory() {
+ }
+
+ /**
+ * Creates an log event.
+ *
+ * @param evtClass the event type
+ * @param prop the resource bundle
+ * @param source the subsystem ID who creates the log event
+ * @param level the severity of the log event
+ * @param multiline the log message has more than one line or not
+ * @param msg the detail message of the log
+ * @param params the parameters in the detail log message
+ */
+ public ILogEvent create(int evtClass, Properties prop, int source,
+ int level, boolean multiline, String msg, Object params[]) {
+ if (evtClass != ILogger.EV_AUDIT)
+ return null;
+ AuditEvent event = new AuditEvent(msg, params);
+
+ event.setLevel(level);
+ event.setSource(source);
+ event.setMultiline(multiline);
+ setProperties(prop, event);
+ return event;
+ }
+
+ /**
+ * Set the resource bundle of the log event.
+ *
+ * @param prop the properties
+ * @param event the log event
+ */
+ protected void setProperties(Properties prop, IBundleLogEvent event) {
+ if (prop == null) {
+ event.setBundleName(null);
+ } else {
+ String bundleName = (String) prop.get(PROP_BUNDLE);
+
+ if (bundleName != null) {
+ event.setBundleName(bundleName);
+ }
+ }
+ }
+
+ /**
+ * Releases an log event.
+ *
+ * @param e the log event
+ */
+ public void release(ILogEvent e) {
+ // do nothing
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/AuditFormat.java b/pki/base/common/src/com/netscape/cmscore/logging/AuditFormat.java
new file mode 100644
index 000000000..0af38f168
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/AuditFormat.java
@@ -0,0 +1,110 @@
+// --- 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.cmscore.logging;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * Define audit log message format
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class AuditFormat {
+
+ /**
+ * default log level for writing audit log
+ */
+ public static final int LEVEL = ILogger.LL_INFO;
+
+ /**
+ * initiative: the event is from EE
+ */
+ public static final String FROMUSER = "fromUser";
+
+ /**
+ * initiative: the event is from agent
+ */
+ public static final String FROMAGENT = "fromAgent";
+
+ /**
+ * initiative: the event is from router
+ */
+ public static final String FROMROUTER = "fromRouter";
+
+ /**
+ * initiative: the event is from remote authority
+ */
+ public static final String FROMRA = "fromRemoteAuthority";
+
+ /**
+ * authentication module: no Authentication manager
+ */
+ public static final String NOAUTH = "noAuthManager";
+
+ // for ProcessCertReq.java ,kra
+ /* 0: request type
+ 1: request ID
+ 2: initiative
+ 3: auth module
+ 4: status
+ 5: cert dn
+ 6: other info. eg cert serial number, violation policies
+ */
+ public static final String FORMAT =
+ "{0} reqID {1} {2} authenticated by {3} is {4} DN requested: {5} {6}";
+ public static final String NODNFORMAT =
+ "{0} reqID {1} {2} authenticated by {3} is {4}";
+
+ public static final String ENROLLMENTFORMAT =
+ IRequest.ENROLLMENT_REQUEST + " reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} {5}";
+ public static final String RENEWALFORMAT =
+ IRequest.RENEWAL_REQUEST + " reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} old serial number: 0x{5} {6}";
+ public static final String REVOCATIONFORMAT =
+ IRequest.REVOCATION_REQUEST + " reqID {0} {1} authenticated by {2} is {3}. DN requested: {4} serial number: 0x{5} revocation reason: {6} {7}";
+
+ // 1: fromAgent AgentID: xxx authenticated by xxx
+ public static final String DOREVOKEFORMAT =
+ IRequest.REVOCATION_REQUEST + " reqID {0} {1} is {2}. DN requested: {3} serial number: 0x{4} revocation reason: {5}";
+ // 1: fromAgent AgentID: xxx authenticated by xxx
+ public static final String DOUNREVOKEFORMAT =
+ IRequest.UNREVOCATION_REQUEST + " reqID {0} {1} is {2}. DN requested: {3} serial number: 0x{4}";
+
+ // 0:initiative
+ public static final String CRLUPDATEFORMAT =
+ "CRLUpdate request {0} authenticated by {1} is {2}. Id: {3}\ncrl Number: {4} last update time: {5} next update time: {6} number of entries in the CRL: {7}";
+
+ // audit user/group
+ public static final String ADDUSERFORMAT =
+ "Admin UID: {0} added User UID: {1}";
+ public static final String REMOVEUSERFORMAT =
+ "Admin UID: {0} removed User UID: {1} ";
+ public static final String MODIFYUSERFORMAT =
+ "Admin UID: {0} modified User UID: {1}";
+ public static final String ADDUSERCERTFORMAT =
+ "Admin UID: {0} added cert for User UID: {1}. cert DN: {2} serial number: 0x{3}";
+ public static final String REMOVEUSERCERTFORMAT =
+ "Admin UID: {0} removed cert of User UID: {1}. cert DN: {2} serial number: 0x{3}";
+ public static final String ADDUSERGROUPFORMAT =
+ "Admin UID: {0} added User UID: {1} to group: {2}";
+ public static final String REMOVEUSERGROUPFORMAT =
+ "Admin UID: {0} removed User UID: {1} from group: {2}";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/LogQueue.java b/pki/base/common/src/com/netscape/cmscore/logging/LogQueue.java
new file mode 100644
index 000000000..24336d308
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/LogQueue.java
@@ -0,0 +1,127 @@
+// --- 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.cmscore.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.MessageFormat;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * A class represents a log queue.
+ * <P>
+ *
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LogQueue implements ILogQueue {
+
+ private static LogQueue mLogQueue = new LogQueue();
+ protected Vector mListeners = null;
+
+ /**
+ * Constructs a log queue.
+ */
+ public LogQueue() {
+ }
+
+ public static ILogQueue getLogQueue() {
+ return mLogQueue;
+ }
+
+ /**
+ * Initializes the log queue.
+ * <P>
+ *
+ */
+ public void init() {
+ mListeners = new Vector();
+
+ }
+
+ /**
+ * Stops this log queue: shuts down all registered listeners
+ * <P>
+ */
+ public void shutdown() {
+ if (mListeners == null)
+ return;
+ for (int i = 0; i < mListeners.size(); i++) {
+ ((ILogEventListener) mListeners.elementAt(i)).shutdown();
+ }
+ mListeners = null;
+ }
+
+ /**
+ * Adds an event listener.
+ *
+ * @param listener the log event listener
+ */
+ public void addLogEventListener(ILogEventListener listener) {
+ //Make sure we don't have duplicated listener
+ if (!mListeners.contains(listener))
+ mListeners.addElement(listener);
+ }
+
+ /**
+ * Removes an event listener.
+ *
+ * @param listener the log event listener
+ */
+ public void removeLogEventListener(ILogEventListener listener) {
+ mListeners.removeElement(listener);
+ }
+
+ /**
+ * Logs an event, and notifies logger to reuse the event.
+ *
+ * @param event the log event
+ */
+ public void log(ILogEvent event) {
+ if (mListeners == null)
+ return;
+ for (int i = 0; i < mListeners.size(); i++) {
+ try {
+ ((ILogEventListener) mListeners.elementAt(i)).log(event);
+ } catch (ELogException e) {
+ // Raidzilla Bug #57592: Don't display potentially
+ // incorrect log message.
+ // ConsoleError.send(new SystemEvent(CMS.getUserMessage("CMS_LOG_EVENT_FAILED",
+ // event.getEventType(), e.toString())));
+
+ // Don't do this again.
+ removeLogEventListener((ILogEventListener)
+ mListeners.elementAt(i));
+ }
+ }
+ }
+
+ /**
+ * Flushes the log buffers (if any)
+ */
+ public void flush() {
+ for (int i = 0; i < mListeners.size(); i++) {
+ ((ILogEventListener) mListeners.elementAt(i)).flush();
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java b/pki/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java
new file mode 100644
index 000000000..9a9d4bd4f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java
@@ -0,0 +1,272 @@
+// --- 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.cmscore.logging;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.MessageFormat;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A class represents a log subsystem.
+ * <P>
+ *
+ * @author thomask
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class LogSubsystem implements ILogSubsystem {
+
+ private static LogSubsystem mInstance = new LogSubsystem();
+ private static ILogQueue mLogQueue = LogQueue.getLogQueue();
+ private IConfigStore mConfig = null;
+
+ public static final String PROP_LOGGING = "log";
+
+ public static final String ID = "log";
+
+ public static final String PROP_CLASS = "class";
+ public static final String PROP_IMPL = "impl";
+ public static final String PROP_PLUGIN = "pluginName";
+ public static final String PROP_INSTANCE = "instance";
+
+ public Hashtable mLogPlugins = new Hashtable();
+ public Hashtable mLogInsts = new Hashtable();
+
+ /**
+ * Constructs a log subsystem.
+ */
+ private LogSubsystem() {
+ }
+
+ public String getId() {
+ return ID;
+ }
+
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Initializes the log subsystem.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ mLogQueue.init();
+
+ // load log plugin implementation
+ IConfigStore c = config.getSubStore(PROP_IMPL);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+ String pluginPath = c.getString(id + "." + PROP_CLASS);
+ LogPlugin plugin = new LogPlugin(id, pluginPath);
+
+ mLogPlugins.put(id, plugin);
+ }
+ if (Debug.ON)
+ Debug.trace("loaded logger plugins");
+
+ // load log instances
+ c = config.getSubStore(PROP_INSTANCE);
+ Enumeration instances = c.getSubStoreNames();
+
+ while (instances.hasMoreElements()) {
+ String insName = (String) instances.nextElement();
+ String implName = c.getString(insName + "." +
+ PROP_PLUGIN);
+ LogPlugin plugin =
+ (LogPlugin) mLogPlugins.get(implName);
+
+ if (plugin == null) {
+ throw new EBaseException(implName);
+ }
+ String className = plugin.getClassPath();
+ // Instantiate and init the log listener.
+ ILogEventListener logInst = null;
+
+ try {
+ logInst = (ILogEventListener)
+ Class.forName(className).newInstance();
+ IConfigStore pConfig =
+ c.getSubStore(insName);
+
+ logInst.init(this, pConfig);
+ // for view from console
+
+ } catch (ClassNotFoundException e) {
+ String errMsg = "LogSubsystem:: init()-" + e.toString();
+
+ throw new EBaseException(insName + ":Failed to instantiate class " + className);
+ } catch (IllegalAccessException e) {
+ String errMsg = "LogSubsystem:: init()-" + e.toString();
+
+ throw new EBaseException(insName + ":Failed to instantiate class " + className);
+ } catch (InstantiationException e) {
+ String errMsg = "LogSubsystem:: init()-" + e.toString();
+
+ throw new EBaseException(insName + ":Failed to instantiate class " + className);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ throw new EBaseException(insName + ":Failed to instantiate class " + className + " error: " + e.getMessage());
+ }
+
+ if (logInst == null) {
+ throw new EBaseException("Failed to instantiate class " + className);
+ }
+
+ if (insName == null) {
+ throw new EBaseException("Failed to instantiate class " + insName);
+ }
+
+ // add log instance to list.
+ mLogInsts.put(insName, logInst);
+ if (Debug.ON)
+ Debug.trace("loaded log instance " + insName + " impl " + implName);
+ }
+
+ }
+
+ public void startup() throws EBaseException {
+ Debug.trace("entering LogSubsystem.startup()");
+ Enumeration enum1 = mLogInsts.keys();
+
+ while (enum1.hasMoreElements()) {
+ String instName = (String) enum1.nextElement();
+
+ Debug.trace("about to call inst=" + instName + " in LogSubsystem.startup()");
+ ILogEventListener inst = (ILogEventListener)
+ mLogInsts.get(instName);
+
+ inst.startup();
+ }
+ }
+
+ /**
+ * Stops this subsystem.
+ * <P>
+ */
+ public void shutdown() {
+ mLogQueue.shutdown();
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves singleton: the LogSubsystem.
+ */
+ public static LogSubsystem getInstance() {
+ return mInstance;
+ }
+
+ /**
+ * Retrieves LogQueue.
+ */
+ public static ILogQueue getLogQueue() {
+ return mLogQueue;
+ }
+
+ public String getLogPluginName(ILogEventListener log) {
+ IConfigStore cs = log.getConfigStore();
+
+ try {
+ return cs.getString("pluginName", "");
+ } catch (EBaseException e) {
+ return "";
+ }
+ }
+
+ /**
+ * Retrieve log instance by it's name
+ */
+ public ILogEventListener getLogInstance(String insName) {
+ return (ILogEventListener) mLogInsts.get(insName);
+ }
+
+ public Hashtable getLogPlugins() {
+ return mLogPlugins;
+ }
+
+ public Hashtable getLogInsts() {
+ return mLogInsts;
+ }
+
+ public Vector getLogDefaultParams(String implName) throws
+ ELogException {
+ // is this a registered implname?
+ LogPlugin plugin = (LogPlugin)
+ mLogPlugins.get(implName);
+
+ if (plugin == null) {
+ throw new ELogException(implName);
+ }
+
+ // a temporary instance
+ ILogEventListener LogInst = null;
+ String className = plugin.getClassPath();
+
+ try {
+ LogInst = (ILogEventListener)
+ Class.forName(className).newInstance();
+ Vector v = LogInst.getDefaultParams();
+
+ return v;
+ } catch (InstantiationException e) {
+ throw new ELogException(
+ CMS.getUserMessage("CMS_LOG_LOAD_CLASS_FAIL", className));
+ } catch (ClassNotFoundException e) {
+ throw new ELogException(
+ CMS.getUserMessage("CMS_LOG_LOAD_CLASS_FAIL", className));
+ } catch (IllegalAccessException e) {
+ throw new ELogException(
+ CMS.getUserMessage("CMS_LOG_LOAD_CLASS_FAIL", className));
+ }
+ }
+
+ public Vector getLogInstanceParams(String insName) throws
+ ELogException {
+ ILogEventListener logInst = getLogInstance(insName);
+
+ if (logInst == null) {
+ return null;
+ }
+ Vector v = logInst.getInstanceParams();
+
+ return v;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/Logger.java b/pki/base/common/src/com/netscape/cmscore/logging/Logger.java
new file mode 100644
index 000000000..b15717ca4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/Logger.java
@@ -0,0 +1,374 @@
+// --- 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.cmscore.logging;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * A class represents certificate server logger
+ * implementation.
+ * <P>
+ *
+ * @author thomask
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class Logger implements ILogger {
+
+ protected static Logger mLogger = new Logger();
+ protected ILogQueue mLogQueue = null;
+ protected Hashtable mFactories = new Hashtable();
+
+ /**
+ * Constructs a generic logger, and registers a list
+ * of resident event factories.
+ */
+ public Logger() {
+ mLogQueue = LogSubsystem.getLogQueue();
+
+ // register standard event factories
+ register(EV_AUDIT, new AuditEventFactory());
+ register(EV_SYSTEM, new SystemEventFactory());
+ register(EV_SIGNED_AUDIT, new SignedAuditEventFactory());
+ }
+
+ /**
+ * get default single global logger
+ */
+ static public Logger getLogger() {
+ return mLogger;
+ }
+
+ /**
+ * Retrieves the associated log queue.
+ */
+ public ILogQueue getLogQueue() {
+ return mLogQueue;
+ }
+
+ /**
+ * Registers log factory.
+ * @param evtClass the event class name: ILogger.EV_SYSTEM or ILogger.EV_AUDIT
+ * @param f the event factory name
+ */
+ public void register(int evtClass, ILogEventFactory f) {
+ mFactories.put(Integer.toString(evtClass), f);
+ }
+
+ //************** default level ****************
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ */
+ public void log(int evtClass, int source, String msg) {
+ log(evtClass, null, source, ILogger.LL_INFO, msg, null);
+ }
+
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ */
+ public void log(int evtClass, Properties props, int source, String msg) {
+ log(evtClass, props, source, ILogger.LL_INFO, msg, null);
+ }
+
+ //************** no param ****************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ */
+ public void log(int evtClass, int source, int level, String msg) {
+ log(evtClass, null, source, level, msg, null);
+ }
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg) {
+ log(evtClass, props, source, level, msg, null);
+ }
+
+ //********************* one param **********************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ */
+ public void log(int evtClass, int source, int level, String msg, Object param) {
+ log(evtClass, null, source, level, msg, param);
+ }
+
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ */
+ public void log(int evtClass, Properties props, int source, String msg, Object param) {
+ log(evtClass, props, source, ILogger.LL_INFO, msg, param);
+ }
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg,
+ Object param) {
+ Object o[] = new Object[1];
+
+ o[0] = param;
+ log(evtClass, props, source, level, msg, o);
+ }
+
+ //******************* multiple param **************************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param params the parameters in the detail message
+ */
+ public void log(int evtClass, int source, int level, String msg,
+ Object params[]) {
+ log(evtClass, null, source, level, msg, params);
+ }
+
+ //*************** the real implementation *****************
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param params the parameters in the detail message
+ */
+ public void log(int evtClass, Properties prop, int source, int level, String msg,
+ Object params[]) {
+ mLogQueue.log(create(evtClass, prop, source, level, msg, params, ILogger.L_SINGLELINE));
+ }
+
+ //******************** multiline log *************************
+ //************** default level ****************
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, int source, String msg, boolean multiline) {
+ log(evtClass, null, source, ILogger.LL_INFO, msg, null, multiline);
+ }
+
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, Properties props, int source, String msg, boolean multiline) {
+ log(evtClass, props, source, ILogger.LL_INFO, msg, null, multiline);
+ }
+
+ //************** no param ****************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, int source, int level, String msg, boolean multiline) {
+ log(evtClass, null, source, level, msg, null, multiline);
+ }
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg, boolean multiline) {
+ log(evtClass, props, source, level, msg, null, multiline);
+ }
+
+ //********************* one param **********************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, int source, int level, String msg, Object param, boolean multiline) {
+ log(evtClass, null, source, level, msg, param, multiline);
+ }
+
+ /**
+ * Logs an event using default log level: ILogger.LL_INFO
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, Properties props, int source, String msg, Object param, boolean multiline) {
+ log(evtClass, props, source, ILogger.LL_INFO, msg, param, multiline);
+ }
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param param the parameter in the detail message
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, Properties props, int source, int level, String msg,
+ Object param, boolean multiline) {
+ Object o[] = new Object[1];
+
+ o[0] = param;
+ log(evtClass, props, source, level, msg, o, multiline);
+ }
+
+ //******************* multiple param **************************
+
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param params the parameters in the detail message
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, int source, int level, String msg,
+ Object params[], boolean multiline) {
+ log(evtClass, null, source, level, msg, params, multiline);
+ }
+
+ //*************** the real implementation *****************
+ /**
+ * Logs an event to the log queue.
+ *
+ * @param evtClass What kind of event it is: EV_AUDIT or EV_SYSTEM.
+ * @param props the resource bundle used for the detailed message
+ * @param source the source of the log event
+ * @param level the level of the log event
+ * @param msg the one line detail message to be logged
+ * @param params the parameters in the detail message
+ * @param multiline true if the message has more than one line, otherwise false
+ */
+ public void log(int evtClass, Properties prop, int source, int level, String msg,
+ Object params[], boolean multiline) {
+ mLogQueue.log(create(evtClass, prop, source, level, msg, params, multiline));
+ }
+
+ //******************** end multiline log *************************
+
+
+ /**
+ * Creates generic log event. If required, we can recycle
+ * events here.
+ */
+ //XXXXXXXXXXX prop is out dated!!!! XXXXXXXXXXXXXXX
+ public ILogEvent create(int evtClass, Properties prop, int source, int level,
+ String msg, Object params[], boolean multiline) {
+ ILogEventFactory f = (ILogEventFactory) mFactories.get(
+ Integer.toString(evtClass));
+
+ if (f == null)
+ return null;
+ return f.create(evtClass, prop, source, level, multiline, msg, params);
+ }
+
+ /**
+ * Notifies logger to reuse the event. This framework
+ * opens up possibility to reuse event.
+ * @param event a log event
+ */
+ public void release(ILogEvent event) {
+ // do nothing for now.
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java b/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java
new file mode 100644
index 000000000..5faa0baba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java
@@ -0,0 +1,124 @@
+// --- 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.cmscore.logging;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A log event object for handling system messages
+ * <P>
+ *
+ * @author mikep
+ * @author mzhao
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class SignedAuditEventFactory implements ILogEventFactory {
+
+ /**
+ * List of supported properties.
+ */
+ public static final String PROP_BUNDLE = "bundleName";
+
+ /**
+ * Constructs a system event factory.
+ */
+ public SignedAuditEventFactory() {
+ }
+
+ /**
+ * Creates an log event.
+ *
+ * @param evtClass the event type
+ * @param prop the resource bundle
+ * @param source the subsystem ID who creates the log event
+ * @param level the severity of the log event
+ * @param multiline the log message has more than one line or not
+ * @param msg the detail message of the log
+ * @param params the parameters in the detail log message
+
+ */
+ public ILogEvent create(int evtClass, Properties prop, int source,
+ int level, boolean multiline, String msg, Object params[]) {
+ if (evtClass != ILogger.EV_SIGNED_AUDIT)
+ return null;
+
+ String message = null;
+ // assume msg format <type=...>:message
+ String typeMessage = msg.trim();
+ String eventType = null;
+ int typeBegin = typeMessage.indexOf("<type=");
+
+ if (typeBegin != -1) {
+ // type is specified
+ int colon = typeMessage.indexOf(">:");
+
+ eventType = typeMessage.substring(typeBegin + 6, colon);
+ message = typeMessage.substring(colon + 2);
+ Debug.trace("SignedAuditEventFactory: create() message=" + message + "\n");
+
+ } else {
+ // no type specified
+ message = msg;
+ }
+
+ SignedAuditEvent event = new SignedAuditEvent(message.trim(), params);
+
+ if (eventType != null)
+ event.setEventType(eventType.trim());
+
+ event.setLevel(level);
+ event.setSource(source);
+ event.setMultiline(multiline);
+ setProperties(prop, event);
+
+ return event;
+ }
+
+ /**
+ * Set the resource bundle of the log event.
+ *
+ * @param prop the properties
+ * @param event the log event
+ */
+ protected void setProperties(Properties prop, IBundleLogEvent event) {
+ if (prop == null) {
+ event.setBundleName(null);
+ } else {
+ String bundleName = (String) prop.get(PROP_BUNDLE);
+
+ if (bundleName != null) {
+ event.setBundleName(bundleName);
+ }
+ }
+ }
+
+ /**
+ * Releases an log event.
+ *
+ * @param e the log event
+ */
+ public void release(ILogEvent e) {
+ // do nothing
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java b/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java
new file mode 100644
index 000000000..0bb99fb5b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java
@@ -0,0 +1,47 @@
+// --- 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.cmscore.logging;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * A class represents certificate server logger
+ * implementation.
+ * <P>
+ *
+ * @author thomask
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class SignedAuditLogger extends Logger {
+
+ /**
+ * Constructs a generic logger, and registers a list
+ * of resident event factories.
+ */
+ public SignedAuditLogger() {
+ super();
+ register(EV_SIGNED_AUDIT, new SignedAuditEventFactory());
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java b/pki/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java
new file mode 100644
index 000000000..4e5131311
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java
@@ -0,0 +1,98 @@
+// --- 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.cmscore.logging;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * A log event object for handling system messages
+ * <P>
+ *
+ * @author mikep
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class SystemEventFactory implements ILogEventFactory {
+
+ /**
+ * List of supported properties.
+ */
+ public static final String PROP_BUNDLE = "bundleName";
+
+ /**
+ * Constructs a system event factory.
+ */
+ public SystemEventFactory() {
+ }
+
+ /**
+ * Creates an log event.
+ *
+ * @param evtClass the event type
+ * @param prop the resource bundle
+ * @param source the subsystem ID who creates the log event
+ * @param level the severity of the log event
+ * @param multiline the log message has more than one line or not
+ * @param msg the detail message of the log
+ * @param params the parameters in the detail log message
+
+ */
+ public ILogEvent create(int evtClass, Properties prop, int source,
+ int level, boolean multiline, String msg, Object params[]) {
+ if (evtClass != ILogger.EV_SYSTEM)
+ return null;
+ SystemEvent event = new SystemEvent(msg, params);
+
+ event.setLevel(level);
+ event.setSource(source);
+ event.setMultiline(multiline);
+ setProperties(prop, event);
+ return event;
+ }
+
+ /**
+ * Set the resource bundle of the log event.
+ *
+ * @param prop the properties
+ * @param event the log event
+ */
+ protected void setProperties(Properties prop, IBundleLogEvent event) {
+ if (prop == null) {
+ event.setBundleName(null);
+ } else {
+ String bundleName = (String) prop.get(PROP_BUNDLE);
+
+ if (bundleName != null) {
+ event.setBundleName(bundleName);
+ }
+ }
+ }
+
+ /**
+ * Releases an log event.
+ *
+ * @param e the log event
+ */
+ public void release(ILogEvent e) {
+ // do nothing
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java b/pki/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java
new file mode 100644
index 000000000..b04186c3a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java
@@ -0,0 +1,250 @@
+// --- 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.cmscore.notification;
+
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.notification.*;
+import java.util.*;
+import java.lang.*;
+
+
+/**
+ * formulates the final email. Escape character '\' is understood.
+ * '$' is used preceeding a token name. A token name should not be a
+ * substring of any other token name
+ * <p>
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class EmailFormProcessor implements IEmailFormProcessor {
+
+ protected final static String TOK_PREFIX = "$";
+ protected final static String TOK_ESC = "\\";
+ protected final static char TOK_END = ' ';
+ protected final static String TOK_VALUE_UNKNOWN = "VALUE UNKNOWN";
+ protected final static String TOK_TOKEN_UNKNOWN = "UNKNOWN TOKEN:";
+ protected ILogger mLogger = CMS.getLogger();
+
+ // stores all the available token keys; added so that we can
+ // parse strings to replace unresolvable token keys and replace
+ // them by the words "VALUE UNKNOWN"
+ protected static String[] token_keys = {
+ TOKEN_ID,
+ TOKEN_SERIAL_NUM,
+ TOKEN_HTTP_HOST,
+ TOKEN_HTTP_PORT,
+ TOKEN_ISSUER_DN,
+ TOKEN_SUBJECT_DN,
+ TOKEN_REQUESTOR_EMAIL,
+ TOKEN_CERT_TYPE,
+ TOKEN_REQUEST_TYPE,
+ TOKEN_STATUS,
+ TOKEN_NOT_AFTER,
+ TOKEN_NOT_BEFORE,
+ TOKEN_SENDER_EMAIL,
+ TOKEN_RECIPIENT_EMAIL,
+ TOKEN_SUMMARY_ITEM_LIST,
+ TOKEN_SUMMARY_TOTAL_NUM,
+ TOKEN_SUMMARY_SUCCESS_NUM,
+ TOKEN_SUMMARY_FAILURE_NUM,
+ TOKEN_EXECUTION_TIME
+ };
+
+ // stores the eventual content of the email
+ Vector mContent = new Vector();
+ Hashtable mTok2vals = null;
+
+ public EmailFormProcessor() {
+ }
+
+ /*
+ * takes the form template, parse and replace all $tokens with the
+ * right values. It handles escape character '\'
+ * @param form The locale specific form template,
+ * @param tok2vals a hashtable containing one to one mapping
+ * from $tokens used by the admins in the form template to the real
+ * values corresponding to the $tokens
+ * @return mail content
+ */
+ public String getEmailContent(String form,
+ Hashtable tok2vals) {
+ mTok2vals = tok2vals;
+
+ if (form == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NULL"));
+ return null;
+ }
+
+ if (mTok2vals == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TOKEN_NULL"));
+ return null;
+ }
+
+ /**
+ * first, take care of the escape characters '\'
+ */
+ StringTokenizer es = new StringTokenizer(form, TOK_ESC);
+
+ if (es.hasMoreTokens() && !form.startsWith(TOK_ESC)) {
+ dollarProcess(es.nextToken());
+ }
+
+ // rest of them start with '\'
+ while (es.hasMoreTokens()) {
+ String t = es.nextToken();
+
+ // put first character (escaped char) in mContent
+ char c = t.charAt(0);
+
+ Character ch = Character.valueOf(c);
+
+ mContent.add(ch.toString());
+
+ // process the rest for $tokens
+ String r = t.substring(1);
+
+ dollarProcess(r);
+ }
+
+ return formContent(mContent);
+ }
+
+ private void dollarProcess(String sub) {
+ StringTokenizer st = new StringTokenizer(sub, TOK_PREFIX);
+
+ // if first token is not a $token, put in mContent as is
+ if (st.hasMoreTokens() && !sub.startsWith(TOK_PREFIX)) {
+ String a = st.nextToken();
+
+ mContent.add(a);
+ }
+
+ /*
+ * all of the string tokens below begin with a '$'
+ * match it one by one with the mTok2vals table
+ */
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+
+ /*
+ * We don't know when a token ends. Compare with every
+ * token in the table for the first match. Which means, a
+ * token name should not be a substring of any token name
+ */
+ boolean matched = false;
+ String tok = null;
+
+ for (Enumeration e = mTok2vals.keys(); e.hasMoreElements();) {
+ // get key
+ tok = (String) e.nextElement();
+
+ // compare key with $token
+ if (t.startsWith(tok)) {
+ // match, put val in mContent
+ Object o = mTok2vals.get(tok);
+
+ if (o != null) {
+ String s = (String) o;
+
+ if (!s.equals("")) {
+ mContent.add(o);
+ } else {
+ break;
+ }
+ } else { // no value, bail out
+ break;
+ }
+
+ // now, put the rest of the non-token string in mContent
+ if (t.length() != tok.length()) {
+ mContent.add(t.substring(tok.length()));
+ }
+
+ matched = true;
+
+ // replaced! bail out.
+ break;
+ }
+ }
+
+ if (!matched) {
+ boolean keyFound = false;
+
+ // no match, put the token back, as is
+ // -- for bug 382162, don't remove the following line, in
+ // case John changes his mind for the better
+ // mContent.add(TOK_PREFIX+t);
+ int tl = token_keys.length;
+
+ for (int i = 0; i < token_keys.length; i++) {
+ if (t.startsWith(token_keys[i])) {
+ // match, replace it with the TOK_VALUE_UNKNOWN
+ mContent.add(TOK_VALUE_UNKNOWN);
+
+ // now, put the rest of the non-token string
+ // in mContent
+ if (t.length() != token_keys[i].length()) {
+ mContent.add(t.substring(token_keys[i].length()));
+ }
+ keyFound = true;
+ break;
+ }
+ // keep looking
+ }
+ if (keyFound == false) {
+ mContent.add(TOK_TOKEN_UNKNOWN + TOK_PREFIX + t);
+ }
+ }
+ }
+ }
+
+ /**
+ * takes a vector of strings and concatenate them
+ */
+ public String formContent(Vector vec) {
+ String content = null;
+
+ Enumeration e = vec.elements();
+
+ // initialize content with first element
+ if (e.hasMoreElements()) {
+ content = (String) e.nextElement();
+ }
+
+ while (e.hasMoreElements()) {
+ String v = (String) e.nextElement();
+
+ content += v;
+ }
+
+ return content;
+ }
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "EmailFormProcessor: " + msg);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java b/pki/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java
new file mode 100644
index 000000000..5f053c297
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java
@@ -0,0 +1,86 @@
+// --- 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.cmscore.notification;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.notification.*;
+import java.util.*;
+
+
+/**
+ * Email resolver keys as input to email resolvers
+ * <P>
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class EmailResolverKeys implements IEmailResolverKeys {
+ private Hashtable mKeys = null;
+
+ public EmailResolverKeys() {
+ mKeys = new Hashtable();
+ }
+
+ /**
+ * sets a key with key name and the key
+ * @param name key name
+ * @param key key
+ * @exception com.netscape.certsrv.base.EBaseException NullPointerException
+ */
+ public void set(String name, Object key)throws EBaseException {
+ try {
+ mKeys.put(name, key);
+ } catch (NullPointerException e) {
+ System.out.println(e.toString());
+ throw new EBaseException("EmailResolverKeys.set()");
+ }
+ }
+
+ /**
+ * returns the key to which the specified name is mapped in this
+ * key set
+ * @param name key name
+ * @return the named email resolver key
+ */
+ public Object get(String name) {
+ return ((Object) mKeys.get(name));
+ }
+
+ /**
+ * removes the name and its corresponding key from this
+ * key set. This method does nothing if the named
+ * key is not in the key set.
+ * @param name key name
+ */
+ public void delete(String name) {
+ mKeys.remove(name);
+ }
+
+ /**
+ * returns an enumeration of the keys in this key
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ * @return an enumeration of the values in this key set
+ * @see java.util.Enumeration
+ */
+ public Enumeration getElements() {
+ return (mKeys.elements());
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java b/pki/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java
new file mode 100644
index 000000000..483426414
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java
@@ -0,0 +1,185 @@
+// --- 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.cmscore.notification;
+
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * Files to be processed and returned to the requested parties. It
+ * is a template with $tokens to be used by the form/template processor.
+ *
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+
+public class EmailTemplate implements IEmailTemplate {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ /* private variables */
+ private String mTemplateFile = new String();
+ private ILogger mLogger = CMS.getLogger();
+
+ /* public vaiables */
+ public String mFileContents;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Default Constructor
+ *
+ * @param templateFile File name of the template including the full path and
+ * file extension
+ */
+ public EmailTemplate(String templatePath) {
+ mTemplateFile = templatePath;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /*
+ * Load the template from the file
+ *
+ * @return true if successful
+ */
+ public boolean init() {
+
+ File template = new File(mTemplateFile);
+
+ /* check if file exists and is accessible */
+ if ((!template.exists()) || (!template.canRead()) || (template.isDirectory())) {
+ String error = "Template: " + mTemplateFile + " does not exist or invalid";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NOT_EXIST"));
+ return false;
+ }
+
+ /* create input stream */
+ FileReader input;
+
+ try {
+ input = new FileReader(template);
+ } catch (FileNotFoundException e) {
+ String error = "Template: " + mTemplateFile + " not found";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NOT_FOUND"));
+
+ return false;
+ }
+
+ /* load template */
+ mFileContents = loadFile(input);
+ if (mFileContents == null) {
+ String error = "Template: Error loading file into string";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_LOAD_ERROR"));
+ return false;
+ }
+
+ // close the stream
+ try {
+ input.close();
+ } catch (IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return Template Name in string form
+ */
+ public String getTemplateName() {
+ return mTemplateFile;
+ }
+
+ /**
+ * @return true if template is an html file, false otherwise
+ */
+ public boolean isHTML() {
+ if (mTemplateFile.endsWith(".html") ||
+ mTemplateFile.endsWith(".HTML") ||
+ mTemplateFile.endsWith(".htm") ||
+ mTemplateFile.endsWith(".HTM"))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * @return Content of the template
+ */
+ public String toString() {
+ return mFileContents;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /* load file into string */
+ private String loadFile(FileReader input) {
+
+ BufferedReader in = new BufferedReader(input);
+ StringBuffer buf = new StringBuffer();
+ String line;
+
+ try {
+ while ((line = in.readLine()) != null) {
+ buf.append(line);
+ buf.append("\n");
+ }
+ } catch (IOException e) {
+ String error = "Template: Error loading file";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_LOADING"));
+ return null;
+ }
+
+ return buf.toString();
+ }
+
+ public int length() {
+ return (mFileContents == null) ? 0 : mFileContents.length();
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java b/pki/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java
new file mode 100644
index 000000000..28f0e364c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java
@@ -0,0 +1,151 @@
+// --- 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.cmscore.notification;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.apps.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * An email resolver that first checks the request email, if none,
+ * then follows by checking the subjectDN of the certificate
+ * <p>
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class ReqCertEmailResolver implements IEmailResolver {
+ private ILogger mLogger = CMS.getLogger();
+
+ public static final String KEY_REQUEST = "request";
+ public static final String KEY_CERT = "cert";
+ // required keys for this resolver to figure out the email address
+ // protected static String[] mRequiredKeys = {KEY_REQUEST, KEY_CERT};
+
+ public ReqCertEmailResolver() {
+ }
+
+ /**
+ * returns an email address by using the resolver keys. The
+ * return value can possibly be null
+ * @param keys list of keys used for resolving the email address
+ */
+ public String getEmail(IEmailResolverKeys keys)
+ throws EBaseException, ENotificationException {
+ IRequest req = (IRequest) keys.get(KEY_REQUEST);
+
+ String mEmail = null;
+
+ if (req != null) {
+ mEmail = req.getExtDataInString(IRequest.HTTP_PARAMS,
+ "csrRequestorEmail");
+ if (mEmail == null) {
+ String mail = req.getExtDataInString("requestor_email");
+ log(ILogger.LL_INFO, "REQUESTOR_EMAIL = " + mail);
+ if (mail != null && !mail.equals(""))
+ return mail;
+ } else {
+ if (!mEmail.equals(""))
+ return mEmail;
+ }
+ } else {
+ log(ILogger.LL_INFO, "request null in keys");
+ }
+
+ X509Certificate cert = (X509Certificate) keys.get(KEY_CERT);
+
+ X500Name subjectDN = null;
+
+ if (cert != null) {
+ subjectDN =
+ (X500Name) cert.getSubjectDN();
+
+ try {
+ mEmail = subjectDN.getEmail();
+ } catch (IOException e) {
+ System.out.println("X500Name getEmail failed");
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ subjectDN.toString()));
+ }
+ } else {
+ log(ILogger.LL_INFO, "cert null in keys");
+ }
+
+ // log it
+ if (mEmail == null) {
+ if (cert != null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_EMAIL", subjectDN.toString()));
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1 for " +
+ subjectDN.toString());
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+ } else if (req != null) {
+ log(ILogger.LL_FAILURE,
+ "no email resolved for request id =" +
+ req.getRequestId().toString());
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1 for request id =" +
+ req.getRequestId().toString());
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "requestId= " + req.getRequestId().toString()));
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_EMAIL_REQUEST"));
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1. No request id or cert info found");
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ ": No request id or cert info found"));
+ }
+ } else {
+ log(ILogger.LL_INFO, "email resolved: " + mEmail);
+ }
+
+ return mEmail;
+ }
+
+ /**
+ * Returns array of required keys for this email resolver
+ * @return Array of required keys.
+ */
+
+ /* public String[] getRequiredKeys() {
+ return mRequiredKeys;
+ }*/
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "ReqCertEmailResolver: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java b/pki/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java
new file mode 100644
index 000000000..440e62e85
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java
@@ -0,0 +1,268 @@
+// --- 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.cmscore.notification;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.notification.*;
+import java.util.Enumeration;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+
+
+/**
+ * An email resolver that first checks the request email, if none,
+ * then follows by checking the subjectDN of the certificate, if none,
+ * then follows by checking the subjectalternatename extension
+ * <p>
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class ReqCertSANameEmailResolver implements IEmailResolver {
+ private ILogger mLogger = CMS.getLogger();
+
+ public static final String KEY_REQUEST = IEmailResolverKeys.KEY_REQUEST;
+ public static final String KEY_CERT = IEmailResolverKeys.KEY_CERT;
+
+ // required keys for this resolver to figure out the email address
+ // protected static String[] mRequiredKeys = {KEY_REQUEST, KEY_CERT};
+
+ public ReqCertSANameEmailResolver() {
+ }
+
+ /**
+ * returns an email address by using the resolver keys. The
+ * return value can possibly be null
+ * @param keys list of keys used for resolving the email address
+ */
+ public String getEmail(IEmailResolverKeys keys)
+ throws EBaseException, ENotificationException {
+ IRequest req = (IRequest) keys.get(KEY_REQUEST);
+
+ String mEmail = null;
+
+ if (req != null) {
+ mEmail = req.getExtDataInString(IRequest.HTTP_PARAMS,
+ IRequest.REQUESTOR_EMAIL);
+ if (mEmail == null) {
+ String mail = req.getExtDataInString("requestor_email");
+ log(ILogger.LL_INFO, "REQUESTOR_EMAIL = " + mail);
+ if (mail != null && !mail.equals(""))
+ return mail;
+ } else {
+ if (!mEmail.equals("")) {
+ log(ILogger.LL_INFO, "REQUESTOR_EMAIL = " + mEmail);
+ return mEmail;
+ }
+ log(ILogger.LL_INFO, "REQUESTOR_EMAIL is null ");
+ }
+ } else {
+ log(ILogger.LL_INFO, "request null in keys");
+ }
+ Object request = keys.get(KEY_CERT);
+ X509Certificate cert = null;
+
+ if (request instanceof RevokedCertImpl) {
+ RevokedCertImpl revCert = (RevokedCertImpl) request;
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ ICertificateRepository certDB = ca.getCertificateRepository();
+
+ cert = certDB.getX509Certificate(revCert.getSerialNumber());
+ }else
+ cert = (X509Certificate) request;
+
+ X500Name subjectDN = null;
+
+ if (cert != null) {
+ subjectDN =
+ (X500Name) cert.getSubjectDN();
+
+ try {
+ mEmail = subjectDN.getEmail();
+ if (mEmail != null) {
+ if (!mEmail.equals("")) {
+ log(ILogger.LL_INFO, "cert subjectDN E=" +
+ mEmail);
+ }
+ } else {
+ log(ILogger.LL_INFO, "no E component in subjectDN ");
+ }
+ } catch (IOException e) {
+ System.out.println("X500Name getEmail failed");
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ subjectDN.toString()));
+ }
+
+ // try subjectalternatename
+ if (mEmail == null) {
+ X509CertInfo certInfo = null;
+
+ CMS.debug("about to try subjectalternatename");
+ try {
+ certInfo = (X509CertInfo)
+ ((X509CertImpl) cert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_CERTINFO"));
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+ }
+
+ CertificateExtensions exts;
+
+ try {
+ exts = (CertificateExtensions)
+ certInfo.get(CertificateExtensions.NAME);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_GET_EXT", e.toString()));
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_GET_EXT", e.toString()));
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+ }
+
+ if (exts != null) {
+ SubjectAlternativeNameExtension ext;
+
+ try {
+ ext =
+ (SubjectAlternativeNameExtension)
+ exts.get(SubjectAlternativeNameExtension.NAME);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_GET_EXT", e.toString()));
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+
+ }
+
+ try {
+ if (ext != null) {
+ GeneralNames gn =
+ (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ Enumeration e = gn.elements();
+
+ while (e.hasMoreElements()) {
+ Object g = (Object) e.nextElement();
+
+ GeneralName gni =
+ (GeneralName) g;
+
+ if (gni.getType() ==
+ GeneralNameInterface.NAME_RFC822) {
+ CMS.debug("got an subjectalternatename email");
+
+ String nameString = g.toString();
+
+ // "RFC822Name: " + name
+ mEmail =
+ nameString.substring(nameString.indexOf(' ') + 1);
+ log(ILogger.LL_INFO,
+ "subjectalternatename email used:" +
+ mEmail);
+
+ break;
+ } else {
+ CMS.debug("not an subjectalternatename email");
+ }
+ }
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_SUBJECTALTNAME"));
+ }
+ }
+ }
+ } else {
+ log(ILogger.LL_INFO, "cert null in keys");
+ }
+
+ // log it
+ if (mEmail == null) {
+ if (cert != null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_EMAIL", subjectDN.toString()));
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1 for " +
+ subjectDN.toString());
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "subjectDN= " + subjectDN.toString()));
+ } else if (req != null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_EMAIL_ID",
+ req.getRequestId().toString()));
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1 for request id =" +
+ req.getRequestId().toString());
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ "requestId= " + req.getRequestId().toString()));
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_NOTIFY_NO_EMAIL_REQUEST"));
+ CMS.debug(
+ "no email resolved, throwing NotificationResources.EMAIL_RESOLVE_FAILED_1. No request id or cert info found");
+ throw new ENotificationException (
+ CMS.getUserMessage("CMS_NOTIFICATION_EMAIL_RESOLVE_FAILED",
+ ": No request id or cert info found"));
+ }
+ } else {
+ log(ILogger.LL_INFO, "email resolved: " + mEmail);
+ }
+
+ return mEmail;
+ }
+
+ /**
+ * Returns array of required keys for this email resolver
+ * @return Array of required keys.
+ */
+
+ /* public String[] getRequiredKeys() {
+ return mRequiredKeys;
+ }*/
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "ReqCertSANameEmailResolver: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/AndExpression.java b/pki/base/common/src/com/netscape/cmscore/policy/AndExpression.java
new file mode 100644
index 000000000..fb3134ffa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/AndExpression.java
@@ -0,0 +1,59 @@
+// --- 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.cmscore.policy;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * This class represents an expression of the form
+ * <var1 op val1 AND var2 op va2>.
+ *
+ * Expressions are used as predicates for policy selection.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class AndExpression implements IExpression {
+ private IExpression mExp1;
+ private IExpression mExp2;
+ public AndExpression(IExpression exp1, IExpression exp2) {
+ mExp1 = exp1;
+ mExp2 = exp2;
+ }
+
+ public boolean evaluate(IRequest req)
+ throws EPolicyException {
+ // If an expression is missing we assume applicability.
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(req) && mExp2.evaluate(req);
+ else if (mExp1 == null)
+ return mExp2.evaluate(req);
+ else // (if mExp2 == null)
+ return mExp1.evaluate(req);
+ }
+
+ public String toString() {
+ return mExp1.toString() + " AND " + mExp2.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java b/pki/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java
new file mode 100644
index 000000000..7a8ab4342
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java
@@ -0,0 +1,672 @@
+// --- 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.cmscore.policy;
+
+
+import java.util.*;
+import java.io.*;
+import java.util.Vector;
+import java.util.Enumeration;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ */
+public class GeneralNameUtil implements IGeneralNameUtil {
+
+ private static final String DOT = ".";
+
+ /**
+ * GeneralName can be used in the context of Constraints. Examples
+ * are NameConstraints, CertificateScopeOfUse extensions. In such
+ * cases, IPAddress may contain netmask component.
+ */
+ static public GeneralName
+ form_GeneralNameAsConstraints(String generalNameChoice, String value)
+ throws EBaseException {
+ try {
+ if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_IPADDRESS)) {
+ StringTokenizer st = new StringTokenizer(value, ",");
+ String ip = st.nextToken();
+ String netmask = null;
+
+ if (st.hasMoreTokens()) {
+ netmask = st.nextToken();
+ }
+ return new GeneralName(new IPAddressName(ip, netmask));
+ } else {
+ return form_GeneralName(generalNameChoice, value);
+ }
+ } catch (InvalidIPAddressException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_IP_ADDR", value));
+ }
+ }
+
+ /**
+ * Form a General Name from a General Name choice and value.
+ * The General Name choice must be one of the General Name Choice Strings
+ * defined in this class.
+ * @param generalNameChoice General Name choice. Must be one of the General
+ * Name choices defined in this class.
+ * @param value String value of the general name to form.
+ */
+ static public GeneralName
+ form_GeneralName(String generalNameChoice, String value)
+ throws EBaseException {
+ GeneralNameInterface generalNameI = null;
+ DerValue derVal = null;
+ GeneralName generalName = null;
+
+ try {
+ if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_OTHERNAME)) {
+ byte[] val = com.netscape.osutil.OSUtil.AtoB(value);
+
+ derVal = new DerValue(new ByteArrayInputStream(val));
+ Debug.trace("otherName formed");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_RFC822NAME)) {
+ generalNameI = new RFC822Name(value);
+ Debug.trace("rfc822Name formed ");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_DNSNAME)) {
+ generalNameI = new DNSName(value);
+ Debug.trace("dnsName formed");
+ } /** not supported -- no sun class
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_X400ADDRESS)) {
+ }
+ **/ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_DIRECTORYNAME)) {
+ generalNameI = new X500Name(value);
+ Debug.trace("X500Name formed");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_EDIPARTYNAME)) {
+ generalNameI = new EDIPartyName(value);
+ Debug.trace("ediPartyName formed");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_URL)) {
+ generalNameI = new URIName(value);
+ Debug.trace("url formed");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_IPADDRESS)) {
+ generalNameI = new IPAddressName(value);
+ Debug.trace("ipaddress formed");
+ } else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_REGISTEREDID)) {
+ ObjectIdentifier oid;
+
+ try {
+ oid = new ObjectIdentifier(value);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_VALUE_FOR_TYPE",
+ generalNameChoice,
+ "value must be a valid OID in the form n.n.n.n"));
+ }
+ generalNameI = new OIDName(oid);
+ Debug.trace("oidname formed");
+ } else {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ new String[] {
+ PROP_GENNAME_CHOICE,
+ "value must be one of: " +
+ GENNAME_CHOICE_OTHERNAME + ", " +
+ GENNAME_CHOICE_RFC822NAME + ", " +
+ GENNAME_CHOICE_DNSNAME + ", " +
+
+ /* GENNAME_CHOICE_X400ADDRESS +", "+ */
+ GENNAME_CHOICE_DIRECTORYNAME + ", " +
+ GENNAME_CHOICE_EDIPARTYNAME + ", " +
+ GENNAME_CHOICE_URL + ", " +
+ GENNAME_CHOICE_IPADDRESS + ", or " +
+ GENNAME_CHOICE_REGISTEREDID + "."
+ }
+ ));
+ }
+ } catch (IOException e) {
+ Debug.printStackTrace(e);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_VALUE_FOR_TYPE",
+ generalNameChoice, e.toString()));
+ } catch (InvalidIPAddressException e) {
+ Debug.printStackTrace(e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_IP_ADDR", value));
+ } catch (RuntimeException e) {
+ Debug.printStackTrace(e);
+ throw e;
+ }
+
+ try {
+ if (generalNameI != null)
+ generalName = new GeneralName(generalNameI);
+ else
+ generalName = new GeneralName(derVal);
+ Debug.trace("general name formed");
+ return generalName;
+ } catch (IOException e) {
+ Debug.printStackTrace(e);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", "Could not form GeneralName. Error: " + e));
+ }
+ }
+
+ /**
+ * Checks if given string is a valid General Name choice and returns
+ * the actual string that can be passed into form_GeneralName().
+ * @param generalNameChoice a General Name choice string.
+ * @return one of General Name choices defined in this class that can be
+ * passed into form_GeneralName().
+ */
+ static public String check_GeneralNameChoice(String generalNameChoice)
+ throws EBaseException {
+ String theGeneralNameChoice = null;
+
+ if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_OTHERNAME))
+ theGeneralNameChoice = GENNAME_CHOICE_OTHERNAME;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_RFC822NAME))
+ theGeneralNameChoice = GENNAME_CHOICE_RFC822NAME;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_DNSNAME))
+ theGeneralNameChoice = GENNAME_CHOICE_DNSNAME;
+
+ /* X400Address not supported.
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_X400ADDRESS))
+ theGeneralNameChoice = GENNAME_CHOICE_X400ADDRESS;
+ */
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_DIRECTORYNAME))
+ theGeneralNameChoice = GENNAME_CHOICE_DIRECTORYNAME;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_EDIPARTYNAME))
+ theGeneralNameChoice = GENNAME_CHOICE_EDIPARTYNAME;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_URL))
+ theGeneralNameChoice = GENNAME_CHOICE_URL;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_IPADDRESS))
+ theGeneralNameChoice = GENNAME_CHOICE_IPADDRESS;
+ else if (generalNameChoice.equalsIgnoreCase(GENNAME_CHOICE_REGISTEREDID))
+ theGeneralNameChoice = GENNAME_CHOICE_REGISTEREDID;
+ else {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ new String[] {
+ PROP_GENNAME_CHOICE + "=" + generalNameChoice,
+ "value must be one of: " +
+ GENNAME_CHOICE_OTHERNAME + ", " +
+ GENNAME_CHOICE_RFC822NAME + ", " +
+ GENNAME_CHOICE_DNSNAME + ", " +
+
+ /* GENNAME_CHOICE_X400ADDRESS +", "+ */
+ GENNAME_CHOICE_DIRECTORYNAME + ", " +
+ GENNAME_CHOICE_EDIPARTYNAME + ", " +
+ GENNAME_CHOICE_URL + ", " +
+ GENNAME_CHOICE_IPADDRESS + ", " +
+ GENNAME_CHOICE_REGISTEREDID + "."
+ }
+ ));
+ }
+ return theGeneralNameChoice;
+ }
+
+ static public class GeneralNamesConfig implements IGeneralNamesConfig {
+ public String mName = null; // substore name of config if any.
+ public GeneralNameConfig[] mGenNameConfigs = null;
+ public IConfigStore mConfig = null;
+ public boolean mIsValueConfigured = true;
+ public boolean mIsPolicyEnabled = true;
+ public int mDefNumGenNames = DEF_NUM_GENERALNAMES;
+ public GeneralNames mGeneralNames = null;
+
+ private String mNameDotGeneralName = mName + DOT + PROP_GENERALNAME;
+
+ public GeneralNamesConfig(
+ String name,
+ IConfigStore config,
+ boolean isValueConfigured,
+ boolean isPolicyEnabled)
+ throws EBaseException {
+ mIsValueConfigured = isValueConfigured;
+ mIsPolicyEnabled = isPolicyEnabled;
+ mName = name;
+ if (mName != null)
+ mNameDotGeneralName = mName + DOT + PROP_GENERALNAME;
+ else
+ mNameDotGeneralName = PROP_GENERALNAME;
+ mConfig = config;
+
+ int numGNs = mConfig.getInteger(PROP_NUM_GENERALNAMES);
+
+ if (numGNs < 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ new String[] {
+ PROP_NUM_GENERALNAMES + "=" + numGNs,
+ "value must be greater than or equal to 0."}
+ ));
+ }
+ mGenNameConfigs = new GeneralNameConfig[numGNs];
+ for (int i = 0; i < numGNs; i++) {
+ String storeName = mNameDotGeneralName + i;
+
+ mGenNameConfigs[i] =
+ newGeneralNameConfig(
+ storeName, mConfig.getSubStore(storeName),
+ mIsValueConfigured, mIsPolicyEnabled);
+ }
+
+ if (mIsValueConfigured && mIsPolicyEnabled) {
+ mGeneralNames = new GeneralNames();
+ for (int j = 0; j < numGNs; j++) {
+ mGeneralNames.addElement(mGenNameConfigs[j].mGeneralName);
+ }
+ }
+ }
+
+ public GeneralNames getGeneralNames() {
+ return mGeneralNames;
+ }
+
+ protected GeneralNameConfig newGeneralNameConfig(
+ String name, IConfigStore config,
+ boolean isValueConfigured, boolean isPolicyEnabled)
+ throws EBaseException {
+ return new GeneralNameConfig(
+ name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ public GeneralNameConfig[] getGenNameConfig() {
+ return (GeneralNameConfig[]) mGenNameConfigs.clone();
+ }
+
+ public int getNumGeneralNames() {
+ return mGenNameConfigs.length;
+ }
+
+ public IConfigStore getConfig() {
+ return mConfig;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public boolean isValueConfigured() {
+ return mIsValueConfigured;
+ }
+
+ public void setDefNumGenNames(int defNum) {
+ mDefNumGenNames = defNum;
+ }
+
+ public int getDefNumGenNames() {
+ return mDefNumGenNames;
+ }
+
+ /**
+ * adds params to default
+ */
+ public static void getDefaultParams(
+ String name, boolean isValueConfigured, Vector params) {
+ String nameDot = "";
+
+ if (name != null)
+ nameDot = name + DOT;
+ params.addElement(
+ nameDot + PROP_NUM_GENERALNAMES + '=' + DEF_NUM_GENERALNAMES);
+ for (int i = 0; i < DEF_NUM_GENERALNAMES; i++) {
+ GeneralNameConfig.getDefaultParams(
+ nameDot + PROP_GENERALNAME + i, isValueConfigured, params);
+ }
+ }
+
+ /**
+ * Get instance params.
+ */
+ public void getInstanceParams(Vector params) {
+ params.addElement(
+ PROP_NUM_GENERALNAMES + '=' + mGenNameConfigs.length);
+ for (int i = 0; i < mGenNameConfigs.length; i++) {
+ mGenNameConfigs[i].getInstanceParams(params);
+ }
+ }
+
+ /**
+ * Get extended plugin info.
+ */
+ public static void getExtendedPluginInfo(
+ String name, boolean isValueConfigured, Vector info) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ info.addElement(PROP_NUM_GENERALNAMES + ";" + NUM_GENERALNAMES_INFO);
+ for (int i = 0; i < DEF_NUM_GENERALNAMES; i++) {
+ GeneralNameConfig.getExtendedPluginInfo(
+ nameDot + PROP_GENERALNAME + i, isValueConfigured, info);
+ }
+ }
+
+ }
+
+
+ static public class GeneralNamesAsConstraintsConfig extends GeneralNamesConfig implements IGeneralNamesAsConstraintsConfig {
+ public GeneralNamesAsConstraintsConfig(
+ String name,
+ IConfigStore config,
+ boolean isValueConfigured,
+ boolean isPolicyEnabled)
+ throws EBaseException {
+ super(name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ protected GeneralNameConfig newGeneralNameConfig(
+ String name, IConfigStore config,
+ boolean isValueConfigured, boolean isPolicyEnabled)
+ throws EBaseException {
+ return new GeneralNameAsConstraintsConfig(name, config,
+ isValueConfigured, isPolicyEnabled);
+ }
+ }
+
+
+ /**
+ * convenience class for policies use.
+ */
+ static public class GeneralNameConfig implements IGeneralNameConfig {
+ public String mName = null;
+ public String mNameDot = null;
+ public IConfigStore mConfig = null;
+ public String mGenNameChoice = null;
+ public boolean mIsValueConfigured = true;
+ public String mValue = null; // used only if isValueConfigured
+ public GeneralName mGeneralName = null; // used only if isValueConfiged.
+ public boolean mIsPolicyEnabled = true;
+
+ public String mNameDotChoice = null;
+ public String mNameDotValue = null;
+
+ public GeneralNameConfig(
+ String name,
+ IConfigStore config,
+ boolean isValueConfigured,
+ boolean isPolicyEnabled)
+ throws EBaseException {
+ mIsValueConfigured = isValueConfigured;
+ mIsPolicyEnabled = isPolicyEnabled;
+ mName = name;
+ if (mName != null && mName.length() > 0) {
+ mNameDot = mName + DOT;
+ mNameDotChoice = mNameDot + PROP_GENNAME_CHOICE;
+ mNameDotValue = mNameDot + PROP_GENNAME_VALUE;
+ } else {
+ mNameDot = "";
+ mNameDotChoice = PROP_GENNAME_CHOICE;
+ mNameDotValue = PROP_GENNAME_VALUE;
+ }
+ mConfig = config;
+
+ // necessary to expand/shrink # general names from console.
+ if (mConfig.size() == 0) {
+ config.putString(mNameDotChoice, "");
+ if (mIsValueConfigured)
+ config.putString(mNameDotValue, "");
+ }
+
+ String choice = null;
+
+ if (mIsPolicyEnabled) {
+ choice = mConfig.getString(PROP_GENNAME_CHOICE);
+ mGenNameChoice = check_GeneralNameChoice(choice);
+ } else {
+ choice = mConfig.getString(PROP_GENNAME_CHOICE, "");
+ if (choice.length() > 0 && !choice.equals("null")) {
+ mGenNameChoice = check_GeneralNameChoice(choice);
+ }
+ }
+ if (mIsValueConfigured) {
+ if (mIsPolicyEnabled) {
+ mValue = mConfig.getString(PROP_GENNAME_VALUE);
+ mGeneralName = formGeneralName(mGenNameChoice, mValue);
+ } else {
+ mValue = mConfig.getString(PROP_GENNAME_VALUE, "");
+ if (mValue != null && mValue.length() > 0)
+ mGeneralName = formGeneralName(mGenNameChoice, mValue);
+ }
+ }
+ }
+
+ /**
+ * Form a general name from the value string.
+ */
+ public GeneralName formGeneralName(String value)
+ throws EBaseException {
+ return formGeneralName(mGenNameChoice, value);
+ }
+
+ public GeneralName formGeneralName(String choice, String value)
+ throws EBaseException {
+ return form_GeneralName(choice, value);
+ }
+
+ /**
+ * @return a vector of General names from a value that can be
+ * either a Vector of strings, string array or just a string.
+ * Returned Vector can be null if value is not of expected type.
+ */
+ public Vector formGeneralNames(Object value)
+ throws EBaseException {
+ Vector gns = new Vector();
+ GeneralName gn = null;
+
+ if (value instanceof String) {
+ if (((String) (value = ((String) value).trim())).length() > 0) {
+ gn = formGeneralName(mGenNameChoice, (String) value);
+ gns.addElement(gn);
+ }
+ } else if (value instanceof String[]) {
+ String[] vals = (String[]) value;
+
+ for (int i = 0; i < vals.length; i++) {
+ String val = vals[i].trim();
+
+ if (val != null && val.length() > 0) {
+ gn = formGeneralName(mGenNameChoice, val);
+ gns.addElement(gn);
+ }
+ }
+ } else if (value instanceof Vector) {
+ Vector vals = (Vector) value;
+
+ for (Enumeration n = vals.elements(); n.hasMoreElements();) {
+ Object val = n.nextElement();
+
+ if (val != null && (val instanceof String) &&
+ ((String) (val = ((String) val).trim())).length() > 0) {
+ gn = formGeneralName(mGenNameChoice, (String) val);
+ gns.addElement(gn);
+ }
+ }
+ }
+ return gns;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public IConfigStore getConfig() {
+ return mConfig;
+ }
+
+ public String getGenNameChoice() {
+ return mGenNameChoice;
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ /*
+ public GeneralNameInterface getGeneralName() {
+ return mGeneralName;
+ }
+
+ */
+ public boolean isValueConfigured() {
+ return mIsValueConfigured;
+ }
+
+ /**
+ * Get default params
+ */
+
+ public static void getDefaultParams(
+ String name, boolean isValueConfigured, Vector params) {
+ String nameDot = "";
+
+ if (name != null)
+ nameDot = name + ".";
+ Debug.trace("GeneralnameConfig getDefaultParams");
+ params.addElement(nameDot + PROP_GENNAME_CHOICE + "=");
+ if (isValueConfigured)
+ params.addElement(nameDot + PROP_GENNAME_VALUE + "=");
+ }
+
+ /**
+ * Get instance params
+ */
+ public void getInstanceParams(Vector params) {
+ String value = (mValue == null) ? "" : mValue;
+ String choice = (mGenNameChoice == null) ? "" : mGenNameChoice;
+
+ params.addElement(mNameDotChoice + "=" + choice);
+ if (mIsValueConfigured)
+ params.addElement(mNameDotValue + "=" + value);
+ }
+
+ /**
+ * Get extended plugin info
+ */
+ public static void getExtendedPluginInfo(
+ String name, boolean isValueConfigured, Vector info) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ info.addElement(
+ nameDot + PROP_GENNAME_CHOICE + ";" + GENNAME_CHOICE_INFO);
+ if (isValueConfigured)
+ info.addElement(
+ nameDot + PROP_GENNAME_VALUE + ";" + GENNAME_VALUE_INFO);
+ }
+ }
+
+
+ /**
+ * convenience class for policies use.
+ */
+ static public class GeneralNameAsConstraintsConfig extends GeneralNameConfig implements IGeneralNameAsConstraintsConfig {
+
+ public GeneralNameAsConstraintsConfig(
+ String name,
+ IConfigStore config,
+ boolean isValueConfigured,
+ boolean isPolicyEnabled)
+ throws EBaseException {
+ super(name, config, isValueConfigured, isPolicyEnabled);
+ }
+
+ public GeneralName getGeneralName() {
+ return mGeneralName;
+ }
+
+ /**
+ * Form a general name from the value string.
+ */
+ public GeneralName formGeneralName(String choice, String value)
+ throws EBaseException {
+ return form_GeneralNameAsConstraints(choice, value);
+ }
+ }
+
+
+ public static class SubjAltNameGN extends GeneralNameUtil.GeneralNameConfig implements ISubjAltNameConfig {
+ static final String REQUEST_ATTR_INFO =
+ "string;Request attribute name. " +
+ "The value of the request attribute will be used to form a " +
+ "General Name in the Subject Alternative Name extension.";
+
+ static final String PROP_REQUEST_ATTR = "requestAttr";
+
+ String mRequestAttr = null;
+ String mPfx = null;
+ String mAttr = null;
+
+ public SubjAltNameGN(
+ String name, IConfigStore config, boolean isPolicyEnabled)
+ throws EBaseException {
+ super(name, config, false, isPolicyEnabled);
+
+ mRequestAttr = mConfig.getString(PROP_REQUEST_ATTR, null);
+ if (mRequestAttr == null) {
+ mConfig.putString(mNameDot + PROP_REQUEST_ATTR, "");
+ mRequestAttr = "";
+ }
+ if (isPolicyEnabled && mRequestAttr.length() == 0) {
+ throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED",
+ mConfig.getName() + "." + PROP_REQUEST_ATTR));
+ }
+ int x = mRequestAttr.indexOf('.');
+
+ if (x == -1)
+ mAttr = mRequestAttr;
+ else {
+ mPfx = mRequestAttr.substring(0, x).trim();
+ mAttr = mRequestAttr.substring(x + 1).trim();
+ }
+ }
+
+ public String getPfx() {
+ return mPfx;
+ }
+
+ public String getAttr() {
+ return mAttr;
+ }
+
+ public void getInstanceParams(Vector params) {
+ params.addElement(mNameDot + PROP_REQUEST_ATTR + "=" + mRequestAttr);
+ super.getInstanceParams(params);
+ }
+
+ public static void getDefaultParams(String name, Vector params) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ params.addElement(nameDot + PROP_REQUEST_ATTR + "=");
+ GeneralNameUtil.GeneralNameConfig.getDefaultParams(name, false, params);
+ }
+
+ public static void getExtendedPluginInfo(String name, Vector params) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ params.addElement(nameDot + PROP_REQUEST_ATTR + ";" + REQUEST_ATTR_INFO);
+ GeneralNameUtil.GeneralNameConfig.getExtendedPluginInfo(name, false, params);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java b/pki/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java
new file mode 100644
index 000000000..63b28d995
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java
@@ -0,0 +1,1552 @@
+// --- 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.cmscore.policy;
+
+
+import java.util.*;
+import java.text.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.request.ARequestQueue;
+
+
+/**
+ * This is a Generic policy processor. The three main functions of
+ * this class are:
+ * 1. To initialize policies by reading policy configuration from the
+ * config file, and maintain 5 sets of policies - viz Enrollment,
+ * Renewal, Revocation and KeyRecovery and KeyArchival.
+ * 2. To apply the configured policies on the given request.
+ * 3. To enable policy listing/configuration via MCC console.
+ *
+ * Since the policy processor also implements the IPolicy interface
+ * the processor itself presents itself as one big policy to the
+ * request processor.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class GenericPolicyProcessor implements IPolicyProcessor {
+ protected IConfigStore mConfig = null;
+ protected IConfigStore mGlobalStore = null;
+ protected IAuthority mAuthority = null;
+
+ // Default System Policies
+ public final static String[] DEF_POLICIES =
+ {"com.netscape.cms.policy.constraints.ManualAuthentication"};
+
+ // Policies that can't be deleted nor disabled.
+ public final static Hashtable DEF_UNDELETABLE_POLICIES =
+ new Hashtable();
+
+ private String mId = "Policy";
+ private Vector mPolicyOrder = new Vector();
+ private Hashtable mImplTable = new Hashtable();
+ private Hashtable mInstanceTable = new Hashtable();
+ PolicySet mEnrollmentRules = new PolicySet("EnrollmentRules");
+ PolicySet mRenewalRules = new PolicySet("RenewalRules");
+ PolicySet mRevocationRules = new PolicySet("RevocationRules");
+ PolicySet mKeyRecoveryRules = new PolicySet("KeyRecoveryRules");
+ PolicySet mKeyArchivalRules = new PolicySet("KeyArchivalRules");
+ private String[] mSystemDefaults = null;
+ private boolean mInitSystemPolicies;
+
+ // A Table of persistent policies and their predicates.
+ // The predicates cannot be changed during configuration.
+ private Hashtable mUndeletablePolicies = null;
+
+ public GenericPolicyProcessor() {
+ mInitSystemPolicies = true; // CA & RA
+ }
+
+ public GenericPolicyProcessor(boolean initSystemPolicies) {
+ mInitSystemPolicies = initSystemPolicies; // KRA
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shuts down this subsystem.
+ * <P>
+ */
+ public void shutdown() {
+ }
+
+ public ISubsystem getAuthority() {
+ return mAuthority;
+ }
+
+ /**
+ * Returns the configuration store.
+ * <P>
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Initializes the PolicyProcessor
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration of this subsystem
+ * @exception EBaseException failed to initialize this Subsystem.
+ */
+ public synchronized void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // Debug.trace("GenericPolicyProcessor::init");
+ CMS.debug("GenericPolicyProcessor::init begins");
+ mAuthority = (IAuthority) owner;
+ mConfig = config;
+ mGlobalStore =
+ SubsystemRegistry.getInstance().get("MAIN").getConfigStore();
+
+ try {
+ IConfigStore configStore = CMS.getConfigStore();
+ String PKI_Subsystem = configStore.getString( "subsystem.0.id",
+ null );
+
+ // CMS 6.1 began utilizing the "Certificate Profiles" framework
+ // instead of the legacy "Certificate Policies" framework.
+ //
+ // Beginning with CS 8.1, to meet the Common Criteria evaluation
+ // performed on this version of the product, it was determined
+ // that this legacy "Certificate Policies" framework would be
+ // deprecated and disabled by default (see Bugzilla Bug #472597).
+ //
+ // NOTE: The "Certificate Policies" framework ONLY applied to
+ // to CA, KRA, and legacy RA (pre-CMS 7.0) subsystems.
+ //
+ if( PKI_Subsystem.trim().equalsIgnoreCase( "ca" ) ||
+ PKI_Subsystem.trim().equalsIgnoreCase( "kra" ) ) {
+ String policyStatus = PKI_Subsystem.trim().toLowerCase()
+ + "." + "Policy"
+ + "." + IPolicyProcessor.PROP_ENABLE;
+
+ if( configStore.getBoolean( policyStatus, true ) == true ) {
+ // NOTE: If "<subsystem>.Policy.enable=<boolean>" is
+ // missing, then the referenced instance existed
+ // prior to this name=value pair existing in its
+ // 'CS.cfg' file, and thus we err on the
+ // side that the user may still need to
+ // use the policy framework.
+ CMS.debug( "GenericPolicyProcessor::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is ENABLED" );
+ } else {
+ // CS 8.1 Default: <subsystem>.Policy.enable=false
+ CMS.debug( "GenericPolicyProcessor::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is DISABLED" );
+ return;
+ }
+ }
+ } catch( EBaseException e ) {
+ throw e;
+ }
+
+ // Initialize default policies system that would be
+ // present in the system always.
+ if (mInitSystemPolicies) {
+ initSystemPolicies(mConfig);
+ }
+
+ // Read listing of undeletable policies if any.
+ initUndeletablePolicies(mConfig);
+
+ // Read all registered policies first..
+ IConfigStore c;
+
+ c = config.getSubStore(PROP_IMPL);
+ Enumeration mImpls = c.getSubStoreNames();
+
+ while (mImpls.hasMoreElements()) {
+ String id = (String) mImpls.nextElement();
+
+ // The implementation id should be unique
+ if (mImplTable.containsKey(id))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DUPLICATE_IMPL_ID", id));
+
+ String clPath = c.getString(id + "." + PROP_CLASS);
+
+ // We should n't let the CatchAll policies to be configurable.
+ if (isSystemDefaultPolicy(clPath))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SYSTEM_POLICY_CONFIG_ERROR", clPath));
+
+ // Verify if the class is a valid implementation of
+ // IPolicyRule
+ try {
+ Object o = Class.forName(clPath).newInstance();
+
+ if (!(o instanceof IEnrollmentPolicy) &&
+ !(o instanceof IRenewalPolicy) &&
+ !(o instanceof IRevocationPolicy) &&
+ !(o instanceof IKeyRecoveryPolicy) &&
+ !(o instanceof IKeyArchivalPolicy))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", clPath));
+ } catch (EBaseException e) {
+ throw e;
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL",
+ id));
+ }
+
+ // Register the implementation.
+ RegisteredPolicy regPolicy =
+ new RegisteredPolicy(id, clPath);
+
+ mImplTable.put(id, regPolicy);
+ }
+
+ // Now read the priority ordering of rule configurations.
+ String policyOrder = config.getString(PROP_ORDER, null);
+
+ if (policyOrder == null) {
+ return;
+ // throw new EPolicyException(PolicyResources.NO_POLICY_ORDERING);
+ } else {
+ StringTokenizer tokens = new StringTokenizer(policyOrder, ",");
+
+ while (tokens.hasMoreTokens()) {
+ mPolicyOrder.addElement(tokens.nextToken().trim());
+ }
+ }
+
+ // Now Read Policy configurations and construct policy objects
+ int numPolicies = mPolicyOrder.size();
+ IConfigStore ruleStore = config.getSubStore(PROP_RULE);
+
+ for (int i = 0; i < numPolicies; i++) {
+ String instanceName = (String) mPolicyOrder.elementAt(i);
+
+ // The instance id should be unique
+ if (mInstanceTable.containsKey(instanceName))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DUPLICATE_INST_ID", instanceName));
+
+ c = ruleStore.getSubStore(instanceName);
+ if (c == null || c.size() == 0)
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_CONFIG",
+ instanceName));
+ IPolicyRule rule = null;
+ String implName;
+ boolean enabled;
+ IExpression filterExp;
+
+ // If the policy rule is not enabled, skip it.
+ String enabledStr = c.getString(PROP_ENABLE, null);
+
+ if (enabledStr == null || enabledStr.trim().length() == 0 ||
+ enabledStr.trim().equalsIgnoreCase("true"))
+ enabled = true;
+ else
+ enabled = false;
+
+ implName = c.getString(PROP_IMPL_NAME, null);
+ if (implName == null) {
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_CONFIG",
+ instanceName));
+ }
+
+ // Make an instance of the specified policy.
+ RegisteredPolicy regPolicy =
+ (RegisteredPolicy) mImplTable.get(implName);
+
+ if (regPolicy == null) {
+ String[] params = {implName, instanceName};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_IMPL_NOT_FOUND", params));
+ }
+
+ String classpath = regPolicy.getClassPath();
+
+ try {
+ rule = (IPolicyRule)
+ Class.forName(classpath).newInstance();
+ if (rule instanceof IPolicyRule)
+ ((IPolicyRule) rule).setInstanceName(instanceName);
+ rule.init(this, c);
+ } catch (Throwable e) {
+ mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_POLICY_INIT_FAILED", instanceName, e.toString()));
+ // disable rule initialized if there is
+ // configuration error
+ enabled = false;
+ c.putString(PROP_ENABLE, "false");
+ }
+
+ if (rule == null)
+ continue;
+
+ // Read the predicate expression if any associated
+ // with the rule
+ String exp = c.getString(GenericPolicyProcessor.PROP_PREDICATE, null);
+
+ if (exp != null)
+ exp = exp.trim();
+ if (exp != null && exp.length() > 0) {
+ filterExp = PolicyPredicateParser.parse(exp);
+ rule.setPredicate(filterExp);
+ }
+
+ // Add the rule to the instance table
+ mInstanceTable.put(instanceName,
+ new PolicyInstance(instanceName, implName, rule, enabled));
+
+ if (!enabled)
+ continue;
+
+ // Add the rule to the policy set according to category if a
+ // rule is enabled.
+ addRule(instanceName, rule);
+ }
+
+ // Verify that the default policies are present and enabled.
+ verifyDefaultPolicyConfig();
+
+ // printPolicies();
+ }
+
+ public boolean isProfileRequest(IRequest request) {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals(""))
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * Apply policies on the given request.
+ *
+ * @param IRequest The given request
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ IPolicySet rules = null;
+ String op = (String) req.getRequestType();
+
+ CMS.debug("GenericPolicyProcessor: apply begins");
+ if (op == null) {
+ CMS.debug("GenericPolicyProcessor: apply op null");
+ // throw new AssertionException("Missing operation type in request. Can't happen!");
+ // Return ACCEPTED for now. Looks like even get CA chain
+ // is being passed in here with request type set elsewhere
+ // on the request.
+ return PolicyResult.ACCEPTED;
+ }
+ if (isProfileRequest(req)) {
+ Debug.trace("GenericPolicyProcessor: Profile-base Request " +
+ req.getRequestId().toString());
+ return PolicyResult.ACCEPTED;
+ }
+ CMS.debug("GenericPolicyProcessor: apply not ProfileRequest. op="+op);
+
+ if (op.equalsIgnoreCase(IRequest.ENROLLMENT_REQUEST))
+ rules = mEnrollmentRules;
+ else if (op.equalsIgnoreCase(IRequest.RENEWAL_REQUEST))
+ rules = mRenewalRules;
+ else if (op.equalsIgnoreCase(IRequest.REVOCATION_REQUEST))
+ rules = mRevocationRules;
+ else if (op.equalsIgnoreCase(IRequest.KEY_RECOVERY_REQUEST))
+ rules = mKeyRecoveryRules;
+ else if (op.equalsIgnoreCase(IRequest.KEY_ARCHIVAL_REQUEST))
+ rules = mKeyArchivalRules;
+ else {
+ // It aint' a CMP request. We don't care.
+ return PolicyResult.ACCEPTED;
+ // throw new AssertionException("Invalid request type. Can't Happen!");
+ }
+
+ // ((PolicySet)rules).printPolicies();
+ // If there are no rules, then it is a serious error.
+ if (rules.count() == 0) {
+ CMS.debug("GenericPolicyProcessor: apply: rule count 0");
+ // if no policy is specified, just accept the request.
+ // KRA has no policy configured by default
+ return PolicyResult.ACCEPTED;
+
+ /**
+ setError(req, PolicyResources.NO_RULES_CONFIGURED, op);
+ return PolicyResult.REJECTED;
+ **/
+ }
+ CMS.debug("GenericPolicyProcessor: apply: rules.count="+ rules.count());
+
+ // request must be up to date or can't process it.
+ PolicyResult res = PolicyResult.ACCEPTED;
+ String mVersion = ARequestQueue.REQUEST_VERSION;
+ String vers = req.getRequestVersion();
+
+ if (vers == null || !vers.equals(mVersion)) {
+ if (vers == null || vers.length() == 0)
+ vers = "none";
+ res = PolicyResult.REJECTED;
+ }
+
+ if (res == PolicyResult.REJECTED)
+ return res;
+
+ CMS.debug("GenericPolicyProcessor: apply: calling rules.apply()");
+ // Apply the policy rules.
+ return rules.apply(req);
+ }
+
+ public void printPolicies() {
+ mEnrollmentRules.printPolicies();
+ mRenewalRules.printPolicies();
+ mRevocationRules.printPolicies();
+ mKeyRecoveryRules.printPolicies();
+ mKeyArchivalRules.printPolicies();
+ }
+
+ public String getPolicySubstoreId() {
+ return mAuthority.getId() + ".Policy";
+ }
+
+ private void setError(IRequest req, String format, String arg) {
+ if (format == null)
+ return;
+ EPolicyException ex = new EPolicyException(format, arg);
+
+ Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector();
+ }
+ ev.addElement(ex.toString());
+ req.setExtData(IRequest.ERRORS, ev);
+ }
+
+ public Enumeration getPolicyImpls() {
+ Vector impls = new Vector();
+ Enumeration enum1 = mImplTable.elements();
+ Enumeration ret = null;
+
+ try {
+ while (enum1.hasMoreElements()) {
+ RegisteredPolicy regPolicy =
+ (RegisteredPolicy) enum1.nextElement();
+
+ // Make an Instance of it
+ IPolicyRule ruleImpl = (IPolicyRule)
+ Class.forName(regPolicy.getClassPath()).newInstance();
+
+ impls.addElement(ruleImpl);
+ }
+ ret = impls.elements();
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ }
+ return ret;
+ }
+
+ public Enumeration getPolicyImplsInfo() {
+ Vector impls = new Vector();
+ Enumeration enum1 = mImplTable.elements();
+ Enumeration ret = null;
+
+ try {
+ while (enum1.hasMoreElements()) {
+ RegisteredPolicy regPolicy =
+ (RegisteredPolicy) enum1.nextElement();
+
+ impls.addElement(regPolicy.getId());
+
+ }
+ ret = impls.elements();
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ }
+ return ret;
+ }
+
+ public IPolicyRule getPolicyImpl(String id) {
+ RegisteredPolicy regImpl = (RegisteredPolicy)
+ mImplTable.get(id);
+
+ if (regImpl == null)
+ return null;
+ IPolicyRule impl = null;
+
+ try {
+ impl =
+ (IPolicyRule) Class.forName(regImpl.getClassPath()).newInstance();
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ }
+ return impl;
+ }
+
+ public Vector getPolicyImplConfig(String id) {
+ IPolicyRule rp = getPolicyImpl(id);
+
+ if (rp == null)
+ return null;
+ Vector v = rp.getDefaultParams();
+
+ if (v == null)
+ v = new Vector();
+ v.insertElementAt(IPolicyRule.PROP_ENABLE + "=" + "true", 0);
+ v.insertElementAt(IPolicyRule.PROP_PREDICATE + "=" + " ", 1);
+ return v;
+ }
+
+ public void deletePolicyImpl(String id)
+ throws EBaseException {
+ // First check if the id is valid;
+ RegisteredPolicy regPolicy =
+ (RegisteredPolicy) mImplTable.get(id);
+
+ if (regPolicy == null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL", id));
+
+ // If any instance exists for this impl, can't delete it.
+ boolean instanceExist = false;
+ Enumeration e = mInstanceTable.elements();
+
+ for (; e.hasMoreElements();) {
+ PolicyInstance inst = (PolicyInstance) e.nextElement();
+
+ if (inst.isInstanceOf(id)) {
+ instanceExist = true;
+ break;
+ }
+ }
+ if (instanceExist) // we found an instance
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_ACTIVE_POLICY_RULES_EXIST", id));
+
+ // Else delete the implementation
+ mImplTable.remove(id);
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+ IConfigStore implStore =
+ policyStore.getSubStore(PROP_IMPL);
+
+ implStore.removeSubStore(id);
+
+ // committing
+ try {
+ mGlobalStore.commit(true);
+ } catch (Exception ex) {
+ Debug.printStackTrace(ex);
+ String[] params = {"implementation", id};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DELETING_POLICY_ERROR", params));
+ }
+ }
+
+ public void addPolicyImpl(String id, String classPath)
+ throws EBaseException {
+ // See if the id is unique
+ if (mImplTable.containsKey(id))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DUPLICATE_IMPL_ID", id));
+
+ // See if the classPath is ok
+ Object impl = null;
+
+ try {
+ impl = Class.forName(classPath).newInstance();
+ }catch (Exception e) {
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL",
+ id));
+ }
+
+ // Does the class implement one of the four interfaces?
+ if (!(impl instanceof IEnrollmentPolicy) &&
+ !(impl instanceof IRenewalPolicy) &&
+ !(impl instanceof IRevocationPolicy) &&
+ !(impl instanceof IKeyRecoveryPolicy) &&
+ !(impl instanceof IKeyArchivalPolicy))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", classPath));
+
+ // Add the implementation to the registry
+ RegisteredPolicy regPolicy =
+ new RegisteredPolicy(id, classPath);
+
+ mImplTable.put(id, regPolicy);
+
+ // Store the impl in the configuration.
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+ IConfigStore implStore =
+ policyStore.getSubStore(PROP_IMPL);
+ IConfigStore newStore = implStore.makeSubStore(id);
+
+ newStore.put(PROP_CLASS, classPath);
+ try {
+ mGlobalStore.commit(true);
+ } catch (Exception e) {
+ String[] params = {"implementation", id};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
+ }
+ }
+
+ public Enumeration getPolicyInstances() {
+ Vector rules = new Vector();
+ Enumeration enum1 = mPolicyOrder.elements();
+ Enumeration ret = null;
+
+ try {
+ while (enum1.hasMoreElements()) {
+ PolicyInstance instance =
+ (PolicyInstance) mInstanceTable.get((String) enum1.nextElement());
+
+ rules.addElement(instance.getRule());
+
+ }
+ ret = rules.elements();
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ }
+ return ret;
+ }
+
+ public Enumeration getPolicyInstancesInfo() {
+ Vector rules = new Vector();
+ Enumeration enum1 = mPolicyOrder.elements();
+ Enumeration ret = null;
+
+ try {
+ while (enum1.hasMoreElements()) {
+ String ruleName = (String) enum1.nextElement();
+ PolicyInstance instance =
+ (PolicyInstance) mInstanceTable.get(ruleName);
+
+ rules.addElement(instance.getRuleInfo());
+ }
+ ret = rules.elements();
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ }
+ return ret;
+ }
+
+ public IPolicyRule getPolicyInstance(String id) {
+ PolicyInstance policyInstance = (PolicyInstance)
+ mInstanceTable.get(id);
+
+ return (policyInstance == null) ? null : policyInstance.getRule();
+ }
+
+ public Vector getPolicyInstanceConfig(String id) {
+ PolicyInstance policyInstance = (PolicyInstance)
+ mInstanceTable.get(id);
+
+ if (policyInstance == null)
+ return null;
+ Vector v = policyInstance.getRule().getInstanceParams();
+
+ if (v == null)
+ v = new Vector();
+ v.insertElementAt(PROP_IMPL_NAME + "=" + policyInstance.getImplId(), 0);
+ v.insertElementAt(PROP_ENABLE + "=" + policyInstance.isActive(), 1);
+ String predicate = " ";
+
+ if (policyInstance.getRule().getPredicate() != null)
+ predicate = policyInstance.getRule().getPredicate().toString();
+ v.insertElementAt(PROP_PREDICATE + "=" + predicate, 2);
+ return v;
+ }
+
+ public void deletePolicyInstance(String id)
+ throws EBaseException {
+ // If the rule is a persistent rule, we can't delete it.
+ if (mUndeletablePolicies.containsKey(id))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_CANT_DELETE_PERSISTENT_POLICY", id));
+
+ // First check if the instance is present.
+ PolicyInstance instance =
+ (PolicyInstance) mInstanceTable.get(id);
+
+ if (instance == null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", id));
+
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+ IConfigStore instanceStore =
+ policyStore.getSubStore(PROP_RULE);
+
+ instanceStore.removeSubStore(id);
+
+ // Remove the rulename from the rder list
+ int index = mPolicyOrder.indexOf(id);
+
+ mPolicyOrder.removeElement(id);
+
+ // Now change the ordering in the config file.
+ policyStore.put(PROP_ORDER, getRuleOrderString(mPolicyOrder));
+
+ // Commit changes to file.
+ try {
+ mGlobalStore.commit(true);
+ } catch (Exception e) {
+ // Put the rule back in the rule order vector.
+ mPolicyOrder.insertElementAt(id, index);
+
+ Debug.printStackTrace(e);
+ String[] params = {"instance", id};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DELETING_POLICY_ERROR", params));
+ }
+
+ IPolicyRule rule = instance.getRule();
+
+ if (rule instanceof IEnrollmentPolicy)
+ mEnrollmentRules.removeRule(id);
+ if (rule instanceof IRenewalPolicy)
+ mRenewalRules.removeRule(id);
+ if (rule instanceof IRevocationPolicy)
+ mRevocationRules.removeRule(id);
+ if (rule instanceof IKeyRecoveryPolicy)
+ mKeyRecoveryRules.removeRule(id);
+ if (rule instanceof IKeyArchivalPolicy)
+ mKeyArchivalRules.removeRule(id);
+
+ // Delete the instance
+ mInstanceTable.remove(id);
+ }
+
+ public void addPolicyInstance(String id, Hashtable ht)
+ throws EBaseException {
+ // The instance id should be unique
+ if (getPolicyInstance(id) != null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_DUPLICATE_INST_ID", id));
+ // There should be an implmentation for this rule.
+ String implName = (String) ht.get(IPolicyRule.PROP_IMPLNAME);
+
+ // See if there is an implementation with this name.
+ IPolicyRule rule = getPolicyImpl(implName);
+
+ if (rule == null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL", implName));
+
+ // Prepare config file entries.
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+ IConfigStore instanceStore =
+ policyStore.getSubStore(PROP_RULE);
+ IConfigStore newStore = instanceStore.makeSubStore(id);
+
+ for (Enumeration keys = ht.keys(); keys.hasMoreElements();) {
+ String key = (String) keys.nextElement();
+ String val = (String) ht.get(key);
+
+ newStore.put(key, val);
+ }
+
+ // Set the order string.
+ policyStore.put(PROP_ORDER,
+ getRuleOrderString(mPolicyOrder, id));
+
+ // Try to initialize this rule.
+ rule.init(this, newStore);
+
+ // Add the rule to the table.
+ String enabledStr = (String) ht.get(IPolicyRule.PROP_ENABLE);
+ boolean active = false;
+
+ if (enabledStr == null || enabledStr.trim().length() == 0 ||
+ enabledStr.equalsIgnoreCase("true"))
+ active = true;
+
+ // Set the predicate if any present on the rule.
+ String predicate = ((String) ht.get(IPolicyRule.PROP_PREDICATE)).trim();
+ IExpression exp = null;
+
+ if (predicate.trim().length() > 0)
+ exp = PolicyPredicateParser.parse(predicate.trim());
+ rule.setPredicate(exp);
+
+ // Store the changes in the file.
+ try {
+ mGlobalStore.commit(true);
+ } catch (Exception e) {
+ String[] params = {"instance", id};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
+ }
+
+ // Add the rule to the instance table.
+ PolicyInstance policyInst = new PolicyInstance(id, implName,
+ rule, active);
+
+ mInstanceTable.put(id, policyInst);
+
+ // Add the rule to the end of order table.
+ mPolicyOrder.addElement(id);
+
+ // If the rule is not active, return.
+ if (!active)
+ return;
+
+ addRule(id, rule);
+ }
+
+ public void modifyPolicyInstance(String id, Hashtable ht)
+ throws EBaseException {
+ // The instance id should be there already
+ PolicyInstance policyInstance = (PolicyInstance)
+ mInstanceTable.get(id);
+
+ if (policyInstance == null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", id));
+ IPolicyRule rule = policyInstance.getRule();
+
+ // The impl id shouldn't change
+ String implId = (String) ht.get(IPolicyRule.PROP_IMPLNAME);
+
+ if (!implId.equals(policyInstance.getImplId()))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_IMPLCHANGE_ERROR", id));
+
+ // Make a new rule instance
+ IPolicyRule newRule = getPolicyImpl(implId);
+
+ if (newRule == null) // Can't happen, but just in case..
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", implId));
+
+ // Try to init this rule.
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+ IConfigStore instanceStore =
+ policyStore.getSubStore(PROP_RULE);
+ IConfigStore oldStore = instanceStore.getSubStore(id);
+ IConfigStore newStore = new PropConfigStore(id);
+
+ // See if the rule is disabled.
+ String enabledStr = (String) ht.get(IPolicyRule.PROP_ENABLE);
+ boolean active = false;
+
+ if (enabledStr == null || enabledStr.trim().length() == 0 ||
+ enabledStr.equalsIgnoreCase("true"))
+ active = true;
+
+ // Set the predicate expression.
+ String predicate = ((String) ht.get(IPolicyRule.PROP_PREDICATE)).trim();
+ IExpression exp = null;
+
+ if (predicate.trim().length() > 0)
+ exp = PolicyPredicateParser.parse(predicate.trim());
+
+ // See if this a persistent rule.
+ if (mUndeletablePolicies.containsKey(id)) {
+ // A persistent rule can't be disabled.
+ if (!active) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_INACTIVE", id));
+ }
+
+ IExpression defPred = (IExpression)
+ mUndeletablePolicies.get(id);
+
+ if (defPred == SimpleExpression.NULL_EXPRESSION)
+ defPred = null;
+ if (exp == null && defPred != null) {
+ String[] params = {id, defPred.toString(),
+ "null" };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ } else if (exp != null && defPred == null) {
+ String[] params = {id, "null", exp.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ } else if (exp != null && defPred != null) {
+ if (!defPred.toString().equals(exp.toString())) {
+ String[] params = {id, defPred.toString(),
+ exp.toString() };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ }
+ }
+ }
+
+ // Predicate for the persistent rule can't be changed.
+ ht.put(IPolicyRule.PROP_ENABLE, String.valueOf(active));
+
+ // put old config store parameters first.
+ for (Enumeration oldkeys = oldStore.keys();
+ oldkeys.hasMoreElements();) {
+ String k = (String) oldkeys.nextElement();
+ String v = (String) oldStore.getString(k);
+
+ newStore.put(k, v);
+ }
+
+ // put modified params.
+ for (Enumeration newkeys = ht.keys();
+ newkeys.hasMoreElements();) {
+ String k = (String) newkeys.nextElement();
+ String v = (String) ht.get(k);
+
+ Debug.trace("newstore key " + k + "=" + v);
+ if (v != null) {
+ if (!k.equals(Constants.OP_TYPE) && !k.equals(Constants.OP_SCOPE) &&
+ !k.equals(Constants.RS_ID) && !k.equals("RULENAME")) {
+ Debug.trace("newstore.put(" + k + "=" + v + ")");
+ newStore.put(k, v);
+ }
+ }
+ }
+
+ // include impl default params in case we missed any.
+
+ /*
+ for (Enumeration keys = ht.keys(); keys.hasMoreElements();)
+ {
+ String key = (String)keys.nextElement();
+ String val = (String)ht.get(key);
+ newStore.put(key, val);
+ }
+ */
+
+
+ // Try to initialize this rule.
+ newRule.init(this, newStore);
+
+ // If we are successfully initialized, replace the rule
+ // instance
+ policyInstance.setRule(newRule);
+ policyInstance.setActive(active);
+
+ // Set the predicate expression.
+ if (exp != null)
+ newRule.setPredicate(exp);
+
+ // Store the changes in the file.
+ try {
+ for (Enumeration e = newStore.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+
+ if (key != null) {
+ Debug.trace(
+ "oldstore.put(" + key + "," +
+ (String) newStore.getString(key) + ")");
+ oldStore.put(key, (String) newStore.getString(key));
+ }
+ }
+ mGlobalStore.commit(true);
+ } catch (Exception e) {
+ String[] params = {"instance", id};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
+ }
+
+ // If rule is disabled, we need to remove it from the
+ // policy set.
+ if (!active) {
+ if (rule instanceof IEnrollmentPolicy)
+ mEnrollmentRules.removeRule(id);
+ if (rule instanceof IRenewalPolicy)
+ mRenewalRules.removeRule(id);
+ if (rule instanceof IRevocationPolicy)
+ mRevocationRules.removeRule(id);
+ if (rule instanceof IKeyRecoveryPolicy)
+ mKeyRecoveryRules.removeRule(id);
+ if (rule instanceof IKeyArchivalPolicy)
+ mKeyArchivalRules.removeRule(id);
+ } else // replace the rule
+ {
+ if (rule instanceof IEnrollmentPolicy)
+ mEnrollmentRules.replaceRule(id, newRule);
+ if (rule instanceof IRenewalPolicy)
+ mRenewalRules.replaceRule(id, newRule);
+ if (rule instanceof IRevocationPolicy)
+ mRevocationRules.replaceRule(id, newRule);
+ if (rule instanceof IKeyRecoveryPolicy)
+ mKeyRecoveryRules.replaceRule(id, newRule);
+ if (rule instanceof IKeyArchivalPolicy)
+ mKeyArchivalRules.replaceRule(id, newRule);
+ }
+ }
+
+ public synchronized void changePolicyInstanceOrdering(
+ String policyOrderStr)
+ throws EBaseException {
+ Vector policyOrder = new Vector();
+ StringTokenizer tokens = new StringTokenizer(policyOrderStr, ",");
+
+ // Get all the elements
+ while (tokens.hasMoreTokens()) {
+ String instanceId = tokens.nextToken().trim();
+
+ // Check if we have that instance configured.
+ if (!mInstanceTable.containsKey(instanceId))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", instanceId));
+ policyOrder.addElement(instanceId);
+ }
+
+ // Now enforce the new ordering
+ // First if the order is the same as what we have,
+ // return.
+ if (policyOrder.size() == mPolicyOrder.size()) {
+ if (areSameVectors(policyOrder, mPolicyOrder))
+ return;
+ }
+ PolicySet enrollmentRules = new PolicySet("EnrollmentRules");
+ PolicySet renewalRules = new PolicySet("RenewalRules");
+ PolicySet revocationRules = new PolicySet("RevocationRules");
+ PolicySet keyRecoveryRules = new PolicySet("KeyRecoveryRules");
+ PolicySet keyArchivalRules = new PolicySet("KeyArchivalRules");
+
+ // add system default rules first.
+ try {
+ for (int i = 0; i < mSystemDefaults.length; i++) {
+ String defRuleName = mSystemDefaults[i].substring(
+ mSystemDefaults[i].lastIndexOf('.') + 1);
+ IPolicyRule defRule = (IPolicyRule)
+ Class.forName(mSystemDefaults[i]).newInstance();
+ IConfigStore ruleConfig =
+ mConfig.getSubStore(PROP_DEF_POLICIES + "." + defRuleName);
+
+ defRule.init(this, ruleConfig);
+ if (defRule instanceof IEnrollmentPolicy)
+ enrollmentRules.addRule(defRuleName, defRule);
+ else if (defRule instanceof IRenewalPolicy)
+ renewalRules.addRule(defRuleName, defRule);
+ else if (defRule instanceof IRevocationPolicy)
+ revocationRules.addRule(defRuleName, defRule);
+ else if (defRule instanceof IKeyRecoveryPolicy)
+ keyRecoveryRules.addRule(defRuleName, defRule);
+ else if (defRule instanceof IKeyArchivalPolicy)
+ keyArchivalRules.addRule(defRuleName, defRule);
+ // else ignore the darned rule.
+ }
+ } catch (Throwable e) {
+ Debug.printStackTrace(e);
+ EBaseException ex = new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot create default policy rule. Error: " + e.getMessage()));
+
+ mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_POLICY_DEF_CREATE", e.toString()));
+ throw ex;
+ }
+
+ // add rules specified in the new order.
+ for (Enumeration enum1 = policyOrder.elements();
+ enum1.hasMoreElements();) {
+ String instanceName = (String) enum1.nextElement();
+ PolicyInstance pInstance = (PolicyInstance)
+ mInstanceTable.get(instanceName);
+
+ if (!pInstance.isActive())
+ continue;
+
+ // Add the rule to the policy set according to category if a
+ // rule is enabled.
+ IPolicyRule rule = pInstance.getRule();
+
+ if (rule instanceof IEnrollmentPolicy)
+ enrollmentRules.addRule(instanceName, rule);
+ else if (rule instanceof IRenewalPolicy)
+ renewalRules.addRule(instanceName, rule);
+ else if (rule instanceof IRevocationPolicy)
+ revocationRules.addRule(instanceName, rule);
+ else if (rule instanceof IKeyRecoveryPolicy)
+ keyRecoveryRules.addRule(instanceName, rule);
+ else if (rule instanceof IKeyArchivalPolicy)
+ keyArchivalRules.addRule(instanceName, rule);
+ // else ignore the darned rule.
+ }
+
+ mEnrollmentRules = enrollmentRules;
+ mRenewalRules = renewalRules;
+ mRevocationRules = revocationRules;
+ mKeyRecoveryRules = keyRecoveryRules;
+ mKeyArchivalRules = keyArchivalRules;
+ mPolicyOrder = policyOrder;
+
+ // Now change the ordering in the config file.
+ IConfigStore policyStore =
+ mGlobalStore.getSubStore(getPolicySubstoreId());
+
+ policyStore.put(PROP_ORDER, policyOrderStr);
+
+ // committing
+ try {
+ mGlobalStore.commit(true);
+ } catch (Exception ex) {
+ Debug.printStackTrace(ex);
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_ORDER_ERROR", policyOrderStr));
+ }
+ }
+
+ private boolean areSameVectors(Vector v1, Vector v2) {
+ if (v1.size() != v2.size())
+ return false;
+ int size = v1.size();
+ int i = 0;
+
+ for (; i < size; i++)
+ if (v2.indexOf(v1.elementAt(i)) != i)
+ break;
+ return (i == size ? true : false);
+ }
+
+ private String getRuleOrderString(Vector rules) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = rules.elements(); e.hasMoreElements();) {
+ sb.append((String) e.nextElement());
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ return new String(sb);
+ }
+
+ private String getRuleOrderString(Vector rules, String newRule) {
+ String currentRules = getRuleOrderString(rules);
+
+ if (currentRules == null || currentRules.length() == 0)
+ return newRule;
+ else
+ return currentRules + "," + newRule;
+ }
+
+ /**
+ * Initializes the default system policies. Currently there is only
+ * one policy - ManualAuthentication. More may be added later on.
+ *
+ * The default policies may be disabled - for example to over-ride
+ * agent approval for testing the system by setting the following
+ * property in the config file:
+ *
+ * <subsystemId>.Policy.systemPolicies.enable=false
+ *
+ * By default the value for this property is true.
+ *
+ * Users can over-ride the default system policies by listing their
+ * 'custom' system policies under the following property:
+ *
+ * <subsystemId>.Policy.systemPolicies=<system policy1 class path>,
+ * <system policy2 class path>
+ *
+ * There can only be one instance of the system policy in the system
+ * and will apply to all requests, and hence predicates are not used
+ * for a system policy. Due to the same reason, these properties are
+ * not configurable using the Console.
+ *
+ * A System policy may read config properties from a subtree under
+ * <subsystemId>.Policy.systemPolicies.<ClassName>. An example is
+ * ra.Policy.systemPolicies.ManualAuthentication.param1=value
+ */
+ private void initSystemPolicies(IConfigStore mConfig)
+ throws EBaseException {
+ // If system policies are disabled, return. No Deferral of
+ // requests may be done.
+ String enable = mConfig.getString(PROP_DEF_POLICIES + "." +
+ PROP_ENABLE, "true").trim();
+
+ if (enable.equalsIgnoreCase("false")) {
+ mSystemDefaults = DEF_POLICIES;
+ return;
+ }
+
+ // Load default policies that are always present.
+ String configuredDefaults = mConfig.getString(PROP_DEF_POLICIES,
+ null);
+
+ if (configuredDefaults == null ||
+ configuredDefaults.trim().length() == 0)
+ mSystemDefaults = DEF_POLICIES;
+ else {
+ Vector rules = new Vector();
+ StringTokenizer tokenizer = new
+ StringTokenizer(configuredDefaults.trim(), ",");
+
+ while (tokenizer.hasMoreTokens()) {
+ String rule = tokenizer.nextToken().trim();
+
+ rules.addElement(rule);
+ }
+ if (rules.size() > 0) {
+ mSystemDefaults = new String[rules.size()];
+ rules.copyInto(mSystemDefaults);
+ } else
+ mSystemDefaults = DEF_POLICIES;
+ }
+
+ // Now Initialize the rules. These defaults have only one
+ // instance and the rule name is the name of the class itself.
+ // Any configuration parameters required could be read from
+ // <subsystemId>.Policy.default.RuleName.
+ for (int i = 0; i < mSystemDefaults.length; i++) {
+ // Load the class and make an instance.
+ // Verify if the class is a valid implementation of
+ // IPolicyRule
+ String ruleName = null;
+
+ try {
+ Object o = Class.forName(mSystemDefaults[i]).newInstance();
+
+ if (!(o instanceof IEnrollmentPolicy) &&
+ !(o instanceof IRenewalPolicy) &&
+ !(o instanceof IRevocationPolicy) &&
+ !(o instanceof IKeyRecoveryPolicy) &&
+ !(o instanceof IKeyArchivalPolicy))
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL",
+ mSystemDefaults[i]));
+
+ IPolicyRule rule = (IPolicyRule) o;
+
+ // Initialize the rule.
+ ruleName = mSystemDefaults[i].substring(
+ mSystemDefaults[i].lastIndexOf('.') + 1);
+ IConfigStore ruleConfig = mConfig.getSubStore(
+ PROP_DEF_POLICIES + "." + ruleName);
+
+ rule.init(this, ruleConfig);
+
+ // Add the rule to the appropriate PolicySet.
+ addRule(ruleName, rule);
+ } catch (EBaseException e) {
+ throw e;
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL",
+ ruleName));
+ }
+ }
+ }
+
+ /**
+ * Read list of undeletable policies if any configured in the
+ * system.
+ *
+ * These are required to protect the system from being misconfigured
+ * to the point that the requests wouldn't serialize or certain
+ * fields in the certificate(s) being checked will go unchecked
+ * ..etc.
+ *
+ * For now the following policies are undeletable:
+ *
+ * DirAuthRule: This is a default DirectoryAuthentication policy
+ * for user certificates that interprets directory
+ * credentials. The presence of this policy is needed
+ * if the OOTB DirectoryAuthentication-based automatic
+ * certificate issuance is supported.
+ *
+ * DefaultUserNameRule: This policy verifies/sets subjectDn for user
+ * certificates.
+ *
+ * DefaultServerNameRule: This policy verifies/sets subjectDn for
+ * server certificates.
+ *
+ * DefaultValidityRule: Verifies/sets validty for all certificates.
+ *
+ * DefaultRenewalValidityRule: Verifies/sets validity for certs being
+ * renewed.
+ *
+ * The 'undeletables' cannot be deleted from the config file, nor
+ * can the be disabled. If any predicates are associated with them
+ * the predicates can't be changed either. But, other config parameters
+ * such as maxValidity, renewalInterval ..etc can be changed to suit
+ * local policy requirements.
+ *
+ * During start up the policy processor will verify if the undeletables
+ * are present, and that they are enabled and that their predicates are
+ * not changed.
+ *
+ * The rules mentioned above are currently hard coded. If these need to
+ * read from the config file, the 'undeletables' can be configured as
+ * as follows:
+ *
+ * <subsystemId>.Policy.undeletablePolicies=<comma separated rule names>
+ * Example:
+ * ra.Policy.undeletablePolicies=DirAuthRule, DefaultUserNameRule, DefaultServerNameRule, DefaultValidityRule, DefaultRenewalValidityRule
+ *
+ * The predicates if any associated with them may be configured as
+ * follows:
+ * <subsystemId>.Policy.undeletablePolicies.DirAuthRule.predicate= certType == client.
+ *
+ * where subsystemId is ra or ca.
+ *
+ * If the undeletables are configured in the file,the configured entries
+ * take precedence over the hardcoded ones in this file. If you are
+ * configuring them in the file, please remember to configure the
+ * predicates if applicable.
+ *
+ * During policy configuration from MCC, the policy processor will not
+ * let you delete an 'undeletable', nor will it let you disable it.
+ * You will not be able to change the predicate either. Other parameters
+ * can be configured as needed.
+ *
+ * If a particular rule needs to be removed from the 'undeletables',
+ * either remove it from the hard coded list above, or configure the
+ * rules required rules only via the config file. The former needs
+ * recompilation of the source. The later is flexible to be able to
+ * make any rule an 'undeletable' or nor an 'undeletable'.
+ *
+ * Example: We want to use only manual forms for enrollment.
+ * We do n't need to burn in DirAuthRule. We need to configure all
+ * other rules except the DirAuthRule as follows:
+ *
+ * ra.Policy.undeletablePolicies = DefaultUserNameRule, DefaultServerNameRule, DefaultValidityRule, DefaultRenewalValidityRule
+ *
+ * The following predicates are necessary:
+ *
+ * ra.Policy.undeletablePolicies.DefaultUserNameRule.predicate = certType == client
+ * ra.Policy.undeletablePolicies.DefaultServerNameRule.predicate = certType == server
+ *
+ * The other two rules do not have any predicates.
+ */
+ private void initUndeletablePolicies(IConfigStore mConfig)
+ throws EBaseException {
+ // Read undeletable policies if any configured.
+ String configuredUndeletables =
+ mConfig.getString(PROP_UNDELETABLE_POLICIES, null);
+
+ if (configuredUndeletables == null ||
+ configuredUndeletables.trim().length() == 0) {
+ mUndeletablePolicies = DEF_UNDELETABLE_POLICIES;
+ return;
+ }
+
+ Vector rules = new Vector();
+ StringTokenizer tokenizer = new
+ StringTokenizer(configuredUndeletables.trim(), ",");
+
+ while (tokenizer.hasMoreTokens()) {
+ String rule = tokenizer.nextToken().trim();
+
+ rules.addElement(rule);
+ }
+
+ if (rules.size() == 0) {
+ mUndeletablePolicies = DEF_UNDELETABLE_POLICIES;
+ return;
+ }
+
+ // For each rule read from the config file, see if any
+ // predicate is set.
+ mUndeletablePolicies = new Hashtable();
+ for (Enumeration e = rules.elements(); e.hasMoreElements();) {
+ String urn = (String) e.nextElement();
+
+ // See if there is predicate in the file
+ String pred = mConfig.getString(PROP_UNDELETABLE_POLICIES +
+ "." + urn + "." + PROP_PREDICATE, null);
+
+ IExpression exp = SimpleExpression.NULL_EXPRESSION;
+
+ if (pred != null)
+ exp = PolicyPredicateParser.parse(pred);
+ mUndeletablePolicies.put(urn, exp);
+ }
+ }
+
+ private void addRule(String ruleName, IPolicyRule rule) {
+ if (rule instanceof IEnrollmentPolicy)
+ mEnrollmentRules.addRule(ruleName, rule);
+ if (rule instanceof IRenewalPolicy)
+ mRenewalRules.addRule(ruleName, rule);
+ if (rule instanceof IRevocationPolicy)
+ mRevocationRules.addRule(ruleName, rule);
+ if (rule instanceof IKeyRecoveryPolicy)
+ mKeyRecoveryRules.addRule(ruleName, rule);
+ if (rule instanceof IKeyArchivalPolicy)
+ mKeyArchivalRules.addRule(ruleName, rule);
+ }
+
+ private boolean isSystemDefaultPolicy(String clPath) {
+ boolean ret = false;
+
+ if (mSystemDefaults == null)
+ return false;
+ for (int i = 0; i < mSystemDefaults.length; i++) {
+ if (clPath.equals(mSystemDefaults[i])) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private void verifyDefaultPolicyConfig()
+ throws EPolicyException {
+ // For each policy in undeletable list make sure that
+ // the policy is present, is not disabled and its predicate
+ // is not tampered with.
+ for (Enumeration e = mUndeletablePolicies.keys();
+ e.hasMoreElements();) {
+ String urn = (String) e.nextElement();
+
+ // See if the rule is in the instance table.
+ PolicyInstance inst = (PolicyInstance) mInstanceTable.get(urn);
+
+ if (inst == null)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_MISSING_PERSISTENT_RULE", urn));
+
+ // See if the instance is disabled.
+ if (!inst.isActive())
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_INACTIVE", urn));
+
+ // See if the predicated is misconfigured.
+ IExpression defPred = (IExpression)
+ mUndeletablePolicies.get(urn);
+
+ // We used SimpleExpression.NULL_EXPRESSION to indicate a null.
+ if (defPred == SimpleExpression.NULL_EXPRESSION)
+ defPred = null;
+ IExpression confPred = inst.getRule().getPredicate();
+
+ if (defPred == null && confPred != null) {
+ String[] params = {urn, "null", confPred.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ } else if (defPred != null && confPred == null) {
+ String[] params = {urn, defPred.toString(), "null"};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ } else if (defPred != null && confPred != null) {
+ if (!defPred.toString().equals(confPred.toString())) {
+ String[] params = {urn, defPred.toString(),
+ confPred.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Class to keep track of various configurable implementations.
+ */
+class RegisteredPolicy {
+ String mId;
+ String mClPath;
+ public RegisteredPolicy (String id, String clPath) {
+ if (id == null || clPath == null)
+ throw new
+ AssertionException("Policy id or classpath can't be null");
+ mId = id;
+ mClPath = clPath;
+ }
+
+ public String getClassPath() {
+ return mClPath;
+ }
+
+ public String getId() {
+ return mId;
+ }
+}
+
+
+class PolicyInstance {
+ String mInstanceId;
+ String mImplId;
+ IPolicyRule mRule;
+ boolean mIsEnabled;
+
+ public PolicyInstance(String instanceId, String implId,
+ IPolicyRule rule, boolean isEnabled) {
+ mInstanceId = instanceId;
+ mImplId = implId;
+ mRule = rule;
+ mIsEnabled = isEnabled;
+ }
+
+ public String getInstanceId() {
+ return mInstanceId;
+ }
+
+ public String getImplId() {
+ return mImplId;
+ }
+
+ public String getRuleInfo() {
+ String enabled = mIsEnabled ? "enabled" : "disabled";
+
+ return mInstanceId + ";" + mImplId + ";visible;" + enabled;
+ }
+
+ public IPolicyRule getRule() {
+ return mRule;
+ }
+
+ public boolean isInstanceOf(String implId) {
+ return mImplId.equals(implId);
+ }
+
+ public boolean isActive() {
+ return mIsEnabled;
+ }
+
+ public void setActive(boolean stat) {
+ mIsEnabled = stat;
+ }
+
+ public void setRule(IPolicyRule newRule) {
+ mRule = newRule;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java b/pki/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java
new file mode 100644
index 000000000..3f421fca4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java
@@ -0,0 +1,46 @@
+// --- 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.cmscore.policy;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.policy.*;
+
+import com.netscape.cmscore.util.Debug;
+
+
+public class JavaScriptRequestProxy {
+ IRequest req;
+ public JavaScriptRequestProxy(IRequest r) {
+ req = r;
+ }
+
+ public String getHTTP(String param) {
+ return req.getExtDataInString(IRequest.HTTP_PARAMS, param);
+ }
+
+ public String get(String param) {
+ return req.getExtDataInString(param);
+ }
+
+ public PolicyResult applyPolicy(IPolicyRule r) {
+ return r.apply(req);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/OrExpression.java b/pki/base/common/src/com/netscape/cmscore/policy/OrExpression.java
new file mode 100644
index 000000000..dfbcb0ef6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/OrExpression.java
@@ -0,0 +1,65 @@
+// --- 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.cmscore.policy;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+
+
+/**
+ * This class represents an Or expression of the form
+ * (var1 op val1 OR var2 op val2).
+ *
+ * Expressions are used as predicates for policy selection.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class OrExpression implements IExpression {
+ private IExpression mExp1;
+ private IExpression mExp2;
+ public OrExpression(IExpression exp1, IExpression exp2) {
+ mExp1 = exp1;
+ mExp2 = exp2;
+ }
+
+ public boolean evaluate(IRequest req)
+ throws EPolicyException {
+ if (mExp1 == null && mExp2 == null)
+ return true;
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.evaluate(req) || mExp2.evaluate(req);
+ else if (mExp1 != null && mExp2 == null)
+ return mExp1.evaluate(req);
+ else // (mExp1 == null && mExp2 != null)
+ return mExp2.evaluate(req);
+ }
+
+ public String toString() {
+ if (mExp1 == null && mExp2 == null)
+ return "";
+ else if (mExp1 != null && mExp2 != null)
+ return mExp1.toString() + " OR " + mExp2.toString();
+ else if (mExp1 != null && mExp2 == null)
+ return mExp1.toString();
+ else // (mExp1 == null && mExp2 != null)
+ return mExp2.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java b/pki/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java
new file mode 100644
index 000000000..46a874291
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java
@@ -0,0 +1,373 @@
+// --- 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.cmscore.policy;
+
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * Default implementation of predicate parser.
+ *
+ * Limitations:
+ *
+ * 1. Currently parentheses are not suported.
+ * 2. Only ==, != <, >, <= and >= operators are supported.
+ * 3. The only boolean operators supported are AND and OR. AND takes precedence
+ * over OR. Example: a AND b OR e OR c AND d
+ * is treated as (a AND b) OR e OR (c AND d)
+ * 4. If this is n't adequate, roll your own.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class PolicyPredicateParser {
+ public static final int OP_AND = 1;
+ public static final int OP_OR = 2;
+ public static final int EXPRESSION = 0;
+
+ public static final String AND = "AND";
+ public static final String OR = "OR";
+
+ private static final char COMMA = ',';
+
+ /**
+ * Parse the predicate expression and return a vector of expressions.
+ *
+ * @param predicateExp The predicate expression as read from the config file.
+ * @return expVector The vector of expressions.
+ */
+ public static IExpression parse(String predicateExpression)
+ throws EPolicyException {
+ if (predicateExpression == null ||
+ predicateExpression.length() == 0)
+ return null;
+ PredicateTokenizer pt = new PredicateTokenizer(predicateExpression);
+
+ if (pt == null || !pt.hasMoreTokens())
+ return null;
+
+ // The first token cannot be an operator. We are not dealing with
+ // reverse-polish notation.
+ String token = pt.nextToken();
+ boolean opANDSeen;
+ boolean opORSeen;
+
+ if (getOP(token) != EXPRESSION) {
+ if (Debug.ON)
+ Debug.trace("Malformed expression: " + predicateExpression);
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_BAD_POLICY_EXPRESSION", predicateExpression));
+ }
+ IExpression current = parseExpression(token);
+ boolean malformed = false;
+ Vector expSet = new Vector();
+ int prevType = EXPRESSION;
+
+ while (pt.hasMoreTokens()) {
+ token = pt.nextToken();
+ int curType = getOP(token);
+
+ if ((prevType != EXPRESSION && curType != EXPRESSION) ||
+ (prevType == EXPRESSION && curType == EXPRESSION)) {
+ malformed = true;
+ break;
+ }
+
+ // If an operator seen skip to the next token
+ if (curType != EXPRESSION) {
+ prevType = curType;
+ continue;
+ }
+
+ // If the previous type was an OR token, add the current expression to
+ // the expression set;
+ if (prevType == OP_OR) {
+ expSet.addElement(current);
+ current = parseExpression(token);
+ prevType = curType;
+ continue;
+ }
+
+ // If the previous type was an AND token, make an AND expression
+ if (prevType == OP_AND) {
+ current = new AndExpression(current, parseExpression(token));
+ prevType = curType;
+ }
+ }
+ if (malformed) {
+ if (Debug.ON)
+ Debug.trace("Malformed expression: " + predicateExpression);
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_BAD_POLICY_EXPRESSION",
+ predicateExpression));
+ }
+
+ // Form an ORExpression
+ if (current != null)
+ expSet.addElement(current);
+
+ int size = expSet.size();
+
+ if (size == 0)
+ return null;
+ OrExpression orExp = new
+ OrExpression((IExpression) expSet.elementAt(0), null);
+
+ for (int i = 1; i < size; i++)
+ orExp = new OrExpression(orExp,
+ (IExpression) expSet.elementAt(i));
+ return orExp;
+ }
+
+ private static int getOP(String token) {
+ if (token.equalsIgnoreCase(AND))
+ return OP_AND;
+ else if (token.equalsIgnoreCase(OR))
+ return OP_OR;
+ else
+ return EXPRESSION;
+ }
+
+ private static IExpression parseExpression(String input)
+ throws EPolicyException {
+ // If the expression has multiple parts separated by commas
+ // we need to construct an AND expression. Else we will return a
+ // simple expression.
+ int commaIndex = input.indexOf(COMMA);
+
+ if (commaIndex < 0)
+ return SimpleExpression.parse(input);
+ int currentIndex = 0;
+ Vector expVector = new Vector();
+
+ while (commaIndex > 0) {
+ SimpleExpression exp = (SimpleExpression)
+ SimpleExpression.parse(input.substring(currentIndex,
+ commaIndex));
+
+ expVector.addElement(exp);
+ currentIndex = commaIndex + 1;
+ commaIndex = input.indexOf(COMMA, currentIndex);
+ }
+ if (currentIndex < (input.length() - 1)) {
+ SimpleExpression exp = (SimpleExpression)
+ SimpleExpression.parse(input.substring(currentIndex));
+
+ expVector.addElement(exp);
+ }
+
+ int size = expVector.size();
+ SimpleExpression exp1 = (SimpleExpression) expVector.elementAt(0);
+ SimpleExpression exp2 = (SimpleExpression) expVector.elementAt(1);
+ AndExpression andExp = new AndExpression(exp1, exp2);
+
+ for (int i = 2; i < size; i++) {
+ andExp = new AndExpression(andExp, (SimpleExpression) expVector.elementAt(i));
+ }
+ return andExp;
+ }
+
+ public static void main(String[] args) {
+
+ /*********
+ IRequest req = new IRequest();
+ try
+ {
+ req.set("ou", "people");
+ req.set("cn", "John Doe");
+ req.set("uid", "jdoes");
+ req.set("o", "airius.com");
+ req.set("certtype", "client");
+ req.set("request", "issuance");
+ req.set("id", new Integer(10));
+ req.set("dualcerts", new Boolean(true));
+
+ Vector v = new Vector();
+ v.addElement("one");
+ v.addElement("two");
+ v.addElement("three");
+ req.set("count", v);
+ }
+ catch (Exception e){e.printStackTrace();}
+ String[] array = { "ou == people AND certtype == client",
+ "ou == servergroup AND certtype == server",
+ "uid == jdoes, ou==people, o==airius.com OR ou == people AND certType == client OR certType == server AND cn == needles.mcom.com",
+ };
+ for (int i = 0; i < array.length; i++)
+ {
+ System.out.println();
+ System.out.println("String: " + array[i]);
+ IExpression exp = null;
+ try
+ {
+ exp = parse(array[i]);
+ if (exp != null)
+ {
+ System.out.println("Parsed Expression: " + exp);
+ boolean result = exp.evaluate(req);
+ System.out.println("Result: " + result);
+ }
+ }
+ catch (Exception e) {e.printStackTrace(); }
+ }
+
+
+ try
+ {
+ BufferedReader rdr = new BufferedReader(
+ new FileReader(args[0]));
+ String line;
+ while((line=rdr.readLine()) != null)
+ {
+ System.out.println();
+ System.out.println("Line Read: " + line);
+ IExpression exp = null;
+ try
+ {
+ exp = parse(line);
+ if (exp != null)
+ {
+ System.out.println(exp);
+ boolean result = exp.evaluate(req);
+ System.out.println("Result: " + result);
+ }
+
+ }catch (Exception e){e.printStackTrace();}
+ }
+ }
+ catch (Exception e){e.printStackTrace(); }
+
+ *******/
+ }
+
+}
+
+
+class PredicateTokenizer {
+ String input;
+ int currentIndex;
+ int endOfString;
+ String nextToken;
+ boolean first;
+
+ public PredicateTokenizer(String predString) {
+ input = predString;
+ currentIndex = 0;
+ nextToken = null;
+ }
+
+ public boolean hasMoreTokens() {
+ return (currentIndex != -1);
+ }
+
+ public String nextToken() {
+ if (nextToken != null) {
+ String toReturn = nextToken;
+
+ nextToken = null;
+ return toReturn;
+ }
+
+ int andIndex = input.indexOf(" AND", currentIndex);
+
+ if (andIndex < 0)
+ andIndex = input.indexOf(" and", currentIndex);
+ int orIndex = input.indexOf(" OR", currentIndex);
+
+ if (orIndex < 0)
+ orIndex = input.indexOf(" or", currentIndex);
+ String toReturn = null;
+
+ if (andIndex == -1 && orIndex == -1) {
+ if (currentIndex == 0) {
+ currentIndex = -1;
+ toReturn = input;
+ } else {
+ int temp = currentIndex;
+
+ currentIndex = -1;
+ toReturn = input.substring(temp);
+ }
+ } else if (andIndex >= 0 && (andIndex < orIndex || orIndex == -1)) {
+ if (currentIndex != andIndex) {
+ toReturn = input.substring(currentIndex, andIndex);
+ nextToken = input.substring(andIndex + 1, andIndex + 4);
+ currentIndex = andIndex + 4;
+ } else {
+ toReturn = "AND";
+ currentIndex += 4;
+ }
+ } else if (orIndex >= 0 && (orIndex < andIndex || andIndex == -1)) {
+ if (currentIndex != orIndex) {
+ toReturn = input.substring(currentIndex, orIndex);
+ nextToken = input.substring(orIndex + 1, orIndex + 3);
+ currentIndex = orIndex + 3;
+ } else {
+ toReturn = "OR";
+ currentIndex += 3;
+ }
+ } else {
+ // Cannot happen; Assert here.
+ toReturn = null;
+ System.out.println("We shouldn't be here!");
+ }
+ if (toReturn == null)
+ return null;
+ else {
+ String trimmed = toReturn.trim();
+
+ if (trimmed == null || trimmed.length() == 0)
+ return nextToken();
+ else
+ return trimmed;
+ }
+ }
+}
+
+
+class AttributeSet implements IAttrSet {
+ Hashtable ht = new Hashtable();
+ public AttributeSet() {
+ }
+
+ public void delete(String name)
+ throws EBaseException {
+ Object ob = ht.get(name);
+
+ ht.remove(ob);
+ }
+
+ public Object get(String name)
+ throws EBaseException {
+ return ht.get(name);
+ }
+
+ public void set(String name, Object ob)
+ throws EBaseException {
+ ht.put(name, ob);
+ }
+
+ public Enumeration getElements() {
+ return ht.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/PolicySet.java b/pki/base/common/src/com/netscape/cmscore/policy/PolicySet.java
new file mode 100644
index 000000000..6ec1fa5c2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/PolicySet.java
@@ -0,0 +1,301 @@
+// --- 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.cmscore.policy;
+
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IExpression;
+import com.netscape.certsrv.policy.IPolicyRule;
+import com.netscape.certsrv.policy.IPolicySet;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * Implements a policy set per IPolicySet interface. This class
+ * uses a vector of ordered policies to enforce priority.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class PolicySet implements IPolicySet {
+ private String mName;
+ private Vector mRuleNames = new Vector();
+ private Vector mRules = new Vector();
+ private ILogger mLogger = CMS.getLogger();
+
+ public PolicySet(String name) {
+ mName = name;
+ }
+
+ /**
+ * Returns the name of the rule set.
+ * <P>
+ *
+ * @return The name of the rule set.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Returns the no of rules in a set.
+ * <P>
+ * @return the no of rules.
+ */
+ public int count() {
+ return mRules.size();
+ }
+
+ /**
+ * Add a policy rule.
+ * <P>
+ *
+ * @param ruleName The name of the rule to be added.
+ * @param rule The rule to be added.
+ */
+ public void addRule(String ruleName, IPolicyRule rule) {
+ if (mRuleNames.indexOf(ruleName) >= 0)
+ return; // XXX - Duplicate - Need to throw an exception.
+
+ if (ruleName != null && rule != null) {
+ mRuleNames.addElement(ruleName);
+ mRules.addElement(rule);
+ }
+ // XXX - TODO: else throw an exception.
+
+ }
+
+ /**
+ * Remplaces a policy rule identified by the given name.
+ *
+ * @param name The name of the rule to be replaced.
+ * @param rule The rule to be replaced.
+ */
+ public void replaceRule(String ruleName, IPolicyRule rule) {
+ int index = mRuleNames.indexOf(ruleName);
+
+ if (index < 0) {
+ addRule(ruleName, rule);
+ return;
+ }
+
+ mRuleNames.setElementAt(ruleName, index);
+ mRules.setElementAt(rule, index);
+ }
+
+ /**
+ * Removes a policy rule identified by the given name.
+ *
+ * @param name The name of the rule to be removed.
+ */
+ public void removeRule(String ruleName) {
+ int index = mRuleNames.indexOf(ruleName);
+
+ if (index < 0)
+ return; // XXX - throw an exception.
+
+ mRuleNames.removeElementAt(index);
+ mRules.removeElementAt(index);
+ }
+
+ /**
+ * Returns the rule identified by a given name.
+ * <P>
+ *
+ * @param name The name of the rule to be return.
+ * @return The rule identified by the given name or null if none exists.
+ */
+ public IPolicyRule getRule(String ruleName) {
+ int index = mRuleNames.indexOf(ruleName);
+
+ if (index < 0)
+ return null;
+ return (IPolicyRule) mRules.elementAt(index);
+ }
+
+ /**
+ * Returns an enumeration of rules.
+ * <P>
+ *
+ * @return An enumeration of rules.
+ */
+ public Enumeration getRules() {
+ return mRules.elements();
+ }
+
+ /**
+ * Apply policies on a given request from a rule set.
+ * The rules may modify the request.
+ *
+ * @param req The request to apply policies on.
+ * @return the PolicyResult.
+ */
+ public PolicyResult apply(IRequest req) {
+ // If there are no rules, we are done.
+ int cnt;
+
+ if ((cnt = mRules.size()) == 0)
+ return PolicyResult.ACCEPTED;
+
+ // All policies are applied before returning the result. Hence
+ // if atleast one of the policies returns a REJECTED, we need to
+ // return that status. If none of the policies REJECTED
+ // the request, but atleast one of them DEFERRED the request, we
+ // need to return DEFERRED.
+ boolean rejected = false;
+ boolean deferred = false;
+ int size = mRules.size();
+
+ for (int index = 0; index < size; index++) {
+ String name = (String) mRuleNames.elementAt(index);
+ IPolicyRule rule = (IPolicyRule) mRules.elementAt(index);
+ IExpression exp = rule.getPredicate();
+
+ try {
+ if (Debug.ON)
+ Debug.trace("evaluating predicate for rule " + rule.getName());
+ CMS.debug("PolicySet: apply()- evaluating predicate for rule " + rule.getName());
+ if (exp != null && !exp.evaluate(req))
+ continue;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (!typeMatched(rule, req))
+ continue;
+
+ try {
+ if (Debug.ON)
+ Debug.trace("Policy " + name + " selected");
+ CMS.debug("Policy " + name + " selected");
+ PolicyResult result = rule.apply(req);
+ CMS.debug("Policy applied");
+
+ if (Debug.ON)
+ Debug.trace("Policy " + name + " returned " + result);
+
+ if (result == PolicyResult.REJECTED) {
+ // It is hard to find out the owner at the moment unless
+ // we pass that info down the chain. For now use S_OTHER
+ // as the system id for the log entry.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_POLICY_REJECT_RESULT", req.getRequestId().toString(), name));
+ rejected = true;
+ } else if (result == PolicyResult.DEFERRED) {
+ // It is hard to find out the owner at the moment unless
+ // we pass that info down the chain. For now use S_OTHER
+ // as the system id for the log entry.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_WARN,
+ CMS.getLogMessage("CMSCORE_POLICY_DEFER_RESULT", req.getRequestId().toString(), name));
+ deferred = true;
+ } else if (result == PolicyResult.ACCEPTED) {
+ // It is hard to find out the owner at the moment unless
+ // we pass that info down the chain. For now use S_OTHER
+ // as the system id for the log entry.
+ } else {
+ // should not get to this status
+ // It is hard to find out the owner at the moment unless
+ // we pass that info down the chain. For now use S_OTHER
+ // as the system id for the log entry.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "policy: Request " + req.getRequestId() + " - Result of applying rule: " + name +
+ " is: " + getPolicyResult(result));
+ }
+ } catch (Throwable ex) {
+ // Customer can install his own policies.
+ // The policy may have bug. We want to
+ // catch those problems and report
+ // them to the log
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_POLICY_ERROR_RESULT", req.getRequestId().toString(), name, ex.toString()));
+ // treat as rejected to prevent request from going into
+ // a weird state. request queue doesn't handle this case.
+ rejected = true;
+ ((IPolicyRule) rule).setError(
+ req,
+ CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", rule.getName(), ex.toString()), null);
+ }
+ }
+
+ if (rejected) {
+ return PolicyResult.REJECTED;
+ } else if (deferred) {
+ return PolicyResult.DEFERRED;
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "Request " + req.getRequestId() +
+ " Policy result: successful");
+ return PolicyResult.ACCEPTED;
+ }
+ }
+
+ public void printPolicies() {
+ if (mRules.size() == 0)
+ return;
+ System.out.println("Policy Set Name: " + mName);
+ System.out.println();
+ int size = mRules.size();
+
+ for (int index = 0; index < size; index++) {
+ String ruleName = (String) mRuleNames.elementAt(index);
+
+ System.out.println("Rule Name: " + ruleName);
+ System.out.println("Implementation: " +
+ mRules.elementAt(index).getClass().getName());
+ }
+ }
+
+ String getPolicyResult(PolicyResult res) {
+ if (res == PolicyResult.ACCEPTED)
+ return "accepted";
+ else if (res == PolicyResult.DEFERRED)
+ return "deferred";
+ else if (res == PolicyResult.REJECTED)
+ return "rejected";
+ else
+ return "unknown";
+ }
+
+ boolean typeMatched(IPolicyRule rule, IRequest req) {
+
+ if (req.getExtDataInCertInfoArray(IRequest.CERT_INFO) != null) {
+ return true;
+ }
+
+ if (req.getExtDataInCertArray(IRequest.OLD_CERTS) != null) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java b/pki/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java
new file mode 100644
index 000000000..7b771442c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java
@@ -0,0 +1,435 @@
+// --- 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.cmscore.policy;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * This class represents an expression of the form var = val,
+ * var != val, var < val, var > val, var <= val, var >= val.
+ *
+ * Expressions are used as predicates for policy selection.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class SimpleExpression implements IExpression {
+ private String mPfx;
+ private String mVar;
+ private String mVal;
+ private String mPartialMatch;
+ private int mOp;
+ private boolean hasWildCard;
+ public static final char WILDCARD_CHAR = '*';
+
+ // This is just for indicating a null expression.
+ public static SimpleExpression NULL_EXPRESSION = new SimpleExpression("null", OP_EQUAL, "null");
+
+ public static IExpression parse(String input)
+ throws EPolicyException {
+ // Get the index of operator
+ // Debug.trace("SimpleExpression::input: " + input);
+ String var = null;
+ int op = -1;
+ String val = null;
+
+ // XXX - Kanda - Need to change this parsing code eventually.
+ ExpressionComps comps = parseForEquality(input);
+
+ if (comps == null)
+ comps = parseForInEquality(input);
+ if (comps == null)
+ comps = parseForGE(input);
+ if (comps == null)
+ comps = parseForLE(input);
+ if (comps == null)
+ comps = parseForGT(input);
+ if (comps == null)
+ comps = parseForLT(input);
+ if (comps == null)
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_BAD_POLICY_EXPRESSION", input));
+ String pfx = null;
+ String rawVar = comps.getAttr();
+ int dotIdx = rawVar.indexOf('.');
+
+ if (dotIdx != -1) {
+ pfx = rawVar.substring(0, dotIdx).trim();
+ var = rawVar.substring(dotIdx + 1).trim();
+ } else {
+ var = rawVar;
+ }
+ op = comps.getOp();
+ val = comps.getVal();
+ return new SimpleExpression(pfx, var, op, val);
+ }
+
+ public SimpleExpression(String var, int op, String val) {
+ this(null, var, op, val);
+ }
+
+ public SimpleExpression(String prefix, String var, int op, String val) {
+ // Assert that op has to be either IExpression.OP_EQUAL or
+ // IExpression.OP_NEQUAL.
+ // If val or var is null throw an exception!
+ mPfx = prefix;
+ mVar = var;
+ mOp = op;
+ mVal = val;
+ int firstIndex;
+
+ if ((firstIndex = mVal.indexOf(WILDCARD_CHAR)) >= 0) {
+ hasWildCard = true;
+ int nextIndex = mVal.indexOf(WILDCARD_CHAR, firstIndex + 1);
+
+ if (nextIndex == -1) {
+ if (firstIndex == 0)
+ mPartialMatch = mVal.substring(1);
+ else
+ mPartialMatch = mVal.substring(0, firstIndex);
+ } else
+ mPartialMatch = mVal.substring(firstIndex + 1, nextIndex);
+ } else
+ hasWildCard = false;
+ }
+
+ public boolean evaluate(IRequest req)
+ throws EPolicyException {
+ // mPfx and mVar are looked up case-indendently
+ String givenVal = req.getExtDataInString(mPfx, mVar);
+
+ if (Debug.ON)
+ Debug.trace("mPfx: " + mPfx + " mVar: " + mVar +
+ ",Given Value: " + givenVal + ", Value to compare with: " + mVal);
+
+ return matchValue(givenVal);
+ }
+
+ private boolean matchVector(Vector value)
+ throws EPolicyException {
+ boolean result = false;
+ Enumeration e = (Enumeration) value.elements();
+
+ for (; e.hasMoreElements();) {
+ result = matchValue(e.nextElement());
+ if (result)
+ break;
+ }
+ return result;
+ }
+
+ private boolean matchStringArray(String[] value)
+ throws EPolicyException {
+ boolean result = false;
+
+ for (int i = 0; i < value.length; i++) {
+ result = matchValue((Object) value[i]);
+ if (result)
+ break;
+ }
+ return result;
+ }
+
+ private boolean matchValue(Object value)
+ throws EPolicyException {
+ boolean result;
+
+ // There is nothing to compare with!
+ if (value == null)
+ return false;
+
+ // XXX - Kanda: We need a better way of handling this!.
+ if (value instanceof String)
+ result = matchStringValue((String) value);
+ else if (value instanceof Integer)
+ result = matchIntegerValue((Integer) value);
+ else if (value instanceof Boolean)
+ result = matchBooleanValue((Boolean) value);
+ else if (value instanceof Vector)
+ result = matchVector((Vector) value);
+ else if (value instanceof String[])
+ result = matchStringArray((String[]) value);
+ else
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_ATTR_VALUE",
+ value.getClass().getName()));
+ return result;
+ }
+
+ private boolean matchStringValue(String givenVal)
+ throws EPolicyException {
+ boolean result;
+
+ switch (mOp) {
+ case OP_EQUAL:
+ if (hasWildCard)
+ result = (givenVal.indexOf(mPartialMatch) >= 0);
+ else
+ result = givenVal.equalsIgnoreCase(mVal);
+ break;
+
+ case OP_NEQUAL:
+ if (hasWildCard)
+ result = (givenVal.indexOf(mPartialMatch) < 0);
+ else
+ result = !givenVal.equalsIgnoreCase(mVal);
+ break;
+
+ case OP_LT:
+ result = (givenVal.compareTo(mVal) < 0);
+ break;
+
+ case OP_GT:
+ result = (givenVal.compareTo(mVal) > 0);
+ break;
+
+ case OP_GE:
+ result = (givenVal.compareTo(mVal) >= 0);
+ break;
+
+ case OP_LE:
+ result = (givenVal.compareTo(mVal) >= 0);
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ private boolean matchIntegerValue(Integer intVal)
+ throws EPolicyException {
+ boolean result;
+ int storedVal;
+ int givenVal = intVal.intValue();
+
+ try {
+ storedVal = new Integer(mVal).intValue();
+ } catch (Exception e) {
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_ATTR_VALUE", mVal));
+
+ }
+ switch (mOp) {
+ case OP_EQUAL:
+ result = (givenVal == storedVal);
+ break;
+
+ case OP_NEQUAL:
+ result = (givenVal != storedVal);
+ break;
+
+ case OP_LT:
+ result = (givenVal < storedVal);
+ break;
+
+ case OP_GT:
+ result = (givenVal > storedVal);
+ break;
+
+ case OP_GE:
+ result = (givenVal >= storedVal);
+ break;
+
+ case OP_LE:
+ result = (givenVal >= storedVal);
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ private boolean matchBooleanValue(Boolean givenVal)
+ throws EPolicyException {
+ boolean result;
+ Boolean storedVal;
+
+ if (!(mVal.equalsIgnoreCase("true") ||
+ mVal.equalsIgnoreCase("false")))
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_ATTR_VALUE",
+ mVal));
+ storedVal = new Boolean(mVal);
+ switch (mOp) {
+ case OP_EQUAL:
+ result = (givenVal.equals(storedVal));
+ break;
+
+ case OP_NEQUAL:
+ case OP_LT:
+ case OP_GT:
+ case OP_GE:
+ case OP_LE:
+ result = (!givenVal.equals(storedVal));
+ break;
+
+ default:
+ throw new AssertionException("Invalid operation code");
+ }
+ return result;
+ }
+
+ public String toString() {
+ String op = null;
+
+ switch (mOp) {
+ case IExpression.OP_EQUAL:
+ op = IExpression.EQUAL_STR;
+ break;
+
+ case IExpression.OP_NEQUAL:
+ op = IExpression.NEQUAL_STR;
+ break;
+
+ case IExpression.OP_GT:
+ op = IExpression.GT_STR;
+ break;
+
+ case IExpression.OP_LT:
+ op = IExpression.LT_STR;
+ break;
+
+ case IExpression.OP_GE:
+ op = IExpression.GE_STR;
+ break;
+
+ case IExpression.OP_LE:
+ op = IExpression.LE_STR;
+ break;
+ }
+ if (mPfx != null && mPfx.length() > 0)
+ return mPfx + "." + mVar + " " + op + " " + mVal;
+ else
+ return mVar + " " + op + " " + mVal;
+ }
+
+ private static ExpressionComps parseForEquality(String expression) {
+ int index = expression.indexOf(IExpression.EQUAL_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_EQUAL;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForInEquality(String expression) {
+ int index = expression.indexOf(IExpression.NEQUAL_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_NEQUAL;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForGT(String expression) {
+ int index = expression.indexOf(IExpression.GT_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_GT;
+ String val = expression.substring(index + 1).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForLT(String expression) {
+ int index = expression.indexOf(IExpression.LT_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_LT;
+ String val = expression.substring(index + 1).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForGE(String expression) {
+ int index = expression.indexOf(IExpression.GE_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_GE;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+
+ private static ExpressionComps parseForLE(String expression) {
+ int index = expression.indexOf(IExpression.LE_STR);
+
+ if (index < 0)
+ return null;
+ else {
+ String attr = expression.substring(0, index).trim();
+ int op = OP_LE;
+ String val = expression.substring(index + 2).trim();
+
+ return new ExpressionComps(attr, op, val);
+ }
+ }
+}
+
+
+class ExpressionComps {
+ String attr;
+ int op;
+ String val;
+
+ public ExpressionComps(String a, int o, String v) {
+ attr = a;
+ op = o;
+ val = v;
+ }
+
+ public String getAttr() {
+ return attr;
+ }
+
+ public int getOp() {
+ return op;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java b/pki/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java
new file mode 100644
index 000000000..25635e901
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java
@@ -0,0 +1,319 @@
+// --- 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.cmscore.profile;
+
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.registry.*;
+import com.netscape.certsrv.profile.*;
+
+
+public class ProfileSubsystem implements IProfileSubsystem {
+ private static final String PROP_LIST = "list";
+ private static final String PROP_CLASS_ID = "class_id";
+ private static final String PROP_CONFIG = "config";
+ private static final String PROP_CHECK_OWNER = "checkOwner";
+
+ private static final String PROP_ENABLE = "enable";
+ private static final String PROP_ENABLE_BY = "enableBy";
+
+ private IConfigStore mConfig = null;
+ private ISubsystem mOwner = null;
+ private Vector mProfileIds = new Vector();
+ private Hashtable mProfiles = new Hashtable();
+ private Hashtable mProfileClassIds = new Hashtable();
+
+ /**
+ * Retrieves the name of this subsystem.
+ */
+ public String getId() {
+ return null;
+ }
+
+ /**
+ * Sets specific to this subsystem.
+ */
+ public void setId(String id) throws EBaseException {
+ }
+
+ /**
+ * Initializes this subsystem with the given configuration
+ * store.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ CMS.debug("ProfileSubsystem: start init");
+ IPluginRegistry registry = (IPluginRegistry)
+ CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+
+ mConfig = config;
+ mOwner = owner;
+
+ // Configuration File Format:
+ // *.list=profile1,profile2
+ // *.profile1.class=com.netscape.cms.profile.common.BasicProfile
+ // *.profile1.config=config/profiles/profile1.cfg
+ // *.profile2.class=com.netscape.cms.profile.common.BasicProfile
+ // *.profile2.config=config/profiles/profile2.cfg
+
+ // read profile id, implementation, and its configuration files
+ String ids = config.getString(PROP_LIST, "");
+ StringTokenizer st = new StringTokenizer(ids, ",");
+
+ while (st.hasMoreTokens()) {
+ String id = (String) st.nextToken();
+ IConfigStore subStore = config.getSubStore(id);
+ String classid = subStore.getString(PROP_CLASS_ID);
+ IPluginInfo info = registry.getPluginInfo("profile", classid);
+ String configPath = subStore.getString(PROP_CONFIG);
+
+ CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName());
+ IProfile profile = createProfile(id, classid, info.getClassName(),
+ configPath);
+
+ CMS.debug("Done Profile Creation - " + id);
+ }
+
+ Enumeration ee = getProfileIds();
+
+ while (ee.hasMoreElements()) {
+ String id = (String) ee.nextElement();
+
+ CMS.debug("Registered Confirmation - " + id);
+ }
+ }
+
+ /**
+ * Creates a profile instance.
+ */
+ public IProfile createProfile(String id, String classid, String className,
+ String configPath)
+ throws EProfileException {
+ IProfile profile = null;
+
+ try {
+ profile = (IProfile) Class.forName(className).newInstance();
+ IConfigStore subStoreConfig = CMS.createFileConfigStore(configPath);
+
+ CMS.debug("ProfileSubsystem: initing " + className);
+ profile.setId(id);
+ profile.init(this, subStoreConfig);
+ mProfileIds.addElement(id);
+ mProfiles.put(id, profile);
+ mProfileClassIds.put(id, classid);
+ return profile;
+ } catch (Exception e) {
+ // throw exceptions
+ CMS.debug(e.toString());
+ CMS.debug(e);
+ }
+ return null;
+ }
+
+ public void deleteProfile(String id, String configPath) throws EProfileException {
+
+ if (isProfileEnable(id)) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE");
+ }
+
+ String ids = "";
+ try {
+ ids = mConfig.getString(PROP_LIST, "");
+ } catch (Exception e) {
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(ids, ",");
+ String list = "";
+
+ while (tokenizer.hasMoreTokens()) {
+ String element = (String) tokenizer.nextToken();
+
+ if (!element.equals(id)) {
+ list = list + element + ",";
+ }
+ }
+ if (!list.equals(""))
+ list = list.substring(0, list.length() - 1);
+
+ mConfig.putString(PROP_LIST, list);
+ mConfig.removeSubStore(id);
+ File file1 = new File(configPath);
+
+ file1.delete();
+ mProfileIds.removeElement(id);
+ mProfiles.remove(id);
+ mProfileClassIds.remove(id);
+ try {
+ CMS.getConfigStore().commit(false);
+ } catch (Exception e) {
+ }
+ }
+
+ public void createProfileConfig(String id, String classId,
+ String configPath)
+ throws EProfileException {
+ try {
+ if (mProfiles.size() > 0) {
+ mConfig.putString(PROP_LIST,
+ mConfig.getString(PROP_LIST) + "," + id);
+ } else {
+ mConfig.putString(PROP_LIST, id);
+ }
+ mConfig.putString(id + "." + PROP_CLASS_ID, classId);
+ mConfig.putString(id + "." + PROP_CONFIG, configPath);
+ CMS.getConfigStore().commit(true);
+ } catch (EBaseException e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ */
+ public void startup() throws EBaseException {
+ CMS.debug("ProfileSubsystem: startup");
+ }
+
+ /**
+ * Stops this system. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown() {
+ mProfileIds.removeAllElements();
+ mProfiles.clear();
+ mProfiles = null;
+ mProfileClassIds.clear();
+ mProfileClassIds = null;
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Adds a profile.
+ */
+ public void addProfile(String id, IProfile profile)
+ throws EProfileException {
+ }
+
+ public boolean isProfileEnable(String id) {
+ IProfile profile = (IProfile) mProfiles.get(id);
+ String enable = null;
+
+ try {
+ enable = profile.getConfigStore().getString(PROP_ENABLE);
+ } catch (EBaseException e) {
+ }
+ if (enable == null || enable.equals("false"))
+ return false;
+ else
+ return true;
+ }
+
+ public String getProfileEnableBy(String id) {
+ if (!isProfileEnable(id))
+ return null;
+ IProfile profile = (IProfile) mProfiles.get(id);
+ String enableBy = null;
+
+ try {
+ enableBy = profile.getConfigStore().getString(PROP_ENABLE_BY);
+ } catch (EBaseException e) {
+ }
+ return enableBy;
+ }
+
+ /**
+ * Enables a profile for execution.
+ */
+ public void enableProfile(String id, String enableBy)
+ throws EProfileException {
+ IProfile profile = (IProfile) mProfiles.get(id);
+
+ profile.getConfigStore().putString(PROP_ENABLE, "true");
+ profile.getConfigStore().putString(PROP_ENABLE_BY, enableBy);
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * Disables a profile for execution.
+ */
+ public void disableProfile(String id)
+ throws EProfileException {
+ IProfile profile = (IProfile) mProfiles.get(id);
+
+ profile.getConfigStore().putString(PROP_ENABLE, "false");
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * Retrieves a profile by id.
+ */
+ public IProfile getProfile(String id)
+ throws EProfileException {
+ return (IProfile) mProfiles.get(id);
+ }
+
+ public String getProfileClassId(String id) {
+ return (String) mProfileClassIds.get(id);
+ }
+
+ /**
+ * Retrieves a list of profile ids. The return
+ * list is of type String.
+ */
+ public Enumeration getProfileIds() {
+ return mProfileIds.elements();
+ }
+
+ /**
+ * Checks if owner id should be enforced during profile approval.
+ *
+ * @return true if approval should be checked
+ */
+ public boolean checkOwner()
+ {
+ try {
+ return mConfig.getBoolean(PROP_CHECK_OWNER, false);
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/registry/PluginInfo.java b/pki/base/common/src/com/netscape/cmscore/registry/PluginInfo.java
new file mode 100644
index 000000000..d0ed9324e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/registry/PluginInfo.java
@@ -0,0 +1,54 @@
+// --- 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.cmscore.registry;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.registry.*;
+
+
+/**
+ * The plugin information includes id, name,
+ * classname, and description.
+ *
+ * @author thomask
+ */
+public class PluginInfo implements IPluginInfo {
+ private String mName = null;
+ private String mDesc = null;
+ private String mClassPath = null;
+
+ public PluginInfo(String name, String desc, String classPath) {
+ mName = name;
+ mDesc = desc;
+ mClassPath = classPath;
+ }
+
+ public String getName(Locale locale) {
+ return mName;
+ }
+
+ public String getDescription(Locale locale) {
+ return mDesc;
+ }
+
+ public String getClassName() {
+ return mClassPath;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java b/pki/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java
new file mode 100644
index 000000000..a424d8b73
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java
@@ -0,0 +1,287 @@
+// --- 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.cmscore.registry;
+
+
+import java.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.registry.*;
+
+
+public class PluginRegistry implements IPluginRegistry {
+
+ private static final String PROP_TYPES = "types";
+ private static final String PROP_IDS = "ids";
+ private static final String PROP_NAME = "name";
+ private static final String PROP_DESC = "desc";
+ private static final String PROP_CLASSPATH = "class";
+ private static final String PROP_FILE = "file";
+
+ private IConfigStore mConfig = null;
+ private IConfigStore mFileConfig = null;
+ private ISubsystem mOwner = null;
+ private Hashtable mTypes = new Hashtable();
+
+ public PluginRegistry() {
+ }
+
+ /**
+ * Retrieves the name of this subsystem.
+ */
+ public String getId() {
+ return null;
+ }
+
+ /**
+ * Sets specific to this subsystem.
+ */
+ public void setId(String id) throws EBaseException {
+ }
+
+ /**
+ * Initializes this subsystem with the given configuration
+ * store.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ CMS.debug("RegistrySubsystem: start init");
+ mConfig = config;
+ mOwner = owner;
+
+ mFileConfig = CMS.createFileConfigStore(
+ mConfig.getString(PROP_FILE));
+
+ String types_str = null;
+
+ try {
+ types_str = mFileConfig.getString(PROP_TYPES, null);
+ } catch (EBaseException e) {
+ }
+ if (types_str == null) {
+ CMS.debug("PluginRegistry: no types");
+ return;
+ }
+ StringTokenizer st = new StringTokenizer(types_str, ",");
+
+ while (st.hasMoreTokens()) {
+ String type = st.nextToken();
+
+ loadPlugins(config, type);
+ }
+ }
+
+ /**
+ * Load plugins of the given type.
+ */
+ public void loadPlugins(IConfigStore config, String type)
+ throws EBaseException {
+ String ids_str = null;
+
+ try {
+ ids_str = mFileConfig.getString(type + "." + PROP_IDS, null);
+ } catch (EBaseException e) {
+ }
+ if (ids_str == null) {
+ return;
+ }
+ StringTokenizer st = new StringTokenizer(ids_str, ",");
+
+ while (st.hasMoreTokens()) {
+ String id = st.nextToken();
+
+ loadPlugin(config, type, id);
+ }
+ }
+
+
+ public IPluginInfo createPluginInfo(String name, String desc, String classPath) {
+ return new PluginInfo(name, desc, classPath);
+ }
+
+ /**
+ * Load plugins of the given type.
+ */
+ public void loadPlugin(IConfigStore config, String type, String id)
+ throws EBaseException {
+ String name = null;
+
+ try {
+ name = mFileConfig.getString(type + "." + id + "." + PROP_NAME, null);
+ } catch (EBaseException e) {
+ }
+ String desc = null;
+
+ try {
+ desc = mFileConfig.getString(type + "." + id + "." + PROP_DESC, null);
+ } catch (EBaseException e) {
+ }
+ String classpath = null;
+
+ try {
+ classpath = mFileConfig.getString(type + "." + id + "." + PROP_CLASSPATH,
+ null);
+ } catch (EBaseException e) {
+ }
+ PluginInfo info = new PluginInfo(name, desc, classpath);
+
+ addPluginInfo(type, id, info, 0);
+ }
+
+ public void removePluginInfo(String type, String id)
+ throws ERegistryException {
+ Hashtable plugins = (Hashtable)mTypes.get(type);
+ if (plugins == null)
+ return;
+ plugins.remove(id);
+ Locale locale = Locale.getDefault();
+ rebuildConfigStore(locale);
+ }
+
+ public void addPluginInfo(String type, String id, IPluginInfo info)
+ throws ERegistryException {
+ addPluginInfo(type, id, info, 1);
+ }
+
+ public void addPluginInfo(String type, String id, IPluginInfo info, int saveConfig)
+ throws ERegistryException {
+ Hashtable plugins = (Hashtable) mTypes.get(type);
+
+ if (plugins == null) {
+ plugins = new Hashtable();
+ mTypes.put(type, plugins);
+ }
+ Locale locale = Locale.getDefault();
+
+ CMS.debug("added plugin " + type + " " + id + " " +
+ info.getName(locale) + " " + info.getDescription(locale) + " " +
+ info.getClassName());
+ plugins.put(id, info);
+
+ // rebuild configuration store
+ if (saveConfig == 1) rebuildConfigStore(locale);
+ }
+
+ public void rebuildConfigStore(Locale locale)
+ throws ERegistryException {
+ Enumeration types = mTypes.keys();
+ StringBuffer typesBuf = new StringBuffer();
+
+ while (types.hasMoreElements()) {
+ String type = (String) types.nextElement();
+
+ typesBuf.append(type);
+ if (types.hasMoreElements()) {
+ typesBuf.append(",");
+ }
+ Hashtable mPlugins = (Hashtable) mTypes.get(type);
+ StringBuffer idsBuf = new StringBuffer();
+ Enumeration plugins = mPlugins.keys();
+
+ while (plugins.hasMoreElements()) {
+ String id = (String) plugins.nextElement();
+
+ idsBuf.append(id);
+ if (plugins.hasMoreElements()) {
+ idsBuf.append(",");
+ }
+ IPluginInfo plugin = (IPluginInfo) mPlugins.get(id);
+
+ mFileConfig.putString(type + "." + id + ".class",
+ plugin.getClassName());
+ mFileConfig.putString(type + "." + id + ".name",
+ plugin.getName(locale));
+ mFileConfig.putString(type + "." + id + ".desc",
+ plugin.getDescription(locale));
+ }
+ mFileConfig.putString(type + ".ids", idsBuf.toString());
+ }
+ mFileConfig.putString("types", typesBuf.toString());
+ try {
+ mFileConfig.commit(false);
+ } catch (EBaseException e) {
+ CMS.debug("PluginRegistry: failed to commit registry.cfg");
+ }
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ */
+ public void startup() throws EBaseException {
+ CMS.debug("RegistrySubsystem: startup");
+ }
+
+ /**
+ * Stops this system. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown() {
+ mTypes.clear();
+ mTypes = null;
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public IConfigStore getFileConfigStore() {
+ return mFileConfig;
+ }
+
+ /**
+ * Returns all type names.
+ */
+ public Enumeration getTypeNames() {
+ return mTypes.keys();
+ }
+
+ /**
+ * Returns a list of identifiers of the given type.
+ */
+ public Enumeration getIds(String type) {
+ Hashtable plugins = (Hashtable) mTypes.get(type);
+
+ if (plugins == null)
+ return null;
+ return plugins.keys();
+ }
+
+ /**
+ * Retrieves the plugin information.
+ */
+ public IPluginInfo getPluginInfo(String type, String id) {
+ Hashtable plugins = (Hashtable) mTypes.get(type);
+
+ if (plugins == null)
+ return null;
+ return (IPluginInfo) plugins.get(id);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/ARequestQueue.java b/pki/base/common/src/com/netscape/cmscore/request/ARequestQueue.java
new file mode 100644
index 000000000..f6d23497a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/ARequestQueue.java
@@ -0,0 +1,1540 @@
+// --- 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.cmscore.request;
+
+
+import java.util.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CRLException;
+import java.math.BigInteger;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.base.IAttrSet;
+
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authentication.AuthToken;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509ExtensionException;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.util.DerInputStream;
+
+
+/**
+ * The ARequestQueue class is an abstract class that implements
+ * most portions of the IRequestQueue interface. This includes
+ * the state engine as defined for processing IRequest objects.
+ * <p>
+ * !Put state machine description here!
+ * <p>
+ * This class defines several abstract protected functions that
+ * need to be defined by the concrete implementation. In
+ * particular, this class does not implement the operations
+ * for storing requests persistantly.
+ * <p>
+ * This class also provides several accessor functions for setting
+ * fields in the IRequest object. These functions are provided
+ * as an aid to saving and restoring the state in the database.
+ * <p>
+ * This class also implements the locking operations specified by
+ * the IRequestQueue interface.
+ * <p>
+ * @author thayes
+ * @version $Revision$ $Date$
+ */
+public abstract class ARequestQueue
+ implements IRequestQueue {
+
+ /**
+ * global request version for tracking request changes.
+ */
+ public final static String REQUEST_VERSION = "1.0.0";
+
+ /**
+ * Create a new (unique) RequestId. (abstract)
+ * <p>
+ * This method must be implemented by the specialized class to
+ * generate a new id from data in the persistant store. This id
+ * is used to create a new request object.
+ * <p>
+ * @return
+ * a new RequestId object.
+ * @exception EBaseException
+ * indicates that creation of the new id could not be completed.
+ * @see RequestId
+ */
+ protected abstract RequestId newRequestId()
+ throws EBaseException;
+
+ /**
+ * Read a request from the persistant store. (abstract)
+ * <p>
+ * This function is called to create the in-memory version of
+ * a request object.
+ * <p>
+ * The implementation of this object can use the createRequest
+ * member function to create a new instance of an IRequest, and
+ * use the setRequestStatus, setCreationTime and setModificationTime
+ * functions to set those values.
+ * <p>
+ * @param id
+ * the id of the request to read.
+ * @return
+ * a new IRequest object. null is returned if the object cannot
+ * be located.
+ * @exception EBaseException
+ * TODO: this is not implemented yet
+ * @see #createRequest
+ * @see #setRequestStatus
+ * @see #setModificationTime
+ * @see #setCreationTime
+ */
+ protected abstract IRequest readRequest(RequestId id);
+
+ /**
+ * Add the request to the store. (abstract)
+ * <p>
+ * This function is called when a new request immediately after
+ * creating a new request.
+ * <p>
+ * @param request
+ * the request to add.
+ * @exception EBaseException
+ * TODO: this is not implemented yet
+ */
+ protected abstract void addRequest(IRequest request) throws EBaseException;
+
+ /**
+ * Modify the request in the store. (abstract)
+ * <p>
+ * Update the persistant copy of this request with the
+ * current values in the object.
+ * <p>
+ * Currently there are no hints for what has changed, so
+ * the entire request should be updated.
+ * <p>
+ * @param request
+ * @exception EBaseException
+ * TODO: this is not implemented yet
+ */
+ protected abstract void modifyRequest(IRequest request);
+
+ /**
+ * Get complete list of RequestId values found i this
+ * queue.
+ * <p>
+ * This method can form the basis for creating other types
+ * of search/list operations (although there are probably more
+ * efficient ways of doing this. ARequestQueue implements
+ * default versions of some of the searching by using this
+ * method as a basis.
+ * <p>
+ * TODO: return IRequestList -or- just use listRequests as
+ * the basic engine.
+ * <p>
+ * @return
+ * an Enumeration that generates RequestId objects.
+ */
+ abstract protected Enumeration getRawList();
+
+ /**
+ * protected access for setting the current state of a request.
+ * <p>
+ * @param request
+ * The request to be modified.
+ * @param status
+ * The new value for the request status.
+ */
+ protected final void setRequestStatus(IRequest request, RequestStatus status) {
+ Request r = (Request) request;
+
+ r.setRequestStatus(status);
+ }
+
+ /**
+ * protected access for setting the modification time of a request.
+ * <p>
+ * @param request
+ * The request to be modified.
+ * @param date
+ * The new value for the time.
+ */
+ protected final void setModificationTime(IRequest request, Date date) {
+ Request r = (Request) request;
+
+ r.mModificationTime = date;
+ }
+
+ /**
+ * protected access for setting the creation time of a request.
+ * <p>
+ * @param request
+ * The request to be modified.
+ * @param date
+ * The new value for the time.
+ */
+ protected final void setCreationTime(IRequest request, Date date) {
+ Request r = (Request) request;
+
+ r.mCreationTime = date;
+ }
+
+ /**
+ * protected access for creating a new Request object
+ * <p>
+ * @param id
+ * The identifier for the new request
+ * @return
+ * A new request object. The caller should fill in other data
+ * values from the datastore.
+ */
+ protected final IRequest createRequest(RequestId id, String requestType) {
+ Request r;
+
+ /*
+ * Determine the specialized class to create for this type
+ *
+ * TODO: this set of classes is an example only. The real set
+ * needs to be determined and implemented.
+ */
+ if (requestType != null && requestType.equals("enrollment")) {
+ r = new EnrollmentRequest(id);
+ } else {
+ r = new Request(id);
+ }
+
+ return r;
+ }
+
+ /**
+ * Implements IRequestQueue.newRequest
+ * <p>
+ * @see IRequestQueue#newRequest
+ */
+ public IRequest newRequest(String requestType)
+ throws EBaseException {
+ if (requestType == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_REQUEST_TYPE", "null"));
+ }
+ RequestId rId = newRequestId();
+ IRequest r = createRequest(rId, requestType);
+
+ // Commented out the lock call because unlock is never called.
+ // mTable.lock(rId);
+
+ // TODO: move this to the first update. This will require
+ // some state information to track the current state.
+ r.setRequestType(requestType);
+ r.setExtData(IRequest.REQ_VERSION, REQUEST_VERSION);
+
+ // NOT_UPDATED mean request is in memory and has
+ // not been serialized to database yet. An add
+ // operation is required to serialize a NOT_UPDATED
+ // request.
+ r.setExtData("dbStatus", "NOT_UPDATED");
+ // addRequest(r);
+
+ // expose requestId to policy so that it can be
+ // used with predicate
+ r.setExtData("requestId", rId.toString());
+
+ return r;
+ }
+
+ /**
+ * Implements IRequestQueue.cloneRequest
+ * <p>
+ * @see IRequestQueue#cloneRequest
+ */
+ public IRequest cloneRequest(IRequest r)
+ throws EBaseException {
+ // 1. check for valid state. (Are any invalid ?)
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs == RequestStatus.BEGIN) throw new EBaseException("Invalid Status");
+
+ // 2. create new request
+ String reqType = r.getRequestType();
+ IRequest clone = newRequest(reqType);
+
+ // 3. copy all attributes of original request to clone and modify.
+ // source id (from remote authority) is not copied.
+ // TODO: set the original request id to some place in the request.
+ clone.copyContents(r);
+ // NOT_UPDATED mean request is in memory and has
+ // not been serialized to database yet. An add
+ // operation is required to serialize a NOT_UPDATED
+ // request.
+ clone.setExtData("dbStatus", "NOT_UPDATED");
+
+ return clone;
+ }
+
+ /**
+ * Implements IRequestQueue.findRequest
+ * <p>
+ * @see IRequestQueue#findRequest
+ */
+ public IRequest findRequest(RequestId id)
+ throws EBaseException {
+ IRequest r;
+
+ // mTable.lock(id);
+
+ r = readRequest(id);
+
+ // if (r == null) mTable.unlock(id);
+
+ return r;
+ }
+
+ private IRequestScheduler mRequestScheduler = null;
+
+ public void setRequestScheduler(IRequestScheduler scheduler) {
+ mRequestScheduler = scheduler;
+ }
+
+ public IRequestScheduler getRequestScheduler() {
+ return mRequestScheduler;
+ }
+
+ /**
+ * Implements IRequestQueue.processRequest
+ * <p>
+ * @see IRequestQueue#processRequest
+ */
+ public final void processRequest(IRequest r)
+ throws EBaseException {
+
+ // #610553 Thread Scheduler
+ IRequestScheduler scheduler = getRequestScheduler();
+
+ if (scheduler != null) {
+ scheduler.requestIn(r);
+ }
+
+ try {
+ // 1. Check for valid state
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs != RequestStatus.BEGIN) throw new EBaseException("Invalid Status");
+
+ stateEngine(r);
+ } finally {
+ if (scheduler != null) {
+ scheduler.requestOut(r);
+ }
+ }
+ }
+
+ /**
+ * Implements IRequestQueue.markRequestPending
+ * <p>
+ * @see IRequestQueue#markRequestPending
+ */
+ public final void markRequestPending(IRequest r)
+ throws EBaseException {
+ // 1. Check for valid state
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs != RequestStatus.BEGIN) throw new EBaseException("Invalid Status");
+
+ // 2. Change the request state. This method of making
+ // a request PENDING does NOT invoke the PENDING notifiers.
+ // To change this, just call stateEngine at the completion of this
+ // routine.
+ setRequestStatus(r, RequestStatus.PENDING);
+
+ updateRequest(r);
+ stateEngine(r);
+ }
+
+ /**
+ * Implements IRequestQueue.cloneAndMarkPending
+ * <p>
+ * @see IRequestQueue#cloneAndMarkPending
+ */
+ public IRequest cloneAndMarkPending(IRequest r)
+ throws EBaseException {
+ IRequest clone = cloneRequest(r);
+
+ markRequestPending(clone);
+ return clone;
+ }
+
+ /**
+ * Implements IRequestQueue.approveRequest
+ * <p>
+ * @see IRequestQueue#approveRequest
+ */
+ public final void approveRequest(IRequest r)
+ throws EBaseException {
+ // 1. Check for valid state
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs != RequestStatus.PENDING) throw new EBaseException("Invalid Status");
+
+ AgentApprovals aas = AgentApprovals.fromStringVector(
+ r.getExtDataInStringVector(AgentApprovals.class.getName()));
+ if (aas == null) {
+ aas = new AgentApprovals();
+ }
+
+ // Record agent who did this
+ String agentName = getUserIdentity();
+
+ if (agentName == null) throw new EBaseException("Missing agent information");
+
+ aas.addApproval(agentName);
+ r.setExtData(AgentApprovals.class.getName(), aas.toStringVector());
+
+ PolicyResult pr = mPolicy.apply(r);
+
+ if (pr == PolicyResult.ACCEPTED) {
+ setRequestStatus(r, RequestStatus.APPROVED);
+ } else if (pr == PolicyResult.DEFERRED ||
+ pr == PolicyResult.REJECTED) {
+ }
+
+ // Always update. The policy code may have made changes to the
+ // request that we want to keep.
+ updateRequest(r);
+
+ stateEngine(r);
+ }
+
+ /**
+ * Implements IRequestQueue.rejectRequest
+ * <p>
+ * @see IRequestQueue#rejectRequest
+ */
+ public final void rejectRequest(IRequest r)
+ throws EBaseException {
+ // 1. Check for valid state
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs != RequestStatus.PENDING) throw new EBaseException("Invalid Status");
+
+ // 2. Change state
+ setRequestStatus(r, RequestStatus.REJECTED);
+ updateRequest(r);
+
+ // 3. Continue processing
+ stateEngine(r); // does nothing
+ }
+
+ /**
+ * Implments IRequestQueue.cancelRequest
+ * <p>
+ * @see IRequestQueue#cancelRequest
+ */
+ public final void cancelRequest(IRequest r)
+ throws EBaseException {
+ setRequestStatus(r, RequestStatus.CANCELED);
+ updateRequest(r);
+
+ stateEngine(r);
+
+ return;
+ }
+
+ /**
+ * caller must lock request and release request
+ */
+ public final void markAsServiced(IRequest r) {
+ setRequestStatus(r, RequestStatus.COMPLETE);
+ updateRequest(r);
+
+ if (mNotify != null) mNotify.notify(r);
+
+ return;
+ }
+
+ /**
+ * Implements IRequestQueue.listRequests
+ * <p>
+ * Should be overridden by the specialized class if
+ * a more efficient method is available for implementing
+ * this operation.
+ * <P>
+ * @see IRequestQueue#listRequests
+ */
+ public IRequestList listRequests() {
+ return new RequestList(getRawList());
+ }
+
+ /**
+ * Implements IRequestQueue.listRequestsByStatus
+ * <p>
+ * Should be overridden by the specialized class if
+ * a more efficient method is available for implementing
+ * this operation.
+ * <P>
+ * @see IRequestQueue#listRequestsByStatus
+ */
+ public IRequestList listRequestsByStatus(RequestStatus s) {
+ return new RequestListByStatus(getRawList(), s, this);
+ }
+
+ /**
+ * Implements IRequestQueue.releaseRequest
+ * <p>
+ * @see IRequestQueue#releaseRequest
+ */
+ public final void releaseRequest(IRequest request) {
+ // mTable.unlock(request.getRequestId());
+ }
+
+ public void updateRequest(IRequest r) {
+ ((Request) r).mModificationTime = CMS.getCurrentDate();
+
+ String name = getUserIdentity();
+
+ if (name != null) r.setExtData(IRequest.UPDATED_BY, name);
+
+ // TODO: use a state flag to determine whether to call
+ // addRequest or modifyRequest (see newRequest as well)
+ modifyRequest(r);
+ }
+
+ // PRIVATE functions
+
+ private final void stateEngine(IRequest r)
+ throws EBaseException {
+ boolean complete = false;
+
+ while (!complete) {
+ RequestStatus rs = r.getRequestStatus();
+
+ if (rs == RequestStatus.BEGIN) {
+ PolicyResult pr = PolicyResult.ACCEPTED;
+
+ if (mPolicy != null)
+ pr = mPolicy.apply(r);
+
+ if (pr == PolicyResult.ACCEPTED) {
+ setRequestStatus(r, RequestStatus.APPROVED);
+ } else if (pr == PolicyResult.DEFERRED) {
+ setRequestStatus(r, RequestStatus.PENDING);
+ } else {
+ setRequestStatus(r, RequestStatus.REJECTED);
+ }
+
+ // if policy accepts the request, the request
+ // will be processed right away. So speed up
+ // the request processing, we do not want to
+ // have too many db operation.
+ if (pr != PolicyResult.ACCEPTED) {
+ updateRequest(r);
+ }
+ } else if (rs == RequestStatus.PENDING) {
+ if (mPendingNotify != null)
+ mPendingNotify.notify(r);
+
+ complete = true;
+ } else if (rs == RequestStatus.APPROVED) {
+ boolean svcComplete;
+
+ svcComplete = mService.serviceRequest(r);
+
+ // Completed requests call the notifier and are done. Others
+ // wait for the serviceComplete call.
+ if (svcComplete) {
+ setRequestStatus(r, RequestStatus.COMPLETE);
+ } else {
+ setRequestStatus(r, RequestStatus.SVC_PENDING);
+ }
+
+ updateRequest(r);
+ } else if (rs == RequestStatus.SVC_PENDING) {
+ complete = true;
+ } else if (rs == RequestStatus.CANCELED) {
+ if (mNotify != null)
+ mNotify.notify(r);
+
+ complete = true;
+ } else if (rs == RequestStatus.REJECTED) {
+ if (mNotify != null)
+ mNotify.notify(r);
+
+ complete = true;
+ } else if (rs == RequestStatus.COMPLETE) {
+ if (mNotify != null)
+ mNotify.notify(r);
+
+ complete = true;
+ }
+ }
+ }
+
+ /**
+ * log a change in the request status
+ */
+ protected void logChange(IRequest request) {
+ // write the queue name and request id
+ // write who changed it
+ // write what change (which state change) was made
+ // - new (processRequest)
+ // - approve
+ // - reject
+
+ // Ordering
+ // - make change in memory
+ // - log change and result
+ // - update record
+ }
+
+ /**
+ * get the identity of the current user
+ */
+ protected String getUserIdentity() {
+ // Record agent who did this
+ SessionContext s = SessionContext.getContext();
+ String name = (String) s.get(SessionContext.USER_ID);
+
+ return name;
+ }
+
+ /**
+ * New non-blocking recover method.
+ */
+ public void recover() {
+ if (CMS.isRunningMode()) {
+ RecoverThread t = new RecoverThread(this);
+
+ t.start();
+ }
+ }
+
+ /**
+ * recover from a crash. Resends all requests that are in
+ * the APPROVED state.
+ */
+ public void recoverWillBlock() {
+ // Get a list of all requests that are APPROVED
+ IRequestList list = listRequestsByStatus(RequestStatus.APPROVED);
+
+ while (list != null && list.hasMoreElements()) {
+ RequestId rid = list.nextRequestId();
+ IRequest request;
+
+ try {
+ request = findRequest(rid);
+
+ //if (request == null) log_error
+
+ // Recheck the status - should be the same!!
+ if (request.getRequestStatus() == RequestStatus.APPROVED) {
+ stateEngine(request);
+ }
+
+ releaseRequest(request);
+ } catch (EBaseException e) {
+ // log
+ }
+ }
+ }
+
+ public INotify getPendingNotify() {
+ return mPendingNotify;
+ }
+
+ // Constructor
+ protected ARequestQueue(IPolicy policy, IService service, INotify notify,
+ INotify pendingNotify) {
+ mPolicy = policy;
+ mService = service;
+ mNotify = notify;
+ mPendingNotify = pendingNotify;
+
+ mLogger = CMS.getLogger();
+ }
+
+ // Instance variables
+ // RequestIDTable mTable = new RequestIDTable();
+
+ IPolicy mPolicy;
+ IService mService;
+ INotify mNotify;
+ INotify mPendingNotify;
+
+ protected ILogger mLogger;
+}
+
+
+//
+// Table of RequestId values that are currently in use by some thread.
+// The fact that the request is in this table constitutes a lock
+// on the value.
+//
+/*
+ class RequestIDTable {
+ public synchronized void lock(RequestId id) {
+ while (true) {
+ if (mHashtable.put(id, id) == null)
+ break;
+
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ };
+ }
+ }
+
+ public synchronized void unlock(RequestId id) {
+ mHashtable.remove(id);
+
+ notifyAll();
+ }
+
+ // instance variables
+ Hashtable mHashtable = new Hashtable();
+ }
+ */
+
+
+//
+// Request - implementation of the IRequest interface. This
+// version is returned by ARequestQueue (and its derivatives)
+//
+class Request
+ implements IRequest {
+ // IRequest.getRequestId
+ public RequestId getRequestId() {
+ return mRequestId;
+ }
+
+ // IRequest.getRequestStatus
+ public RequestStatus getRequestStatus() {
+ return mRequestStatus;
+ }
+
+ // Obsolete
+ public void setRequestStatus(RequestStatus s) {
+ mRequestStatus = s;
+ // expose request status so that we can do predicate upon it
+ setExtData(IRequest.REQ_STATUS, s.toString());
+ }
+
+ public boolean isSuccess() {
+ Integer result = getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && result.equals(IRequest.RES_SUCCESS))
+ return true;
+ else
+ return false;
+ }
+
+ public String getError(Locale locale) {
+ return getExtDataInString(IRequest.ERROR);
+ }
+
+ // IRequest.getSourceId
+ public String getSourceId() {
+ return mSourceId;
+ }
+
+ // IRequest.setSourceId
+ public void setSourceId(String id) {
+ mSourceId = id;
+ }
+
+ // IRequest.getRequestOwner
+ public String getRequestOwner() {
+ return mOwner;
+ }
+
+ // IRequest.setRequestOwner
+ public void setRequestOwner(String id) {
+ mOwner = id;
+ }
+
+ // IRequest.getRequestType
+ public String getRequestType() {
+ return mRequestType;
+ }
+
+ // IRequest.setRequestType
+ public void setRequestType(String type) {
+ mRequestType = type;
+ setExtData(IRequest.REQ_TYPE, type);
+ }
+
+ // IRequest.getRequestVersion
+ public String getRequestVersion() {
+ return getExtDataInString(IRequest.REQ_VERSION);
+ }
+
+ // IRequest.getCreationTime
+ public Date getCreationTime() {
+ return mCreationTime;
+ }
+
+ public String getContext() {
+ return mContext;
+ }
+
+ public void setContext(String ctx) {
+ mContext = ctx;
+ }
+
+ // IRequest.getModificationTime
+ public Date getModificationTime() {
+ return mModificationTime;
+ }
+
+ /**
+ * this isn't that efficient but will do for now.
+ */
+ public void copyContents(IRequest req) {
+ Enumeration e = req.getExtDataKeys();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ if (!key.equals(IRequest.ISSUED_CERTS) &&
+ !key.equals(IRequest.ERRORS) &&
+ !key.equals(IRequest.REMOTE_REQID)) {
+ if (req.isSimpleExtDataValue(key)) {
+ setExtData(key, req.getExtDataInString(key));
+ } else {
+ setExtData(key, req.getExtDataInHashtable(key));
+ }
+ }
+ }
+ }
+
+ /**
+ * This function used to check that the keys obeyed LDAP attribute name
+ * syntax rules. Keys are being encoded now, so it is changed to just
+ * filter out null and empty string keys.
+ *
+ * @param key The key to check
+ * @return false if invalid
+ */
+ protected boolean isValidExtDataKey(String key) {
+ return key != null &&
+ (! key.equals(""));
+ }
+
+ protected boolean isValidExtDataHashtableValue(Hashtable hash) {
+ if (hash == null) {
+ return false;
+ }
+ Enumeration keys = hash.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ if (! ((key instanceof String) &&
+ isValidExtDataKey((String)key)) ) {
+ return false;
+ }
+
+ Object value = hash.get(key);
+ if (! (value instanceof String)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean setExtData(String key, String value) {
+ if (! isValidExtDataKey(key)) {
+ return false;
+ }
+ if (value == null) {
+ return false;
+ }
+
+ mExtData.put(key, value);
+ return true;
+ }
+
+ public boolean setExtData(String key, Hashtable value) {
+ if ( !(isValidExtDataKey(key) && isValidExtDataHashtableValue(value)) ) {
+ return false;
+ }
+
+ mExtData.put(key, new ExtDataHashtable(value));
+ return true;
+ }
+
+ public boolean isSimpleExtDataValue(String key) {
+ return (mExtData.get(key) instanceof String);
+ }
+
+ public String getExtDataInString(String key) {
+ Object value = mExtData.get(key);
+ if (value == null) {
+ return null;
+ }
+ if (! (value instanceof String)) {
+ return null;
+ }
+ return (String)value;
+ }
+
+ public Hashtable getExtDataInHashtable(String key) {
+ Object value = mExtData.get(key);
+ if (value == null) {
+ return null;
+ }
+ if (! (value instanceof Hashtable)) {
+ return null;
+ }
+ return new ExtDataHashtable((Hashtable)value);
+ }
+
+ public Enumeration getExtDataKeys() {
+ return mExtData.keys();
+ }
+
+ public void deleteExtData(String type) {
+ mExtData.remove(type);
+ }
+
+ public boolean setExtData(String key, String subkey, String value) {
+ if (! (isValidExtDataKey(key) && isValidExtDataKey(subkey)) ) {
+ return false;
+ }
+ if (isSimpleExtDataValue(key)) {
+ return false;
+ }
+ if (value == null) {
+ return false;
+ }
+
+ Hashtable existingValue = (Hashtable)mExtData.get(key);
+ if (existingValue == null) {
+ existingValue = new ExtDataHashtable();
+ mExtData.put(key, existingValue);
+ }
+ existingValue.put(subkey, value);
+ return true;
+ }
+
+ public String getExtDataInString(String key, String subkey) {
+ Hashtable value = getExtDataInHashtable(key);
+ if (value == null) {
+ return null;
+ }
+ return (String)value.get(subkey);
+ }
+
+ public boolean setExtData(String key, Integer value) {
+ if (value == null) {
+ return false;
+ }
+ return setExtData(key, value.toString());
+ }
+
+ public Integer getExtDataInInteger(String key) {
+ String strVal = getExtDataInString(key);
+ if (strVal == null) {
+ return null;
+ }
+ try {
+ return Integer.valueOf(strVal);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ public boolean setExtData(String key, Integer[] data) {
+ if (data == null) {
+ return false;
+ }
+ String[] stringArray = new String[data.length];
+ for (int index = 0; index < data.length; index++) {
+ stringArray[index] = data[index].toString();
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public Integer[] getExtDataInIntegerArray(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ Integer[] intArray = new Integer[stringArray.length];
+ for (int index = 0; index < stringArray.length; index++) {
+ try {
+ intArray[index] = new Integer(stringArray[index]);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ return intArray;
+ }
+
+ public boolean setExtData(String key, BigInteger value) {
+ if (value == null) {
+ return false;
+ }
+ return setExtData(key, value.toString());
+ }
+
+ public BigInteger getExtDataInBigInteger(String key) {
+ String strVal = getExtDataInString(key);
+ if (strVal == null) {
+ return null;
+ }
+ try {
+ return new BigInteger(strVal);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ public boolean setExtData(String key, BigInteger[] data) {
+ if (data == null) {
+ return false;
+ }
+ String[] stringArray = new String[data.length];
+ for (int index = 0; index < data.length; index++) {
+ stringArray[index] = data[index].toString();
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public BigInteger[] getExtDataInBigIntegerArray(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ BigInteger[] intArray = new BigInteger[stringArray.length];
+ for (int index = 0; index < stringArray.length; index++) {
+ try {
+ intArray[index] = new BigInteger(stringArray[index]);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ return intArray;
+ }
+
+ public boolean setExtData(String key, Throwable e) {
+ if (e == null) {
+ return false;
+ }
+ return setExtData(key, e.toString());
+ }
+
+ public boolean setExtData(String key, byte[] data) {
+ if (data == null) {
+ return false;
+ }
+ return setExtData(key, CMS.BtoA(data));
+ }
+
+ public byte[] getExtDataInByteArray(String key) {
+ String value = getExtDataInString(key);
+ if (value != null) {
+ return CMS.AtoB(value);
+ }
+ return null;
+ }
+
+ public boolean setExtData(String key, X509CertImpl data) {
+ if (data == null) {
+ return false;
+ }
+ try {
+ return setExtData(key, data.getEncoded());
+ } catch (CertificateEncodingException e) {
+ return false;
+ }
+ }
+
+ public X509CertImpl getExtDataInCert(String key) {
+ byte[] data = getExtDataInByteArray(key);
+ if (data != null) {
+ try {
+ return new X509CertImpl(data);
+ } catch (CertificateException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public boolean setExtData(String key, X509CertImpl[] data) {
+ if (data == null) {
+ return false;
+ }
+ String[] stringArray = new String[data.length];
+ for (int index = 0; index < data.length; index++) {
+ try {
+ stringArray[index] = CMS.BtoA(data[index].getEncoded());
+ } catch (CertificateEncodingException e) {
+ return false;
+ }
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public X509CertImpl[] getExtDataInCertArray(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ X509CertImpl[] certArray = new X509CertImpl[stringArray.length];
+ for (int index = 0; index < stringArray.length; index++) {
+ try {
+ certArray[index] = new X509CertImpl(CMS.AtoB(stringArray[index]));
+ } catch (CertificateException e) {
+ return null;
+ }
+ }
+ return certArray;
+ }
+
+ public boolean setExtData(String key, X509CertInfo data) {
+ if (data == null) {
+ return false;
+ }
+ try {
+ return setExtData(key, data.getEncodedInfo(true));
+ } catch (CertificateEncodingException e) {
+ return false;
+ }
+ }
+
+ public X509CertInfo getExtDataInCertInfo(String key) {
+ byte[] data = getExtDataInByteArray(key);
+ if (data != null) {
+ try {
+ return new X509CertInfo(data);
+ } catch (CertificateException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public boolean setExtData(String key, X509CertInfo[] data) {
+ if (data == null) {
+ return false;
+ }
+ String[] stringArray = new String[data.length];
+ for (int index = 0; index < data.length; index++) {
+ try {
+ stringArray[index] = CMS.BtoA(data[index].getEncodedInfo(true));
+ } catch (CertificateEncodingException e) {
+ return false;
+ }
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public X509CertInfo[] getExtDataInCertInfoArray(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ X509CertInfo[] certArray = new X509CertInfo[stringArray.length];
+ for (int index = 0; index < stringArray.length; index++) {
+ try {
+ certArray[index] = new X509CertInfo(CMS.AtoB(stringArray[index]));
+ } catch (CertificateException e) {
+ return null;
+ }
+ }
+ return certArray;
+ }
+
+ public boolean setExtData(String key, RevokedCertImpl[] data) {
+ if (data == null) {
+ return false;
+ }
+ String[] stringArray = new String[data.length];
+ for (int index = 0; index < data.length; index++) {
+ try {
+ stringArray[index] = CMS.BtoA(data[index].getEncoded());
+ } catch (CRLException e) {
+ return false;
+ }
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public RevokedCertImpl[] getExtDataInRevokedCertArray(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ RevokedCertImpl[] certArray = new RevokedCertImpl[stringArray.length];
+ for (int index = 0; index < stringArray.length; index++) {
+ try {
+ certArray[index] = new RevokedCertImpl(CMS.AtoB(stringArray[index]));
+ } catch (CRLException e) {
+ return null;
+ } catch (X509ExtensionException e) {
+ return null;
+ }
+ }
+ return certArray;
+ }
+
+ public boolean setExtData(String key, Vector stringVector) {
+ String[] stringArray;
+ if (stringVector == null) {
+ return false;
+ }
+ try {
+ stringArray = (String[])stringVector.toArray(new String[0]);
+ } catch (ArrayStoreException e) {
+ return false;
+ }
+ return setExtData(key, stringArray);
+ }
+
+ public Vector getExtDataInStringVector(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ return new Vector(Arrays.asList(stringArray));
+ }
+
+ public boolean getExtDataInBoolean(String key, boolean defVal) {
+ String val = getExtDataInString(key);
+ if (val == null)
+ return defVal;
+ return val.equalsIgnoreCase("true") || val.equalsIgnoreCase("ON");
+ }
+
+ public boolean getExtDataInBoolean(String prefix, String type, boolean defVal) {
+ String val = getExtDataInString(prefix, type);
+ if (val == null)
+ return defVal;
+ return val.equalsIgnoreCase("true") || val.equalsIgnoreCase("ON");
+ }
+
+ public boolean setExtData(String key, IAuthToken data) {
+ if (data == null) {
+ return false;
+ }
+ Hashtable hash = new Hashtable();
+ Enumeration keys = data.getElements();
+ while (keys.hasMoreElements()) {
+ try {
+ String authKey = (String) keys.nextElement();
+ hash.put(authKey, data.getInString(authKey));
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ return setExtData(key, hash);
+ }
+
+ public IAuthToken getExtDataInAuthToken(String key) {
+ Hashtable hash = getExtDataInHashtable(key);
+ if (hash == null) {
+ return null;
+ }
+ AuthToken authToken = new AuthToken(null);
+ Enumeration keys = hash.keys();
+ while (keys.hasMoreElements()) {
+ try {
+ String hashKey = (String) keys.nextElement();
+ authToken.set(hashKey, (String) hash.get(hashKey));
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ return authToken;
+ }
+
+ public boolean setExtData(String key, CertificateExtensions data) {
+ if (data == null) {
+ return false;
+ }
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ try {
+ data.encode(byteStream);
+ } catch (CertificateException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+ return setExtData(key, byteStream.toByteArray());
+ }
+
+ public CertificateExtensions getExtDataInCertExts(String key) {
+ CertificateExtensions exts = null;
+ byte[] extensionsData = getExtDataInByteArray(key);
+ if (extensionsData != null) {
+ exts = new CertificateExtensions();
+ try {
+ exts.decodeEx(new ByteArrayInputStream(extensionsData));
+ // exts.decode() does not work when the CertExts size is 0
+ // exts.decode(new ByteArrayInputStream(extensionsData));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return exts;
+ }
+
+ public boolean setExtData(String key, CertificateSubjectName data) {
+ if (data == null) {
+ return false;
+ }
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ try {
+ data.encode(byteStream);
+ } catch (IOException e) {
+ return false;
+ }
+ return setExtData(key, byteStream.toByteArray());
+ }
+
+ public CertificateSubjectName getExtDataInCertSubjectName(String key) {
+ CertificateSubjectName name = null;
+ byte[] nameData = getExtDataInByteArray(key);
+ if (nameData != null) {
+ try {
+ // You must use DerInputStream
+ // using ByteArrayInputStream fails
+ name = new CertificateSubjectName(
+ new DerInputStream(nameData));
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return name;
+ }
+
+ public boolean setExtData(String key, String[] values) {
+ if (values == null) {
+ return false;
+ }
+ Hashtable hashValue = new Hashtable();
+ for (int index = 0; index < values.length; index++) {
+ hashValue.put(Integer.toString(index), values[index]);
+ }
+ return setExtData(key, hashValue);
+ }
+
+ public String[] getExtDataInStringArray(String key) {
+ int index;
+
+ Hashtable hashValue = getExtDataInHashtable(key);
+ if (hashValue == null) {
+ return null;
+ }
+ Set arrayKeys = hashValue.keySet();
+ Vector listValue = new Vector(arrayKeys.size());
+ for (Iterator iter = arrayKeys.iterator(); iter.hasNext();) {
+ String arrayKey = (String)iter.next();
+ try {
+ index = Integer.parseInt(arrayKey);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ if (listValue.size() < (index + 1)) {
+ listValue.setSize(index + 1);
+ }
+ listValue.set(index,
+ hashValue.get(arrayKey));
+ }
+ return (String[])listValue.toArray(new String[0]);
+ }
+
+ public IAttrSet asIAttrSet() {
+ return new RequestIAttrSetWrapper(this);
+ }
+
+ Request(RequestId id) {
+ mRequestId = id;
+ setRequestStatus(RequestStatus.BEGIN);
+ }
+
+ // instance variables
+ protected RequestId mRequestId;
+ protected RequestStatus mRequestStatus;
+ protected String mSourceId;
+ protected String mSource;
+ protected String mOwner;
+ protected String mRequestType;
+ protected String mContext; // string for now.
+ protected ExtDataHashtable mExtData = new ExtDataHashtable();
+
+ Date mCreationTime = CMS.getCurrentDate();
+ Date mModificationTime = CMS.getCurrentDate();
+}
+
+class RequestIAttrSetWrapper implements IAttrSet {
+ IRequest mRequest;
+
+ public RequestIAttrSetWrapper(IRequest request) {
+ mRequest = request;
+ }
+
+ public void set(String name, Object obj) throws EBaseException {
+ try {
+ mRequest.setExtData(name, (String)obj);
+ } catch (ClassCastException e) {
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ public Object get(String name) throws EBaseException {
+ return mRequest.getExtDataInString(name);
+ }
+
+ public void delete(String name) throws EBaseException {
+ mRequest.deleteExtData(name);
+ }
+
+ public Enumeration getElements() {
+ return mRequest.getExtDataKeys();
+ }
+}
+
+
+/**
+ * Example of a specialized request class.
+ */
+class EnrollmentRequest
+ extends Request
+ implements IEnrollmentRequest {
+ EnrollmentRequest(RequestId id) {
+ super(id);
+ }
+}
+
+
+class RequestListByStatus
+ implements IRequestList {
+ public boolean hasMoreElements() {
+ return (mNext != null);
+ }
+
+ public Object nextRequest() {
+ return null;
+ }
+
+ public IRequest nextRequestObject() {
+ return null;
+ }
+
+ public Object nextElement() {
+ RequestId next = mNext;
+
+ update();
+
+ return next;
+ }
+
+ public RequestId nextRequestId() {
+ RequestId next = mNext;
+
+ update();
+
+ return next;
+ }
+
+ public RequestListByStatus(Enumeration e, RequestStatus s, IRequestQueue q) {
+ mEnumeration = e;
+ mStatus = s;
+ mQueue = q;
+
+ update();
+ }
+
+ protected void update() {
+ RequestId rId;
+
+ mNext = null;
+
+ while (mNext == null) {
+ if (!mEnumeration.hasMoreElements()) break;
+
+ rId = (RequestId) mEnumeration.nextElement();
+
+ try {
+ IRequest r = mQueue.findRequest(rId);
+
+ if (r.getRequestStatus() == mStatus) mNext = rId;
+
+ mQueue.releaseRequest(r);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ protected RequestStatus mStatus;
+ protected IRequestQueue mQueue;
+ protected Enumeration mEnumeration;
+ protected RequestId mNext;
+}
+
+
+class RequestList
+ implements IRequestList {
+ public boolean hasMoreElements() {
+ return mEnumeration.hasMoreElements();
+ }
+
+ public Object nextElement() {
+ return mEnumeration.nextElement();
+ }
+
+ public RequestId nextRequestId() {
+ return (RequestId) mEnumeration.nextElement();
+ }
+
+ public Object nextRequest() {
+ return null;
+ }
+
+ public IRequest nextRequestObject() {
+ return null;
+ }
+
+ public RequestList(Enumeration e) {
+ mEnumeration = e;
+ }
+
+ protected Enumeration mEnumeration;
+}
+
+
+class RecoverThread extends Thread {
+ private ARequestQueue mQ = null;
+
+ public RecoverThread(ARequestQueue q) {
+ mQ = q;
+ setName("RequestRecoverThread");
+ }
+
+ public void run() {
+ mQ.recoverWillBlock();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/ARequestRecord.java b/pki/base/common/src/com/netscape/cmscore/request/ARequestRecord.java
new file mode 100644
index 000000000..b81d5d211
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/ARequestRecord.java
@@ -0,0 +1,44 @@
+// --- 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.cmscore.request;
+
+
+import java.util.Hashtable;
+import java.util.Date;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+
+/**
+ * The low level (attributes only) version of the database
+ * record object. This exists so that RecordAttr methods can use
+ * this type definition,
+ *
+ * RequestRecord refers both to this class and to RecordAttr objects.
+ */
+class ARequestRecord {
+ RequestId mRequestId;
+ RequestStatus mRequestState;
+ Date mCreateTime;
+ Date mModifyTime;
+ String mSourceId;
+ String mOwner;
+ String mRequestType;
+ Hashtable mExtData;
+};
diff --git a/pki/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java b/pki/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java
new file mode 100644
index 000000000..7494b5e48
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java
@@ -0,0 +1,74 @@
+// --- 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.cmscore.request;
+
+
+/**
+ * temporary location for cert request constants.
+ * XXX we really need to centralize all these but for now they are here
+ * as needed.
+ */
+public class CertRequestConstants {
+ // request types - these have string values.
+ // made to match policy constants.
+ public final static String GETCRL_REQUEST = "getCRL";
+ public final static String GETCACHAIN_REQUEST = "getCAChain";
+ public final static String GETREVOCATIONINFO_REQUEST = "getRevocationInfo";
+
+ public final static String REVOCATION_CHECK_CHALLENGE_REQUEST = "checkChallengePhrase";
+ public final static String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+
+ // BigInteger Value and BigIntegerValue array.
+ public final static String SERIALNO = "serialNumber";
+ public final static String SERIALNOS = "serialNumbers";
+
+ // int value.
+ public final static String REVOKE_REASON = "revokeReason";
+
+ // this has a string value.
+ public final static String HOLDINSTRCODE = "holdInstrCode";
+ public final static String HOLDCALLISSUER = "holdCallIssuer";
+ public final static String HOLDREJECT = "holdReject";
+
+ // this has a Date value.
+ public final static String INVALIDITYDATE = "InvalidityDate";
+
+ // this has a CRLExtensions value.
+ public final static String CRLEXTS = "CRLExts";
+
+ // this has a String value - it is either null or set.
+ public final static String DOGETCACHAIN = "doGetCAChain";
+
+ // this has a CertificateChain value.
+ public final static String CACERTCHAIN = "CACertChain";
+
+ // this has a CRL value.
+ public final static String CRL = "CRL";
+
+ // this has a X509CertImpl value.
+ public final static String CERTIFICATE = "certificate";
+
+ // this is an array of EBaseException for service errors when
+ // there's an error processing an array of something such as
+ // certs to renew, certs to revoke, etc.
+ public final static String SVCERRORS = "serviceErrors";
+
+ // crl update status after a revocation.
+ public final static String CRL_UPDATE_STATUS = "crlUpdateStatus";
+ public final static String CRL_UPDATE_ERROR = "crlUpdateError";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java b/pki/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java
new file mode 100644
index 000000000..cdc5a7eea
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java
@@ -0,0 +1,71 @@
+package com.netscape.cmscore.request;
+
+import java.util.*;
+
+/**
+ * Subclass of Hashtable returned by IRequest.getExtDataInHashtable. Its
+ * purpose is to hide the fact that LDAP doesn't preserve the case of keys.
+ * It does this by lowercasing all keys used to access the Hashtable.
+ */
+public class ExtDataHashtable extends Hashtable {
+
+ public ExtDataHashtable() {
+ super();
+ }
+
+ public ExtDataHashtable(int i) {
+ super(i);
+ }
+
+ public ExtDataHashtable(int i, float v) {
+ super(i, v);
+ }
+
+ public ExtDataHashtable(Map map) {
+ // the super constructor seems to call putAll, but I can't
+ // rely on that behaviour
+ super();
+ putAll(map);
+ }
+
+ public boolean containsKey(Object o) {
+ if (o instanceof String) {
+ String key = (String)o;
+ return super.containsKey(key.toLowerCase());
+ }
+ return super.containsKey(o);
+ }
+
+ public Object get(Object o) {
+ if (o instanceof String) {
+ String key = (String)o;
+ return super.get(key.toLowerCase());
+ }
+ return super.get(o);
+ }
+
+ public Object put(Object oKey, Object val) {
+ if (oKey instanceof String) {
+ String key = (String)oKey;
+ return super.put(key.toLowerCase(), val);
+ }
+ return super.put(oKey, val);
+ }
+
+ public void putAll(Map map) {
+ Set keys = map.keySet();
+ for (Iterator i = keys.iterator();
+ i.hasNext();) {
+ Object key = i.next();
+ put(key, map.get(key));
+ }
+ }
+
+ public Object remove(Object o) {
+ if (o instanceof String) {
+ String key = (String)o;
+ return super.remove(key.toLowerCase());
+ }
+ return super.remove(o);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestAttr.java b/pki/base/common/src/com/netscape/cmscore/request/RequestAttr.java
new file mode 100644
index 000000000..ea60dc470
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/RequestAttr.java
@@ -0,0 +1,63 @@
+// --- 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.cmscore.request;
+
+
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.ldap.*;
+
+
+/**
+ * The RequestAttr class defines the methods used
+ * to transfer data between the various representations of
+ * a request. The three forms are:
+ * 1) LDAPAttributes (and Modifications)
+ * 2) Database record IDBAttrSet
+ * 3) IRequest (Request) object
+ */
+abstract class RequestAttr {
+
+ /**
+ *
+ */
+
+ abstract void set(ARequestRecord r, Object o);
+
+ abstract Object get(ARequestRecord r);
+
+ abstract void read(IRequestMod a, IRequest r, ARequestRecord rr);
+
+ abstract void add(IRequest r, ARequestRecord rr);
+
+ abstract void mod(ModificationSet mods, IRequest r);
+
+ RequestAttr(String attrName, IDBAttrMapper mapper) {
+ mAttrName = attrName;
+ mMapper = mapper;
+ }
+
+ protected void addmod(ModificationSet mods, Object o) {
+ mods.add(mAttrName, Modification.MOD_REPLACE, o);
+ }
+
+ String mAttrName;
+ IDBAttrMapper mMapper;
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java b/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java
new file mode 100644
index 000000000..f390d436d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java
@@ -0,0 +1,708 @@
+// --- 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.cmscore.request;
+
+
+import java.math.BigInteger;
+
+import java.util.Date;
+import java.util.Enumeration;
+
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.cmscore.dbs.DBSubsystem;
+
+import com.netscape.certsrv.base.EBaseException;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.ldap.*;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestVirtualList;
+import com.netscape.cmscore.request.ARequestQueue;
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+import com.netscape.cmscore.util.Debug;
+
+
+public class RequestQueue
+ extends ARequestQueue
+ implements IRequestMod {
+ // ARequestQueue.newRequestId
+ protected RequestId newRequestId()
+ throws EBaseException {
+ // get the next request Id
+ BigInteger next = mRepository.getNextSerialNumber();
+
+ RequestId rid = new RequestId(next.toString());
+
+ return rid;
+ }
+
+ protected IRequest readRequest(RequestId id) {
+ RequestRecord record;
+
+ // String name = Schema.LDAP_ATTR_REQUEST_ID + "=" +
+ String name = "cn" + "=" +
+ id + "," + mBaseDN;
+
+ Object obj = null;
+ IDBSSession dbs = null;
+
+ try {
+ dbs = mDB.createSession();
+ obj = dbs.read(name);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ // TODO Errors!!!
+ if (obj == null || !(obj instanceof RequestRecord)) return null;
+
+ record = (RequestRecord) obj;
+
+ /*
+ setRequestStatus(r, record.mRequestState);
+ r.setSourceId(record.mSourceId);
+ r.setRequestOwner(record.mOwner);
+ record.storeAttrs(r, record.mRequestAttrs);
+ setModificationTime(r, record.mModifyTime);
+ setCreationTime(r, record.mCreateTime);
+ */
+ return makeRequest(record);
+ }
+
+ protected void addRequest(IRequest r) throws EBaseException {
+ // setup to call dbs.add(name, IAttrSet)
+ RequestRecord record = new RequestRecord();
+
+ record.add(r);
+
+ // compute the name of the object
+ // String name = Schema.LDAP_ATTR_REQUEST_ID + "=" +
+ String name = "cn" + "=" +
+ record.mRequestId + "," + mBaseDN;
+
+ IDBSSession dbs = null;
+
+ try {
+ dbs = mDB.createSession();
+ dbs.add(name, record);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ throw e;
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+ }
+
+ protected void modifyRequest(IRequest r) {
+ String dbStatus = r.getExtDataInString("dbStatus");
+
+ if (!dbStatus.equals("UPDATED")) {
+ try {
+ r.setExtData("dbStatus", "UPDATED");
+ addRequest(r);
+ } catch (EBaseException e) {
+ System.out.println(e.toString());
+ }
+ return;
+ }
+
+ ModificationSet mods = new ModificationSet();
+
+ try {
+ RequestRecord.mod(mods, r);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ }
+
+ /*
+ //
+ mods.add(IRequestRecord.ATTR_REQUEST_STATE,
+ Modification.MOD_REPLACE, r.getRequestStatus());
+
+ mods.add(IRequestRecord.ATTR_SOURCE_ID,
+ Modification.MOD_REPLACE, r.getSourceId());
+
+ mods.add(IRequestRecord.ATTR_REQUEST_OWNER,
+ Modification.MOD_REPLACE, r.getRequestOwner());
+
+ mods.add(IRequestRecord.ATTR_MODIFY_TIME,
+ Modification.MOD_REPLACE, r.getModificationTime());
+
+ java.util.Hashtable ht = RequestRecord.loadAttrs(r);
+ mods.add(RequestRecord.ATTR_REQUEST_ATTRS,
+ Modification.MOD_REPLACE, ht);
+ */
+
+ // String name = Schema.LDAP_ATTR_REQUEST_ID + "=" +
+ String name = "cn" + "=" +
+ r.getRequestId() + "," + mBaseDN;
+
+ IDBSSession dbs = null;
+
+ try {
+ dbs = mDB.createSession();
+ dbs.modify(name, mods);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+ }
+
+ IRequest makeRequest(RequestRecord record) {
+ IRequest r = createRequest(record.mRequestId, record.mRequestType);
+
+ try {
+ // convert (copy) fields
+ record.read(this, r);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ }
+
+ return r;
+ }
+
+ public void modRequestStatus(IRequest r, RequestStatus s) {
+ setRequestStatus(r, s);
+ }
+
+ public void modCreationTime(IRequest r, Date d) {
+ setCreationTime(r, d);
+ }
+
+ public void modModificationTime(IRequest r, Date d) {
+ setModificationTime(r, d);
+ }
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException
+ {
+ mRepository.resetSerialNumber(serial);
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ mRepository.removeAllObjects();
+ }
+
+ public BigInteger getLastRequestIdInRange(BigInteger reqId_low_bound, BigInteger reqId_upper_bound)
+ {
+ CMS.debug("RequestQueue: getLastRequestId: low " + reqId_low_bound + " high " + reqId_upper_bound);
+ if(reqId_low_bound == null || reqId_upper_bound == null || reqId_low_bound.compareTo(reqId_upper_bound) >= 0)
+ {
+ CMS.debug("RequestQueue: getLastRequestId: bad upper and lower bound range.");
+ return null;
+ }
+
+ String filter = "(" + "requeststate" + "=*" + ")";
+
+ RequestId fromId = new RequestId(reqId_upper_bound.toString(10));
+
+ CMS.debug("RequestQueue: getLastRequestId: filter " + filter + " fromId " + fromId);
+ ListEnumeration recList = (ListEnumeration) getPagedRequestsByFilter(fromId,filter,5 * -1,"requestId");
+
+ int size = recList.getSize();
+
+ CMS.debug("RequestQueue: getLastRequestId: size " + size);
+
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ CMS.debug("RequestQueue: getSizeBeforeJumpTo: " + ltSize);
+
+ if (size <= 0) {
+ CMS.debug("RequestQueue: getLastRequestId: request list is empty.");
+
+ BigInteger ret = new BigInteger(reqId_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+ }
+
+ IRequest curRec = null;
+
+ RequestId curId = null;
+
+ String reqId = null;
+
+ for(int i = 0; i < 5; i++)
+ {
+ curRec = recList.getElementAt(i);
+
+ if(curRec != null) {
+
+ curId = curRec.getRequestId();
+
+ reqId = curId.toString();
+
+ CMS.debug("RequestQueue: curReqId: " + reqId);
+
+ BigInteger curIdInt = new BigInteger(reqId);
+
+
+ if( ((curIdInt.compareTo(reqId_low_bound) == 0) || (curIdInt.compareTo(reqId_low_bound) == 1) ) &&
+ ((curIdInt.compareTo(reqId_upper_bound) == 0) || (curIdInt.compareTo(reqId_upper_bound) == -1) ))
+ {
+ CMS.debug("RequestQueue: getLastRequestId : returning value " + curIdInt);
+ return curIdInt;
+ }
+
+ }
+
+ }
+
+
+ BigInteger ret = new BigInteger(reqId_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+
+ }
+
+ /**
+ * Implements IRequestQueue.findRequestBySourceId
+ * <p>
+ * @see com.netscape.certsrv.request.IRequestQueue#findRequestBySourceId
+ */
+ public RequestId findRequestBySourceId(String id) {
+ IRequestList irl = findRequestsBySourceId(id);
+
+ if (irl == null) return null;
+
+ return irl.nextRequestId();
+ }
+
+ /**
+ * Implements IRequestQueue.findRequestsBySourceId
+ * <p>
+ * @see com.netscape.certsrv.request.IRequestQueue#findRequestsBySourceId
+ */
+ public IRequestList findRequestsBySourceId(String id) {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+
+ // Need only the requestid in the result of the search
+ // TODO: generic search returning RequestId
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+ String filter = "(" + IRequestRecord.ATTR_SOURCE_ID + "=" + id + ")";
+
+ try {
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, filter);
+ } catch (EBaseException e) {
+ Debug.trace("Error in Ldap Request searching code: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null || !results.hasMoreElements()) return null;
+
+ return new SearchEnumeration(this, results);
+
+ }
+
+ protected Enumeration getRawList() {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+
+ try {
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, "(requestId=*)");
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null) return null;
+
+ return new SearchEnumeration(this, results);
+ }
+
+ /**
+ */
+ public IRequestList listRequestsByFilter(String f) {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+
+ try {
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, f);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null) return null;
+
+ return new SearchEnumeration(this, results);
+ }
+
+ /**
+ */
+ public IRequestList listRequestsByFilter(String f, int maxSize) {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+
+ try {
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, f, maxSize);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null) return null;
+
+ return new SearchEnumeration(this, results);
+ }
+
+ /**
+ */
+ public IRequestList listRequestsByFilter(String f, int maxSize, int timeLimit) {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+
+ try {
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, f, maxSize, timeLimit);
+ } catch (EBaseException e) {
+ Debug.trace("Error: " + e);
+ Debug.printStackTrace(e);
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null) return null;
+
+ return new SearchEnumeration(this, results);
+ }
+
+ public IRequestList listRequestsByStatus(RequestStatus s) {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+ String attrs[] = { IRequestRecord.ATTR_REQUEST_ID };
+
+ try {
+ String f1;
+ String f2;
+
+ f1 = "(" + IRequestRecord.ATTR_REQUEST_STATE + "=" + s + ")";
+ f2 = "(" + IRequestRecord.ATTR_REQUEST_ID + "=*)";
+
+ f1 = "(&" + f1 + f2 + ")";
+
+ dbs = mDB.createSession();
+ results = dbs.search(mBaseDN, f1);
+ } catch (EBaseException e) {
+ //System.err.println("Error: "+e);
+ //e.printStackTrace();
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ if (results == null) return null;
+
+ return new SearchEnumeration(this, results);
+ }
+
+ /*
+ * Implements IRequestQueue.getPagedRequests
+ */
+ public IRequestVirtualList getPagedRequests(int pageSize) {
+ return getPagedRequestsByFilter("(requestId=*)", pageSize, "requestId");
+ }
+
+ /*
+ * Implements IRequestQueue.getPagedRequestsByFilter
+ */
+ public IRequestVirtualList
+ getPagedRequestsByFilter(String filter, int pageSize, String sortKey) {
+ return getPagedRequestsByFilter(null, filter, pageSize, sortKey);
+ }
+
+ public IRequestVirtualList
+ getPagedRequestsByFilter(RequestId from, String filter, int pageSize,
+ String sortKey) {
+ return getPagedRequestsByFilter(from, false, filter, pageSize, sortKey);
+ }
+
+ public IRequestVirtualList
+ getPagedRequestsByFilter(RequestId from, boolean jumpToEnd, String filter, int pageSize,
+ String sortKey) {
+ IDBVirtualList results = null;
+ IDBSSession dbs = null;
+
+ try {
+ dbs = mDB.createSession();
+ } catch (EBaseException e) {
+ return null;
+ }
+
+ try {
+
+ if (from == null) {
+ results = dbs.createVirtualList(mBaseDN, filter, (String[]) null,
+ sortKey, pageSize);
+ } else {
+ int len = from.toString().length();
+ String internalRequestId = null;
+
+ if (jumpToEnd) {
+ internalRequestId ="99";
+ } else {
+ if (len > 9) {
+ internalRequestId = Integer.toString(len) + from.toString();
+ } else {
+ internalRequestId = "0" + Integer.toString(len) +
+ from.toString();
+ }
+ }
+
+ results = dbs.createVirtualList(mBaseDN, filter, (String[]) null,
+ internalRequestId, sortKey, pageSize);
+ }
+ } catch (EBaseException e) {
+ return null;
+ } finally {
+ try {
+ dbs.close();
+ } catch (EBaseException e) {
+ }
+ }
+
+ try {
+ results.setSortKey(sortKey);
+ } catch (EBaseException e) {//XXX
+ System.out.println(e.toString());
+ return null;
+ }
+
+ return new ListEnumeration(this, results);
+ }
+
+ public RequestQueue(String name, int increment, IPolicy p, IService s, INotify n,
+ INotify pendingNotify)
+ throws EBaseException {
+ super(p, s, n, pendingNotify);
+
+ mDB = DBSubsystem.getInstance();
+ mBaseDN = "ou=" + name + ",ou=requests," + mDB.getBaseDN();
+
+ mRepository = new RequestRepository(name, increment, mDB,this);
+
+ }
+
+ /*
+ * list record attributes (debugging output)
+ */
+ static void listRecordAttrs(String s, java.util.Hashtable h) {
+ System.err.println(s);
+ java.util.Enumeration e = h.keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ System.err.println("Attr: " + name + " Value: " + h.get(name));
+ }
+ }
+
+ /*
+ * return request repository
+ */
+ public IRepository getRequestRepository() {
+ return (IRepository) mRepository;
+ }
+
+ public String getPublishingStatus() {
+ return mRepository.getPublishingStatus();
+ }
+
+ public void setPublishingStatus(String status) {
+ mRepository.setPublishingStatus(status);
+ }
+
+ protected String mBaseDN;
+ protected IDBSubsystem mDB;
+ protected RequestRepository mRepository;
+}
+
+
+class SearchEnumeration
+ implements IRequestList {
+ public RequestId nextRequestId() {
+ Object obj;
+
+ obj = mResults.nextElement();
+
+ if (obj == null || !(obj instanceof RequestRecord)) return null;
+
+ RequestRecord r = (RequestRecord) obj;
+
+ return r.mRequestId;
+ }
+
+ public boolean hasMoreElements() {
+ return mResults.hasMoreElements();
+ }
+
+ public Object nextElement() {
+ return nextRequestId();
+ }
+
+ public SearchEnumeration(IDBSearchResults r) {
+ mResults = r;
+ }
+
+ public SearchEnumeration(RequestQueue queue, IDBSearchResults r) {
+ mResults = r;
+ mQueue = queue;
+ }
+
+ public Object nextRequest() {
+ Object obj;
+
+ obj = mResults.nextElement();
+
+ if (obj == null || !(obj instanceof RequestRecord)) return null;
+
+ RequestRecord r = (RequestRecord) obj;
+
+ return r;
+ }
+
+ public IRequest nextRequestObject() {
+ RequestRecord record = (RequestRecord)nextRequest();
+ if (record != null)
+ return mQueue.makeRequest(record);
+ return null;
+ }
+
+ protected IDBSearchResults mResults;
+ protected RequestQueue mQueue;
+}
+
+
+class ListEnumeration
+ implements IRequestVirtualList {
+ public IRequest getElementAt(int i) {
+ RequestRecord record = (RequestRecord) mList.getElementAt(i);
+
+ if (record == null) return null;
+
+ return mQueue.makeRequest(record);
+ }
+
+ public int getCurrentIndex() {
+ return mList.getCurrentIndex();
+ }
+
+ public int getSize() {
+ return mList.getSize();
+ }
+
+ public int getSizeBeforeJumpTo() {
+ return mList.getSizeBeforeJumpTo();
+
+ }
+
+ public int getSizeAfterJumpTo() {
+ return mList.getSizeAfterJumpTo();
+
+ }
+ ListEnumeration(RequestQueue queue, IDBVirtualList list) {
+ mQueue = queue;
+ mList = list;
+ }
+
+ protected RequestQueue mQueue;
+ protected IDBVirtualList mList;
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestRecord.java b/pki/base/common/src/com/netscape/cmscore/request/RequestRecord.java
new file mode 100644
index 000000000..85995aaa3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/RequestRecord.java
@@ -0,0 +1,870 @@
+// --- 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.cmscore.request;
+
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.math.BigInteger;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.cmscore.dbs.StringMapper;
+import com.netscape.cmscore.dbs.DateMapper;
+import com.netscape.cmscore.dbs.BigIntegerMapper;
+
+import com.netscape.certsrv.request.ldap.*;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestRecord;
+
+import com.netscape.cmscore.util.Debug;
+
+
+//
+// A request record is the stored version of a request.
+// It has a set of attributes that are mapped into LDAP
+// attributes for actual directory operations.
+//
+public class RequestRecord
+ extends ARequestRecord
+ implements IRequestRecord, IDBObj {
+ public RequestId getRequestId() {
+ return mRequestId;
+ }
+
+ public Enumeration getAttrNames() {
+ return mAttrTable.keys();
+ }
+
+ // IDBObj.get
+ public Object get(String name) {
+ if (name.equals(IRequestRecord.ATTR_REQUEST_ID))
+ return mRequestId;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_STATE))
+ return mRequestState;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_TYPE))
+ return mRequestType;
+ else if (name.equals(IRequestRecord.ATTR_MODIFY_TIME))
+ return mModifyTime;
+ else if (name.equals(IRequestRecord.ATTR_CREATE_TIME))
+ return mCreateTime;
+ else if (name.equals(IRequestRecord.ATTR_SOURCE_ID))
+ return mSourceId;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_OWNER))
+ return mOwner;
+ else if (name.equals(IRequestRecord.ATTR_EXT_DATA))
+ return mExtData;
+ else {
+ RequestAttr ra = (RequestAttr) mAttrTable.get(name);
+
+ if (ra != null) return ra.get(this);
+ }
+
+ return null;
+ }
+
+ // IDBObj.set
+ public void set(String name, Object o) {
+ if (name.equals(IRequestRecord.ATTR_REQUEST_ID))
+ mRequestId = (RequestId) o;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_STATE))
+ mRequestState = (RequestStatus) o;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_TYPE))
+ mRequestType = (String) o;
+ else if (name.equals(IRequestRecord.ATTR_CREATE_TIME))
+ mCreateTime = (Date) o;
+ else if (name.equals(IRequestRecord.ATTR_MODIFY_TIME))
+ mModifyTime = (Date) o;
+ else if (name.equals(IRequestRecord.ATTR_SOURCE_ID))
+ mSourceId = (String) o;
+ else if (name.equals(IRequestRecord.ATTR_REQUEST_OWNER))
+ mOwner = (String) o;
+ else if (name.equals(IRequestRecord.ATTR_EXT_DATA))
+ mExtData = (Hashtable)o;
+ else {
+ RequestAttr ra = (RequestAttr) mAttrTable.get(name);
+
+ if (ra != null) ra.set(this, o);
+ }
+ }
+
+ // IDBObj.delete
+ public void delete(String name)
+ throws EBaseException {
+ throw new EBaseException("Invalid call to delete");
+ }
+
+ // IDBObj.getElements
+ public Enumeration getElements() {
+ return mAttrs.elements();
+ }
+
+ // IDBObj.getSerializableAttrNames
+ public Enumeration getSerializableAttrNames() {
+ return mAttrs.elements();
+ }
+
+ // copy values from r to the local record
+ void add(IRequest r) throws EBaseException {
+ // Collect the values for the record
+ mRequestId = r.getRequestId();
+ mRequestType = r.getRequestType();
+ mRequestState = r.getRequestStatus();
+ mSourceId = r.getSourceId();
+ mOwner = r.getRequestOwner();
+ mCreateTime = r.getCreationTime();
+ mModifyTime = r.getModificationTime();
+ mExtData = loadExtDataFromRequest(r);
+
+ for (int i = 0; i < mRequestA.length; i++) {
+ mRequestA[i].add(r, this);
+ }
+ }
+
+ void read(IRequestMod a, IRequest r) throws EBaseException {
+ a.modRequestStatus(r, mRequestState);
+ r.setSourceId(mSourceId);
+ r.setRequestOwner(mOwner);
+ a.modModificationTime(r, mModifyTime);
+ a.modCreationTime(r, mCreateTime);
+ storeExtDataIntoRequest(r);
+
+ for (int i = 0; i < mRequestA.length; i++) {
+ mRequestA[i].read(a, r, this);
+ }
+ }
+
+ static void mod(ModificationSet mods, IRequest r) throws EBaseException {
+ //
+ mods.add(IRequestRecord.ATTR_REQUEST_STATE,
+ Modification.MOD_REPLACE, r.getRequestStatus());
+
+ mods.add(IRequestRecord.ATTR_SOURCE_ID,
+ Modification.MOD_REPLACE, r.getSourceId());
+
+ mods.add(IRequestRecord.ATTR_REQUEST_OWNER,
+ Modification.MOD_REPLACE, r.getRequestOwner());
+
+ mods.add(IRequestRecord.ATTR_MODIFY_TIME,
+ Modification.MOD_REPLACE, r.getModificationTime());
+
+ mods.add(IRequestRecord.ATTR_EXT_DATA,
+ Modification.MOD_REPLACE, loadExtDataFromRequest(r));
+
+ for (int i = 0; i < mRequestA.length; i++) {
+ mRequestA[i].mod(mods, r);
+ }
+ }
+
+ static void register(IDBSubsystem db)
+ throws EDBException {
+ IDBRegistry reg = db.getRegistry();
+
+ reg.registerObjectClass(RequestRecord.class.getName(), mOC);
+
+ reg.registerAttribute(IRequestRecord.ATTR_REQUEST_ID, new RequestIdMapper());
+ reg.registerAttribute(IRequestRecord.ATTR_REQUEST_STATE, new RequestStateMapper());
+ reg.registerAttribute(IRequestRecord.ATTR_CREATE_TIME,
+ new DateMapper(Schema.LDAP_ATTR_CREATE_TIME));
+ reg.registerAttribute(IRequestRecord.ATTR_MODIFY_TIME,
+ new DateMapper(Schema.LDAP_ATTR_MODIFY_TIME));
+ reg.registerAttribute(IRequestRecord.ATTR_SOURCE_ID,
+ new StringMapper(Schema.LDAP_ATTR_SOURCE_ID));
+ reg.registerAttribute(IRequestRecord.ATTR_REQUEST_OWNER,
+ new StringMapper(Schema.LDAP_ATTR_REQUEST_OWNER));
+ ExtAttrDynMapper extAttrMapper = new ExtAttrDynMapper();
+ reg.registerAttribute(IRequestRecord.ATTR_EXT_DATA, extAttrMapper);
+ reg.registerDynamicMapper(extAttrMapper);
+
+ for (int i = 0; i < mRequestA.length; i++) {
+ RequestAttr ra = mRequestA[i];
+
+ reg.registerAttribute(ra.mAttrName, ra.mMapper);
+ }
+ }
+
+ protected static final String mOC[] =
+ { Schema.LDAP_OC_TOP, Schema.LDAP_OC_REQUEST, Schema.LDAP_OC_EXTENSIBLE };
+
+ protected static Hashtable loadExtDataFromRequest(IRequest r) throws EBaseException {
+ Hashtable h = new Hashtable();
+
+ Enumeration e = r.getExtDataKeys();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ if (r.isSimpleExtDataValue(key)) {
+ h.put(key, r.getExtDataInString(key));
+ } else {
+ h.put(key, r.getExtDataInHashtable(key));
+ }
+ }
+
+ return h;
+ }
+
+ protected void storeExtDataIntoRequest(IRequest r) throws EBaseException {
+ Enumeration e = mExtData.keys();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ Object value = mExtData.get(key);
+ if (value instanceof String) {
+ r.setExtData(key, (String)value);
+ } else if (value instanceof Hashtable) {
+ r.setExtData(key, (Hashtable)value);
+ } else {
+ throw new EDBException("Illegal data value in RequestRecord: " +
+ r.toString());
+ }
+ }
+ }
+
+ protected static Vector mAttrs = new Vector();
+
+ static Hashtable mAttrTable = new Hashtable();
+
+ /*
+ * This table contains attribute handlers for attributes
+ * of the request. These attributes are ones that are stored
+ * apart from the generic name/value pairs supported by the get/set
+ * interface plus the hashtable for the name/value pairs themselves.
+ *
+ * NOTE: Eventually, all attributes should be done here. Currently
+ * only the last ones added are implemented this way.
+ */
+ static RequestAttr mRequestA[] = {
+
+ new RequestAttr(IRequest.ATTR_REQUEST_TYPE,
+ new StringMapper(Schema.LDAP_ATTR_REQUEST_TYPE)) {
+ void set(ARequestRecord r, Object o) {
+ r.mRequestType = (String) o;
+ }
+
+ Object get(ARequestRecord r) {
+ return r.mRequestType;
+ }
+
+ void read(IRequestMod a, IRequest r, ARequestRecord rr) {
+ r.setRequestType(rr.mRequestType);
+ }
+
+ void add(IRequest r, ARequestRecord rr) {
+ rr.mRequestType = r.getRequestType();
+ }
+
+ void mod(ModificationSet mods, IRequest r) {
+ addmod(mods, r.getRequestType());
+ }
+ }
+
+ };
+ static {
+ mAttrs.add(IRequestRecord.ATTR_REQUEST_ID);
+ mAttrs.add(IRequestRecord.ATTR_REQUEST_STATE);
+ mAttrs.add(IRequestRecord.ATTR_CREATE_TIME);
+ mAttrs.add(IRequestRecord.ATTR_MODIFY_TIME);
+ mAttrs.add(IRequestRecord.ATTR_SOURCE_ID);
+ mAttrs.add(IRequestRecord.ATTR_REQUEST_OWNER);
+ mAttrs.add(IRequestRecord.ATTR_EXT_DATA);
+
+ for (int i = 0; i < mRequestA.length; i++) {
+ RequestAttr ra = mRequestA[i];
+
+ mAttrs.add(ra.mAttrName);
+ mAttrTable.put(ra.mAttrName, ra);
+ }
+ }
+
+}
+
+
+//
+// A mapper between an request state object and
+// its LDAP attribute representation
+// <P>
+//
+// @author thayes
+// @version $Revision$ $Date$
+//
+class RequestStateMapper
+ implements IDBAttrMapper {
+ // IDBAttrMapper methods
+
+ //
+ //
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mAttrs.elements();
+ }
+
+ //
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs) {
+ RequestStatus rs = (RequestStatus) obj;
+
+ attrs.add(new LDAPAttribute(Schema.LDAP_ATTR_REQUEST_STATE,
+ rs.toString()));
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent)
+ throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(Schema.LDAP_ATTR_REQUEST_STATE);
+
+ if (attr == null) throw new EBaseException("schema violation");
+
+ String value = (String) attr.getStringValues().nextElement();
+
+ parent.set(name, RequestStatus.fromString(value));
+ }
+
+ public String mapSearchFilter(String name, String op, String value) {
+ return Schema.LDAP_ATTR_REQUEST_STATE + op + value;
+ }
+
+ protected final static Vector mAttrs = new Vector();
+
+ static {
+ mAttrs.add(Schema.LDAP_ATTR_REQUEST_STATE);
+ }
+}
+
+
+//
+// A mapper between an request id object and
+// its LDAP attribute representation
+// <P>
+//
+// @author thayes
+// @version $Revision$ $Date$
+//
+class RequestIdMapper
+ implements IDBAttrMapper {
+ // IDBAttrMapper methods
+
+ //
+ //
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mAttrs.elements();
+ }
+
+ //
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs) {
+ RequestId rid = (RequestId) obj;
+
+ String v = BigIntegerMapper.BigIntegerToDB(new BigInteger(rid.toString()));
+
+ attrs.add(new LDAPAttribute(Schema.LDAP_ATTR_REQUEST_ID, v));
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent)
+ throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(Schema.LDAP_ATTR_REQUEST_ID);
+
+ if (attr == null) throw new EBaseException("schema violation");
+
+ String value = (String) attr.getStringValues().nextElement();
+
+ parent.set(name, new RequestId(
+ BigIntegerMapper.BigIntegerFromDB(value).toString()));
+ }
+
+ public String mapSearchFilter(String name, String op, String value) {
+ String v = null;
+
+ try {
+ v = BigIntegerMapper.BigIntegerToDB(new BigInteger(value));
+ } catch (NumberFormatException e) {
+ v = value;
+ }
+ return Schema.LDAP_ATTR_REQUEST_ID + op + v;
+ }
+
+ protected final static Vector mAttrs = new Vector();
+
+ static {
+ mAttrs.add(Schema.LDAP_ATTR_REQUEST_ID);
+ }
+}
+
+
+/**
+ * A mapper between an request attr set and its LDAP attribute representation.
+ *
+ * The attr attribute is no longer used. This class is kept for historical
+ * and migration purposes.
+ *
+ * @author thayes
+ * @version $Revision$ $Date$
+ * @deprecated
+ */
+class RequestAttrsMapper
+ implements IDBAttrMapper {
+ // IDBAttrMapper methods
+
+ //
+ //
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mAttrs.elements();
+ }
+
+ //
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs) {
+ Hashtable ht = (Hashtable) obj;
+ Enumeration e = ht.keys();
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ String key = null;
+ Object value = null;
+
+ while (e.hasMoreElements()) {
+ key = (String) e.nextElement();
+ value = ht.get(key);
+ byte data[] = null;
+
+ try {
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (NotSerializableException x) {
+ if (Debug.ON) {
+ System.err.println("Error: attribute '" + key + "' (" +
+ x.getMessage() + ") is not serializable");
+ x.printStackTrace();
+ }
+ } catch (Exception x) {
+ if (Debug.ON) {
+ System.err.println("Error: attribute '" + key +
+ "' - error during serialization: " + x);
+ x.printStackTrace();
+ }
+ }
+ }
+
+ os.writeObject(null);
+ os.close();
+
+ attrs.add(new LDAPAttribute(Schema.LDAP_ATTR_REQUEST_ATTRS,
+ bos.toByteArray()));
+ } catch (Exception x) {
+ Debug.trace("Output Mapping Error in requeset ID " +
+ ((RequestRecord) parent).getRequestId().toString() + " : " + x);
+ //if (Debug.ON) {
+ Debug.printStackTrace(x);
+ //}
+ }
+ }
+
+ private byte[] encode(Object value)
+ throws NotSerializableException, IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+
+ return bos.toByteArray();
+ }
+
+ private Object decode(byte[] data)
+ throws ObjectStreamException, IOException, ClassNotFoundException {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ return is.readObject();
+ }
+
+ private Hashtable decodeHashtable(byte[] data)
+ throws ObjectStreamException, IOException, ClassNotFoundException {
+ Hashtable ht = new Hashtable();
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ String key = null;
+
+ try {
+
+ while (true) {
+ key = (String) is.readObject();
+
+ // end of table is marked with null
+ if (key == null) break;
+
+ byte[] bytes = (byte[]) is.readObject();
+
+ ht.put(key, decode(bytes));
+ }
+ } catch (ObjectStreamException e) {
+ Debug.trace("Key " + key); // would be nice to know object type.
+ throw e;
+ } catch (IOException e) {
+ Debug.trace("Key " + key); // would be nice to know object type.
+ throw e;
+ } catch (ClassNotFoundException e) {
+ Debug.trace("Key " + key); // would be nice to know object type.
+ throw e;
+ }
+
+ return ht;
+ }
+
+ /**
+ * Implements IDBAttrMapper.mapLDAPAttributeSetToObject
+ * <p>
+ * @see IDBAttrMapper#mapLDAPAttributeSetToObject
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent)
+ throws EBaseException {
+ Hashtable ht = null;
+
+ //
+ // Data is stored in a (single valued) binary attribute
+ //
+ byte[] value;
+
+ LDAPAttribute attr = null;
+
+ try {
+ attr = attrs.getAttribute(Schema.LDAP_ATTR_REQUEST_ATTRS);
+
+ if (attr != null) {
+ Enumeration values = attr.getByteValues();
+
+ value = (byte[]) values.nextElement();
+
+ ht = decodeHashtable(value);
+ }
+ } catch (Exception x) {
+ Debug.trace("Mapping error in request Id " +
+ ((RequestRecord) parent).getRequestId().toString() + " : " + x);
+ Debug.trace("Attr " + attr.getName());
+ //if (Debug.ON) {
+ Debug.printStackTrace(x);
+ //}
+ }
+
+ parent.set(name, ht);
+ }
+
+ public String mapSearchFilter(String name, String op, String value) {
+ return Schema.LDAP_ATTR_REQUEST_ID + op + value;
+ }
+
+ protected final static Vector mAttrs = new Vector();
+
+ static {
+ mAttrs.add(Schema.LDAP_ATTR_REQUEST_ATTRS);
+ }
+}
+
+/**
+ * Maps dynamic data for the extData- prefix to and from the extData Hashtable
+ * in RequestRecord.
+ *
+ * The data in RequestRecord is stored in a Hashtable. It comes in two forms:
+ * 1. String key1 => String value1
+ * String key2 => String value2
+ * This is stored in LDAP as:
+ * extData-key1 => value1
+ * extData-key2 => value2
+ *
+ * 2. String key => Hashtable value
+ * where value stores:
+ * String key2 => String value2
+ * String key3 => String value3
+ * This is stored in LDAP as:
+ * extData-key;key2 => value2
+ * extData-key;key3 => value3
+ *
+ * These can be mixed, but each top-level key can only be associated with
+ * a String value or a Hashtable value.
+ *
+ */
+class ExtAttrDynMapper implements IDBDynAttrMapper {
+
+ public boolean supportsLDAPAttributeName(String attrName) {
+ return (attrName != null) &&
+ attrName.toLowerCase().startsWith(extAttrPrefix);
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mAttrs.elements();
+ }
+
+
+ /**
+ * Decodes extdata encoded keys.
+ * -- followed by a 4 digit hexadecimal string is decoded to the character
+ * representing the hex string.
+ *
+ * The routine is written to be highly efficient. It only allocates
+ * the StringBuffer if needed and copies the pieces in large chunks.
+ *
+ * @param key The key to decode
+ * @return The decoded key.
+ */
+ public String decodeKey(String key) {
+ StringBuffer output = null;
+ char[] input = key.toCharArray();
+ int startCopyIndex = 0;
+
+ int index = 0;
+ while (index < input.length) {
+ if (input[index] == '-') {
+ if ( ((index + 1) < input.length) &&
+ (input[index + 1] == '-')) {
+ if (output == null) {
+ output = new StringBuffer(input.length);
+ }
+ output.append(input, startCopyIndex, index - startCopyIndex);
+ index += 2;
+ if ((index + 3) < input.length) {
+ output.append(
+ Character.toChars(
+ Integer.parseInt(new String(input, index, 4),
+ 16))
+ );
+ }
+ index += 4;
+ startCopyIndex = index;
+ } else {
+ index++;
+ }
+ } else {
+ index++;
+ }
+ }
+
+ if (output == null) {
+ return key;
+ } else {
+ output.append(input, startCopyIndex, index - startCopyIndex);
+ return output.toString();
+ }
+ }
+
+ /**
+ * Encoded extdata keys for storage in LDAP.
+ *
+ * The rules for encoding are trickier than decoding. We want to allow
+ * '-' by itself to be stored in the database (for the common case of keys
+ * like 'Foo-Bar'. Therefore we are using '--' as the encoding character.
+ * The rules are:
+ * 1) All characters [^-a-zA-Z0-9] are encoded as --XXXX where XXXX is the
+ * hex representation of the digit.
+ * 2) [a-zA-Z0-9] are always passed through unencoded
+ * 3) [-] is passed through as long as it is preceded and followed
+ * by [a-zA-Z0-9] (or if it's at the beginning/end of the string)
+ * 4) If [-] is preceded or followed by [^a-zA-Z0-9] then
+ * the - as well as all following [^a-zA-Z0-9] characters are encoded
+ * as --XXXX.
+ *
+ * This routine tries to be as efficient as possible with StringBuffer and
+ * large copies. However, the encoding unfortunately requires several
+ * objects to be allocated.
+ *
+ * @param key The key to encode
+ * @return The encoded key
+ */
+ public String encodeKey(String key) {
+ StringBuffer output = null;
+ char[] input = key.toCharArray();
+ int startCopyIndex = 0;
+
+ int index = 0;
+ while (index < input.length) {
+ if (! isAlphaNum(input[index])) {
+ if ((input[index] == '-') &&
+ ((index + 1) < input.length) &&
+ (isAlphaNum(input[index + 1]))) {
+ index += 2;
+ } else if ((input[index] == '-') &&
+ ((index + 1) == input.length)) {
+ index += 1;
+ } else {
+ if (output == null) {
+ output = new StringBuffer(input.length + 5);
+ }
+ output.append(input, startCopyIndex, index - startCopyIndex);
+ while ( (index < input.length) &&
+ (! isAlphaNum(input[index])) ) {
+ output.append("--");
+ String hexString = Integer.toHexString(input[index]);
+ int padding = 4 - hexString.length();
+ while (padding > 0) {
+ output.append('0');
+ padding--;
+ }
+ output.append(hexString);
+ index++;
+ }
+ startCopyIndex = index;
+ }
+ } else {
+ index++;
+ }
+ }
+
+ if (output == null) {
+ return key;
+ } else {
+ output.append(input, startCopyIndex, index - startCopyIndex);
+ return output.toString();
+ }
+ }
+
+ protected boolean isAlphaNum(char in) {
+ if ((in >= 'a') && (in <= 'z')) {
+ return true;
+ }
+ if ((in >= 'A') && (in <= 'Z')) {
+ return true;
+ }
+ if ((in >= '0') && (in <= '9')) {
+ return true;
+ }
+ return false;
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ Hashtable ht = (Hashtable) obj;
+ Enumeration e = ht.keys();
+
+ try {
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ Object value = ht.get(key);
+ if (value instanceof String) {
+ String stringValue = (String)value;
+ attrs.add(new LDAPAttribute(
+ extAttrPrefix + encodeKey(key),
+ stringValue));
+ } else if (value instanceof Hashtable) {
+ Hashtable innerHash = (Hashtable)value;
+ Enumeration innerHashEnum = innerHash.keys();
+ while (innerHashEnum.hasMoreElements()){
+ String innerKey = (String)innerHashEnum.nextElement();
+ String innerValue = (String)innerHash.get(innerKey);
+ attrs.add(new LDAPAttribute(
+ extAttrPrefix + encodeKey(key) + ";" + encodeKey(innerKey),
+ innerValue));
+ }
+ }
+ }
+ } catch (Exception x) {
+ Debug.trace("Output Mapping Error in requeset ID " +
+ ((IRequestRecord) parent).getRequestId().toString() + " : " + x);
+ //if (Debug.ON) {
+ Debug.printStackTrace(x);
+ //}
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs, String name,
+ IDBObj parent)
+ throws EBaseException {
+ Hashtable ht = new Hashtable();
+ Hashtable valueHashtable;
+
+ Enumeration attrEnum = attrs.getAttributes();
+ while (attrEnum.hasMoreElements()) {
+ LDAPAttribute attr = (LDAPAttribute)attrEnum.nextElement();
+ String baseName = attr.getBaseName();
+ if (baseName.toLowerCase().startsWith(extAttrPrefix)) {
+ String keyName = decodeKey(
+ baseName.substring(extAttrPrefix.length()));
+ String[] subTypes = attr.getSubtypes();
+ String[] values = attr.getStringValueArray();
+ if (values.length != 1) {
+ String message = "Output Mapping Error in request ID " +
+ ((IRequestRecord) parent).getRequestId().toString() + " : " +
+ "more than one value returned for " +
+ keyName;
+ Debug.trace(message);
+ throw new EBaseException(message);
+ }
+ if ((subTypes != null) && (subTypes.length > 0)) {
+ if (subTypes.length != 1) {
+ String message = "Output Mapping Error in request ID " +
+ ((IRequestRecord) parent).getRequestId().toString() + " : " +
+ "more than one subType returned for " +
+ keyName;
+ Debug.trace(message);
+ throw new EBaseException(message);
+ }
+ Object value = ht.get(keyName);
+ if ((value != null) && (! (value instanceof Hashtable))) {
+ String message = "Output Mapping Error in request ID " +
+ ((IRequestRecord) parent).getRequestId().toString() + " : " +
+ "combined no-subtype and subtype data for key " +
+ keyName;
+ Debug.trace(message);
+ throw new EBaseException(message);
+ }
+ valueHashtable = (Hashtable)value;
+ if (valueHashtable == null) {
+ valueHashtable = new Hashtable();
+ ht.put(keyName, valueHashtable);
+ }
+ valueHashtable.put(decodeKey(subTypes[0]), values[0]);
+ } else {
+ ht.put(keyName, values[0]);
+ }
+ }
+ }
+
+ parent.set(name, ht);
+ }
+
+ public String mapSearchFilter(String name, String op, String value) throws EBaseException {
+ return name + op + value;
+ }
+
+ protected final static String extAttrPrefix = "extdata-";
+
+ protected final static Vector mAttrs = new Vector();
+
+ static {
+ mAttrs.add(Schema.LDAP_ATTR_EXT_ATTR);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestRepository.java b/pki/base/common/src/com/netscape/cmscore/request/RequestRepository.java
new file mode 100644
index 000000000..c6ab7129e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/RequestRepository.java
@@ -0,0 +1,214 @@
+// --- 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.cmscore.request;
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.dbs.*;
+
+
+/**
+ * TODO: what does this class provide beyond the Repository
+ * base class??
+ * <p>
+ * @author thayes
+ * @version $Revision$ $Date$
+ */
+class RequestRepository
+ extends Repository {
+
+ IDBSubsystem mDB = null;
+ IRequestQueue mRequestQueue = null;
+ /**
+ * Create a request repository that uses the LDAP database
+ * <p>
+ * @param name
+ * the name of the repository. This String is used to
+ * construct the DN for the repository's LDAP entry.
+ * @param db
+ * the LDAP database system.
+ */
+ public RequestRepository(String name, int increment, IDBSubsystem db)
+ throws EDBException {
+ super(db, increment, "ou=" + name + ",ou=requests," + db.getBaseDN());
+
+ CMS.debug("RequestRepository: constructor 1");
+ mBaseDN = "ou=" + name + ",ou=requests," + db.getBaseDN();
+
+ // Let RequestRecord class register its
+ // database mapping and object mapping values
+ RequestRecord.register(db);
+ mDB = db;
+ }
+
+ public RequestRepository(String name, int increment, IDBSubsystem db,IRequestQueue requestQueue)
+ throws EDBException {
+ super(db, increment, "ou=" + name + ",ou=requests," + db.getBaseDN());
+
+ CMS.debug("RequestRepository: constructor2.");
+ mRequestQueue = requestQueue;
+ mBaseDN = "ou=" + name + ",ou=requests," + db.getBaseDN();
+
+ // Let RequestRecord class register its
+ // database mapping and object mapping values
+ RequestRecord.register(db);
+ mDB = db;
+ }
+
+ /**
+ * get the LDAP base DN for this repository. This
+ * value can be used by the request queue to create the
+ * name for the request records themselves.
+ * <p>
+ * @return
+ * the LDAP base DN.
+ */
+ public String getBaseDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException
+ {
+ setTheSerialNumber(serial);
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ IDBSSession s = mDB.createSession();
+ try {
+ Enumeration e = s.search(getBaseDN(),
+ "(" + RequestRecord.ATTR_REQUEST_ID + "=*)");
+ while (e.hasMoreElements()) {
+ RequestRecord r = (RequestRecord)e.nextElement();
+ String name = "cn" + "=" +
+ r.getRequestId().toString() + "," + getBaseDN();
+ s.delete(name);
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger min, BigInteger max)
+ {
+
+ CMS.debug("RequestRepository: in getLastSerialNumberInRange: min " + min + " max " + max);
+
+ CMS.debug("RequestRepository: mRequestQueue " + mRequestQueue);
+
+ BigInteger ret = null;
+
+ if(mRequestQueue == null) {
+
+ CMS.debug("RequestRepository: mRequestQueue is null.");
+
+ } else {
+
+ CMS.debug("RequestRepository: about to call mRequestQueue.getLastRequestIdInRange");
+ ret = mRequestQueue.getLastRequestIdInRange(min,max);
+
+ }
+
+ return ret;
+
+ }
+ /**
+ * the LDAP base DN for this repository
+ */
+ protected String mBaseDN;
+
+
+ public String getPublishingStatus() {
+ RepositoryRecord record = null;
+ Object obj = null;
+ IDBSSession dbs = null;
+ String status = null;
+
+ try {
+ dbs = mDB.createSession();
+ obj = dbs.read(mBaseDN);
+ } catch (Exception e) {
+ CMS.debug("RequestRepository: getPublishingStatus: Error: " + e);
+ CMS.debugStackTrace();
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) {
+ try {
+ dbs.close();
+ } catch (Exception ex) {
+ CMS.debug("RequestRepository: getPublishingStatus: Error: " + ex);
+ }
+ }
+ }
+
+ if (obj != null || (obj instanceof RepositoryRecord)) {
+ record = (RepositoryRecord) obj;
+ status = record.getPublishingStatus();
+ } else {
+ CMS.debug("RequestRepository: obj is NOT instanceof RepositoryRecord");
+ }
+ CMS.debug("RequestRepository: getPublishingStatus mBaseDN: " + mBaseDN +
+ " status: " + ((status != null)?status:"null"));
+
+ return status;
+ }
+
+ public void setPublishingStatus(String status) {
+ IDBSSession dbs = null;
+
+ CMS.debug("RequestRepository: setPublishingStatus mBaseDN: " + mBaseDN + " status: " + status);
+ ModificationSet mods = new ModificationSet();
+
+ if (status != null && status.length() > 0) {
+ mods.add(IRepositoryRecord.ATTR_PUB_STATUS,
+ Modification.MOD_REPLACE, status);
+
+ try {
+ dbs = mDB.createSession();
+ dbs.modify(mBaseDN, mods);
+ } catch (Exception e) {
+ CMS.debug("RequestRepository: setPublishingStatus: Error: " + e);
+ CMS.debugStackTrace();
+ } finally {
+ // Close session - ignoring errors (UTIL)
+ if (dbs != null) {
+ try {
+ dbs.close();
+ } catch (Exception ex) {
+ CMS.debug("RequestRepository: setPublishingStatus: Error: " + ex);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java b/pki/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java
new file mode 100644
index 000000000..2e05e54eb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java
@@ -0,0 +1,190 @@
+// --- 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.cmscore.request;
+
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.cmscore.dbs.DBSubsystem;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.*;
+
+
+/**
+ * RequestSubsystem
+ * <p>
+ * This class is reponsible for managing storage of request objects
+ * in the local database.
+ * <p>
+ * TODO: review this
+ * It provides:
+ * + registration of LDAP/JAVA mapping classes with the DBSubsystem
+ * + creation of RequestQueue storage in the database
+ * + retrieval of existing RequestQueue objects from the database
+ * <p>
+ * @author thayes
+ * @version $Revision$, $Date$
+ */
+public class RequestSubsystem
+ implements IRequestSubsystem, ISubsystem {
+
+ public final static String ID = IRequestSubsystem.SUB_ID;
+
+ // singleton enforcement
+
+ private static RequestSubsystem mInstance = new RequestSubsystem();
+
+ public static RequestSubsystem getInstance() {
+ return mInstance;
+ }
+
+ private RequestSubsystem() {
+ }
+
+ // end singleton enforcement.
+
+ //
+ // Create a new request queue. The LDAP DN for the entry
+ // in the database is supplied by the caller.
+ //
+ public void createRequestQueue(String name)
+ throws EBaseException {
+
+ /*
+ String dbName = makeQueueName(name);
+ IDBSSession dbs = createDBSSession();
+
+ // Create Repository record here
+
+ dbs.add(dbName, r);
+ */
+ }
+
+ public IRequestQueue
+ getRequestQueue(String name, int increment, IPolicy p, IService s, INotify n)
+ throws EBaseException {
+ return getRequestQueue(name, increment, p, s, n, null);
+ }
+
+ public IRequestQueue
+ getRequestQueue(String name, int increment, IPolicy p, IService s, INotify n,
+ INotify pendingNotifier)
+ throws EBaseException {
+ RequestQueue rq = new RequestQueue(name, increment, p, s, n, pendingNotifier);
+
+ // can't do this here because the service depends on getting rq
+ // (to get request) and since this method hasn't returned it's rq is null.
+ //rq.recover();
+
+ return rq;
+ }
+
+ //
+ // ISubsystem methods:
+ // getId, setId, init, startup, shutdown, getConfigStore
+ //
+
+ /**
+ * Implements ISubsystem.getId
+ * <p>
+ * @see ISubsystem#getId
+ */
+ public String getId() {
+ return mId;
+ }
+
+ // ISubsystem.setId
+ public void setId(String id)
+ throws EBaseException {
+ mId = id;
+ }
+
+ // ISubsystem.init
+ public void init(ISubsystem parent, IConfigStore config) {
+ mParent = parent;
+ mConfig = config;
+ }
+
+ /**
+ * Implements ISubsystem.startup
+ * <p>
+ * @see ISubsystem#startup
+ */
+ public void startup()
+ throws EBaseException {
+ mLogger = CMS.getLogger();
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_REQQUEUE, ILogger.LL_INFO,
+ "Request subsystem started");
+ }
+
+ public void shutdown() {
+ mRequestQueue = null;
+
+ if (mLogger != null) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_REQQUEUE, ILogger.LL_INFO,
+ "Request subsystem stopped");
+ }
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ //
+ // Access to the DBSubsystem environment value
+ //
+ protected IDBSubsystem getDBSubsystem() {
+ return DBSubsystem.getInstance();
+ }
+
+ //
+ // Create a database session in the default database
+ // system.
+ //
+ protected IDBSSession createDBSSession()
+ throws EBaseException {
+ return getDBSubsystem().createSession();
+ }
+
+ //
+ // Make a queue name
+ //
+ protected String makeQueueName(String name) {
+ IDBSubsystem db = getDBSubsystem();
+
+ return "cn=" + name + "," + db.getBaseDN();
+ }
+
+ // Instance variables
+
+ private IConfigStore mConfig;
+ private ISubsystem mParent;
+ private String mId = IRequestSubsystem.SUB_ID;
+ private IRequestQueue mRequestQueue;
+
+ protected ILogger mLogger;
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/request/Schema.java b/pki/base/common/src/com/netscape/cmscore/request/Schema.java
new file mode 100644
index 000000000..182e3470e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/request/Schema.java
@@ -0,0 +1,51 @@
+// --- 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.cmscore.request;
+
+
+//
+// The Schema class contains constant string values for
+// LDAP attribute and object class names used in this package
+//
+class Schema {
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_OC_REQUEST = "request";
+ public static final String LDAP_OC_EXTENSIBLE = "extensibleObject";
+
+ public static final String LDAP_ATTR_REQUEST_ID = "requestId";
+ public static final String LDAP_ATTR_REQUEST_STATE = "requestState";
+ public static final String LDAP_ATTR_CREATE_TIME = "dateOfCreate";
+ public static final String LDAP_ATTR_MODIFY_TIME = "dateOfModify";
+ public static final String LDAP_ATTR_REQUEST_XATTRS = "adminMessages";
+ public static final String LDAP_ATTR_SOURCE_ID = "requestSourceId";
+
+ public static final String LDAP_ATTR_REQUEST_OWNER = "requestOwner";
+ public static final String LDAP_ATTR_REQUEST_ATTRS = "requestAttributes";
+ public static final String LDAP_ATTR_AGENT_GROUP = "requestAgentGroup";
+ public static final String LDAP_ATTR_REQUEST_TYPE = "requestType";
+ public static final String LDAP_ATTR_REQUEST_ERROR = "requestError";
+
+ // This attribute is a placeholder used by ExtAttrDynMapper
+ public static final String LDAP_ATTR_EXT_ATTR = "extAttr";
+
+ // Indicates a special state that may be searched for exactly
+ // such as requiresAgentService. The idea is to reduce the space
+ // used in indexes to optimize common queries.
+ // NOT IMPLEMENTED
+ public static final String LDAP_ATTR_REQUEST_FLAG = "requestFlag";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/security/CASigningCert.java b/pki/base/common/src/com/netscape/cmscore/security/CASigningCert.java
new file mode 100644
index 000000000..22d0b8c17
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/CASigningCert.java
@@ -0,0 +1,169 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.cert.*;
+import java.security.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.apps.CMS;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.*;
+
+
+/**
+ * CA signing certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CASigningCert extends CertificateInfo {
+
+ public static final String SUBJECT_NAME =
+ "CN=Certificate Authority, O=Netscape Communications, C=US";
+
+ public CASigningCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public CASigningCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ /* included in console UI
+ try {
+ if (mProperties.get(Constants.PR_AKI) == null) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+ */
+ try {
+ if (mProperties.get(Constants.PR_CERT_LEN) == null) {
+ mProperties.put(Constants.PR_CERT_LEN, "-1");
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_CERT_LEN, "-1");
+ }
+ try {
+ if (mProperties.get(Constants.PR_IS_CA) == null) {
+ // "null" mean no BasicConstriant
+ mProperties.put(Constants.PR_IS_CA, "null");
+ }
+ } catch (Exception e) {
+ // "null" mean no BasicConstriant
+ mProperties.put(Constants.PR_IS_CA, "null");
+ }
+ /* included in console UI
+ try {
+ if (mProperties.get(Constants.PR_SKI) == null) {
+ mProperties.put(Constants.PR_SKI, Constants.FALSE);
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_SKI, Constants.FALSE);
+ }
+ */
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ // get PQG params from the configuration file
+ public static PQGParams getPQGParams() throws EBaseException, IOException,
+ PQGParamGenException {
+
+ byte[] p = mConfig.getByteArray("ca.dsaP", null);
+ byte[] q = mConfig.getByteArray("ca.dsaQ", null);
+ byte[] g = mConfig.getByteArray("ca.dsaG", null);
+ byte[] seed = mConfig.getByteArray("ca.dsaSeed", null);
+ byte[] H = mConfig.getByteArray("ca.dsaH", null);
+ int counter = mConfig.getInteger("ca.dsaCounter", 0);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+ BigInteger pqgSeed = new BigInteger(seed);
+ BigInteger pqgH = new BigInteger(H);
+
+ return new PQGParams(P, Q, G, pqgSeed, counter, pqgH);
+ }
+ return null;
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+
+ cmsFileTmp.putString("ca.signing.tokenname", tokenname);
+ String keyType = (String) mProperties.get(Constants.PR_KEY_TYPE);
+ String alg = "";
+
+ if (keyType.equals("DSA"))
+ alg = "SHA1withDSA";
+ else if (keyType.equals("RSA"))
+ alg = "SHA1withRSA";
+ else
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", keyType));
+
+ cmsFileTmp.putString("ca.signing.defaultSigningAlgorithm", alg);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ cmsFileTmp.putString("ca.signing.cacertnickname", nickname);
+ else
+ cmsFileTmp.putString("ca.signing.cacertnickname",
+ tokenname + ":" + nickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName = (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "caSigningCert " + instanceName;
+ }
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ extension.set(KeyUsageExtension.NON_REPUDIATION, new Boolean(true));
+ extension.set(KeyUsageExtension.KEY_CERTSIGN, new Boolean(true));
+ extension.set(KeyUsageExtension.CRL_SIGN, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/CertificateInfo.java b/pki/base/common/src/com/netscape/cmscore/security/CertificateInfo.java
new file mode 100644
index 000000000..f702f2e87
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/CertificateInfo.java
@@ -0,0 +1,255 @@
+// --- 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.cmscore.security;
+
+
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.crypto.Signature;
+
+
+/**
+ * This base class provides methods to import CA signing cert or get certificate
+ * request.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public abstract class CertificateInfo {
+
+ protected KeyCertData mProperties;
+ protected KeyPair mKeyPair;
+ protected static IConfigStore mConfig;
+
+ public CertificateInfo(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public CertificateInfo(KeyCertData properties, KeyPair pair) {
+ mProperties = properties;
+ if (pair == null) {
+ mKeyPair = (KeyPair) properties.get("keypair");
+ } else {
+ mKeyPair = pair;
+ }
+ mConfig = (IConfigStore) (mProperties.get("cmsFile"));
+ }
+
+ protected abstract KeyUsageExtension getKeyUsageExtension() throws IOException;
+
+ public abstract String getSubjectName();
+
+ //public abstract SignatureAlgorithm getSigningAlgorithm();
+ public abstract String getKeyAlgorithm();
+
+ public abstract String getNickname();
+
+ public abstract void updateConfig(IConfigStore store) throws EBaseException;
+
+ public CertificateValidity getCertificateValidity() throws EBaseException {
+
+ /*
+ String period = (String)mProperties.get(Constants.PR_VALIDITY_PERIOD);
+ Date notBeforeDate = CMS.getCurrentDate();
+ Date notAfterDate = new Date(notBeforeDate.getYear(),
+ notBeforeDate.getMonth(),
+ notBeforeDate.getDate()+Integer.parseInt(period));
+ return new CertificateValidity(notBeforeDate, notAfterDate);
+ */
+ Date notBeforeDate = null;
+ Date notAfterDate = null;
+ String notBeforeStr = (String) mProperties.get("notBeforeStr");
+ String notAfterStr = (String) mProperties.get("notAfterStr");
+
+ if (notBeforeStr != null && notAfterStr != null) {
+ notBeforeDate = new Date(Long.parseLong(notBeforeStr));
+ notAfterDate = new Date(Long.parseLong(notAfterStr));
+ } else {
+ int beginYear =
+ Integer.parseInt(mProperties.getBeginYear()) - 1900;
+ int afterYear =
+ Integer.parseInt(mProperties.getAfterYear()) - 1900;
+ int beginMonth =
+ Integer.parseInt(mProperties.getBeginMonth());
+ int afterMonth =
+ Integer.parseInt(mProperties.getAfterMonth());
+ int beginDate =
+ Integer.parseInt(mProperties.getBeginDate());
+ int afterDate =
+ Integer.parseInt(mProperties.getAfterDate());
+ int beginHour =
+ Integer.parseInt(mProperties.getBeginHour());
+ int afterHour =
+ Integer.parseInt(mProperties.getAfterHour());
+ int beginMin =
+ Integer.parseInt(mProperties.getBeginMin());
+ int afterMin =
+ Integer.parseInt(mProperties.getAfterMin());
+ int beginSec =
+ Integer.parseInt(mProperties.getBeginSec());
+ int afterSec =
+ Integer.parseInt(mProperties.getAfterSec());
+
+ notBeforeDate = new Date(beginYear, beginMonth, beginDate,
+ beginHour, beginMin, beginSec);
+ notAfterDate = new Date(afterYear, afterMonth, afterDate,
+ afterHour, afterMin, afterSec);
+ }
+ return new CertificateValidity(notBeforeDate, notAfterDate);
+ }
+
+ public X509CertInfo getCertInfo() throws EBaseException, PQGParamGenException {
+ X509CertInfo certInfo = new X509CertInfo();
+
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ BigInteger serialNumber = mProperties.getSerialNumber();
+
+ certInfo.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber(serialNumber));
+ certInfo.set(X509CertInfo.EXTENSIONS, getExtensions());
+ certInfo.set(X509CertInfo.VALIDITY, getCertificateValidity());
+ String issuerName = mProperties.getIssuerName();
+
+ if (issuerName == null) {
+ issuerName = getSubjectName();
+ }
+
+ certInfo.set(X509CertInfo.ISSUER,
+ new CertificateIssuerName(new X500Name(issuerName)));
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(new X500Name(getSubjectName())));
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ PublicKey pubk = mKeyPair.getPublic();
+ X509Key xKey = KeyCertUtil.convertPublicKeyToX509Key(pubk);
+
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(xKey));
+ //SignatureAlgorithm algm = getSigningAlgorithm();
+ SignatureAlgorithm algm =
+ (SignatureAlgorithm) mProperties.get(Constants.PR_SIGNATURE_ALGORITHM);
+
+ if (algm == null) {
+ String hashtype = (String) mProperties.get(ConfigConstants.PR_HASH_TYPE);
+
+ algm = KeyCertUtil.getSigningAlgorithm(getKeyAlgorithm(), hashtype);
+ mProperties.put(Constants.PR_SIGNATURE_ALGORITHM, algm);
+ }
+
+ AlgorithmId sigAlgId = getAlgorithmId();
+
+ if (sigAlgId == null) {
+ byte[]encodedOID = ASN1Util.encode(algm.toOID());
+
+ sigAlgId = new AlgorithmId(new ObjectIdentifier(
+ new DerInputStream(encodedOID)));
+ }
+ certInfo.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(sigAlgId));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY"));
+ } catch (CertificateException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT", e.toString()));
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", ""));
+ }
+
+ return certInfo;
+ }
+
+ public CertificateExtensions getExtensions() throws IOException,
+ CertificateException, InvalidKeyException, NoSuchAlgorithmException {
+ CertificateExtensions exts = new CertificateExtensions();
+
+ KeyCertUtil.setExtendedKeyUsageExtension(exts, mProperties);
+ KeyCertUtil.setDERExtension(exts, mProperties);
+ KeyCertUtil.setBasicConstraintsExtension(exts, mProperties);
+ KeyCertUtil.setSubjectKeyIdentifier(mKeyPair, exts, mProperties);
+ //KeyCertUtil.setOCSPSigning(mKeyPair, exts, mProperties);
+ KeyCertUtil.setAuthInfoAccess(mKeyPair, exts, mProperties);
+ KeyCertUtil.setOCSPNoCheck(mKeyPair, exts, mProperties);
+ KeyPair caKeyPair = (KeyPair) mProperties.get(Constants.PR_CA_KEYPAIR);
+ String aki = mProperties.getAKI();
+
+ if ((aki != null) && (aki.equals(Constants.TRUE))) {
+ CertificateExtensions caexts = null;
+
+ // if (this instanceof CASigningCert) {
+ if (this.getClass().getName().indexOf("CASigningCert") != -1) {
+ caexts = exts;
+ } else {
+ caexts = mProperties.getCAExtensions();
+ }
+ setAuthorityKeyIdExt(caexts, exts);
+ }
+ boolean isKeyUsageEnabled = mProperties.getKeyUsageExtension();
+
+ if (isKeyUsageEnabled) {
+ KeyCertUtil.setKeyUsageExtension(
+ exts, getKeyUsageExtension());
+ }
+ return exts;
+ }
+
+ public AlgorithmId getAlgorithmId() {
+ return (AlgorithmId) (mProperties.get(Constants.PR_ALGORITHM_ID));
+ }
+
+ public void setAuthorityKeyIdExt(CertificateExtensions caexts, CertificateExtensions ext)
+ throws IOException, CertificateException, CertificateEncodingException,
+ CertificateParsingException {
+ SubjectKeyIdentifierExtension subjKeyExt = null;
+
+ try {
+ subjKeyExt =
+ (SubjectKeyIdentifierExtension) caexts.get(SubjectKeyIdentifierExtension.NAME);
+ } catch (IOException e) {
+ }
+
+ if (subjKeyExt == null)
+ return;
+ else {
+ KeyIdentifier keyId = (KeyIdentifier) subjKeyExt.get(
+ SubjectKeyIdentifierExtension.KEY_ID);
+ AuthorityKeyIdentifierExtension authExt =
+ new AuthorityKeyIdentifierExtension(false, keyId, null, null);
+
+ ext.set(AuthorityKeyIdentifierExtension.NAME, authExt);
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/JssSubsystem.java b/pki/base/common/src/com/netscape/cmscore/security/JssSubsystem.java
new file mode 100644
index 000000000..cf63a770b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/JssSubsystem.java
@@ -0,0 +1,2153 @@
+// --- 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.cmscore.security;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkcs7.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.security.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import netscape.security.x509.*;
+import java.security.cert.CertificateException;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import org.mozilla.jss.pkcs11.PK11SecureRandom;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.util.Debug;
+import netscape.ldap.util.*;
+import com.netscape.cmsutil.crypto.*;
+
+
+/**
+ * Subsystem for initializing JSS>
+ * <P>
+ * @version $Revision$ $Date$
+ */
+public final class JssSubsystem implements ICryptoSubsystem {
+ public static final String ID = "jss";
+
+ private static final String CONFIG_DIR = "configDir";
+ private static final String CERTPREFIX_ALIAS = "certPrefix";
+ private static final String KEYPREFIX_ALIAS = "keyPrefix";
+ private static final String CONFIGDIR_ALIAS = "configDir";
+ private static final String SECMODNAME_ALIAS = "secmodName";
+ private static final String PROP_ENABLE = "enable";
+ private static final String PROP_OCSP_ENABLE = "ocspcheck.enable";
+ private static final String PASSWORD_ALIAS = "password";
+ private static final String mId = ID;
+ private IConfigStore mSSLSubStore;
+ protected IConfigStore mConfig = null;
+ private boolean mInited = false;
+ private ILogger mLogger = null;
+ private CryptoManager mCryptoManager = null;
+
+ protected PasswordCallback mPWCB = null;
+
+ private static JssSubsystem mInstance = new JssSubsystem();
+ private Hashtable mNicknameMapCertsTable = new Hashtable();
+ private Hashtable mNicknameMapUserCertsTable = new Hashtable();
+
+ private FileInputStream devRandomInputStream=null;
+
+ // This date format is to format the date string of the certificate in such a way as
+ // May 01, 1999 01:55:55.
+ private static SimpleDateFormat mFormatter = new SimpleDateFormat("MMMMM dd, yyyy HH:mm:ss");
+
+ // SSL related variables.
+
+ private IConfigStore mSSLConfig = null;
+
+ private static final String PROP_SSL = "ssl";
+ private static final String PROP_SSL_CIPHERPREF = Constants.PR_CIPHER_PREF;
+ private static final String PROP_SSL_ECTYPE = Constants.PR_ECTYPE;
+
+ private static Hashtable mCipherNames = new Hashtable();
+
+ /* default sslv2 and sslv3 cipher suites(all), set if no prefs in config.*/
+ private static final String DEFAULT_CIPHERPREF =
+ "rc4export,rc2export,rc4,rc2,des,desede3," +
+ "rsa_rc4_40_md5,rsa_rc2_40_md5,rsa_des_sha," +
+ "rsa_rc4_128_md5,rsa_3des_sha,rsa_fips_des_sha," +
+ "rsa_fips_3des_sha,fortezza,fortezza_rc4_128_sha," +
+ "fortezza_null,rsa_null_md5";
+
+ /* list of all ciphers JSS supports */
+ private static final int mJSSCipherSuites[] = {
+ SSLSocket.SSL2_RC4_128_WITH_MD5,
+ SSLSocket.SSL2_RC4_128_EXPORT40_WITH_MD5,
+ SSLSocket.SSL2_RC2_128_CBC_WITH_MD5,
+ SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5,
+ SSLSocket.SSL2_DES_64_CBC_WITH_MD5,
+ SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5,
+ SSLSocket.SSL3_RSA_WITH_RC4_128_MD5,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA,
+ SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSLSocket.SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
+ SSLSocket.SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA,
+ SSLSocket.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+ SSLSocket.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
+ };
+
+ static {
+
+ /* set ssl cipher string names. */
+ /* disallowing SSL2 ciphers to be turned on
+ mCipherNames.put(Constants.PR_SSL2_RC4_128_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_RC4_128_WITH_MD5));
+ mCipherNames.put(Constants.PR_SSL2_RC4_128_EXPORT40_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_RC4_128_EXPORT40_WITH_MD5));
+ mCipherNames.put(Constants.PR_SSL2_RC2_128_CBC_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_RC2_128_CBC_WITH_MD5));
+ mCipherNames.put(Constants.PR_SSL2_RC2_128_CBC_EXPORT40_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5));
+ mCipherNames.put(Constants.PR_SSL2_DES_64_CBC_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_DES_64_CBC_WITH_MD5));
+ mCipherNames.put(Constants.PR_SSL2_DES_192_EDE3_CBC_WITH_MD5,
+ Integer.valueOf(SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5));
+ */
+ mCipherNames.put(Constants.PR_SSL3_RSA_WITH_NULL_MD5,
+ Integer.valueOf(SSLSocket.SSL3_RSA_WITH_NULL_MD5));
+ mCipherNames.put(Constants.PR_SSL3_RSA_EXPORT_WITH_RC4_40_MD5,
+ Integer.valueOf(SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5));
+ mCipherNames.put(Constants.PR_SSL3_RSA_WITH_RC4_128_MD5,
+ Integer.valueOf(SSLSocket.SSL3_RSA_WITH_RC4_128_MD5));
+ mCipherNames.put(Constants.PR_SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ Integer.valueOf(SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5));
+ mCipherNames.put(Constants.PR_SSL3_RSA_WITH_DES_CBC_SHA,
+ Integer.valueOf(SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA));
+ mCipherNames.put(Constants.PR_SSL3_RSA_WITH_3DES_EDE_CBC_SHA,
+ Integer.valueOf(SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA));
+ mCipherNames.put(Constants.PR_SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
+ Integer.valueOf(SSLSocket.SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA));
+ mCipherNames.put(Constants.PR_SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA,
+ Integer.valueOf(SSLSocket.SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA));
+ mCipherNames.put(Constants.PR_SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
+ Integer.valueOf(SSLSocket.SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA));
+ mCipherNames.put(Constants.PR_SSL_RSA_FIPS_WITH_DES_CBC_SHA,
+ Integer.valueOf(SSLSocket.SSL_RSA_FIPS_WITH_DES_CBC_SHA));
+ mCipherNames.put(Constants.PR_TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
+ Integer.valueOf(SSLSocket.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA));
+ mCipherNames.put(Constants.PR_TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+ Integer.valueOf(SSLSocket.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA));
+ }
+
+ public static JssSubsystem getInstance() {
+ return mInstance;
+ }
+
+ /**
+ * Constructs a Security service subsystem.
+ */
+ private JssSubsystem() {
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+
+ }
+
+ // Add entropy to the 'default' RNG token
+ public void addEntropy(int bits)
+ throws org.mozilla.jss.util.NotImplementedException,
+ IOException,
+ TokenException
+ {
+ int read=0;
+ int bytes = (7+bits)/8;
+ byte[] b = new byte[bytes];
+ if (devRandomInputStream == null) {
+ throw new IOException(CMS.getLogMessage("CMSCORE_SECURITY_NO_ENTROPY_STREAM"));
+ }
+ do {
+ int c = devRandomInputStream.read(b,read,bytes-read);
+ read += c;
+ }
+ while (read < bytes);
+
+ CMS.debug("JssSubsystem adding "+bits+" bits ("+bytes+" bytes) of entropy to default RNG token");
+ CMS.debug(b);
+ PK11SecureRandom sr = new PK11SecureRandom();
+ sr.setSeed(b);
+ }
+
+ /**
+ * Initializes the Jss security subsystem.
+ * <P>
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mLogger = CMS.getLogger();
+
+ if (mInited)
+ {
+ // This used to throw an exeception (e.g. - on Solaris).
+ // If JSS is already initialized simply return.
+ CMS.debug("JssSubsystem already inited.. returning.");
+ return;
+ }
+
+ mConfig = config;
+
+ // If disabled, just return
+ boolean enabled = config.getBoolean(PROP_ENABLE, true);
+
+ if (!enabled)
+ return;
+
+ try {
+ devRandomInputStream = new FileInputStream("/dev/urandom");
+ } catch (IOException ioe) {
+ // XXX - add new exception
+ }
+
+ // get hardcoded password (for debugging.
+ String pw;
+
+ if ((pw = config.getString(PASSWORD_ALIAS, null)) != null) {
+ // hardcoded password in config file
+ mPWCB = new Password(pw.toCharArray());
+ CMS.debug("JssSubsystem init() got password from hardcoded in config");
+ }
+
+ String certDir;
+
+ certDir = config.getString(CONFIG_DIR, null);
+
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(certDir,
+ "", "", "secmod.db");
+
+ vals.removeSunProvider = false;
+ vals.installJSSProvider = true;
+ try {
+ CryptoManager.initialize(vals);
+ } catch (AlreadyInitializedException e) {
+ // do nothing
+ } catch (Exception e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+
+ try {
+ mCryptoManager = CryptoManager.getInstance();
+ initSSL();
+ } catch (CryptoManager.NotInitializedException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+
+ mInited = true;
+ }
+
+ public String getCipherVersion() throws EBaseException {
+ return "cipherdomestic";
+ }
+
+ public String getCipherPreferences() throws EBaseException {
+ String cipherpref = "";
+
+ if (mSSLConfig != null) {
+ cipherpref = mSSLConfig.getString(PROP_SSL_CIPHERPREF, "");
+ if (cipherpref.equals("")) {
+ cipherpref = DEFAULT_CIPHERPREF;
+ }
+ }
+ return cipherpref;
+ }
+
+ public String getECType(String certType) throws EBaseException {
+ if (mSSLConfig != null) {
+ // for SSL server, check the value of jss.ssl.sslserver.ectype
+ return mSSLConfig.getString(certType + "." + PROP_SSL_ECTYPE, "ECDHE");
+ } else {
+ return "ECDHE";
+ }
+ }
+
+ public String isCipherFortezza() throws EBaseException {
+ // we always display fortezza suites.
+ // too much work to display tokens/certs corresponding to the
+ // suites.
+ return "true";
+ }
+
+ void installProvider() {
+ int position = java.security.Security.insertProviderAt(
+ new com.netscape.cmscore.security.Provider(),
+ 1);
+
+ if (position == -1) {
+ Debug.trace("Unable to install CMS provider");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_INSTALL_PROVIDER"));
+ }
+ }
+
+ public void setCipherPreferences(String cipherPrefs)
+ throws EBaseException {
+ if (mSSLConfig != null) {
+ if (cipherPrefs.equals(""))
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NO_EMPTY_CIPHERPREFS"));
+ mSSLConfig.putString(Constants.PR_CIPHER_PREF, cipherPrefs);
+ }
+ }
+
+ /**
+ * Initialize SSL cipher suites from config file.
+ *
+ */
+ private void initSSL() throws EBaseException {
+ // JSS will AND what is set and what is allowed by export policy
+ // so we can set what is requested.
+
+ try {
+ SSLServerSocket.configServerSessionIDCache(10, 0, 0, null);
+ } catch (SocketException e) {
+ }
+
+ mSSLConfig = mConfig.getSubStore(PROP_SSL);
+ String sslCiphers = null;
+
+ if (mSSLConfig != null)
+ sslCiphers = getCipherPreferences();
+ if (Debug.ON)
+ Debug.trace("configured ssl cipher prefs is " + sslCiphers);
+
+ // first, disable all ciphers, since JSS defaults to all-enabled
+ for (int i = mJSSCipherSuites.length - 1; i >= 0; i--) {
+ try {
+ SSLSocket.setCipherPreferenceDefault(mJSSCipherSuites[i],
+ false);
+ } catch (SocketException e) {
+ }
+ }
+
+ // the sslCiphers string will always contain something
+
+ if (sslCiphers != null && sslCiphers.length() != 0) {
+ StringTokenizer ciphers = new StringTokenizer(sslCiphers, ",");
+
+ if (!ciphers.hasMoreTokens()) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_INVALID_CIPHER", sslCiphers));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY", PROP_SSL_CIPHERPREF));
+ }
+ while (ciphers.hasMoreTokens()) {
+ String cipher = ciphers.nextToken();
+ Integer sslcipher = (Integer) mCipherNames.get(cipher);
+
+ if (sslcipher != null) {
+ String msg = "setting ssl cipher " + cipher;
+
+ CMS.debug("JSSSubsystem: initSSL(): "+msg);
+ log(ILogger.LL_INFO, msg);
+ if (Debug.ON)
+ Debug.trace(msg);
+ try {
+ SSLSocket.setCipherPreferenceDefault(
+ sslcipher.intValue(), true);
+ } catch (SocketException e) {
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieves a configuration store of this subsystem.
+ * <P>
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Starts up this service.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shutdowns this subsystem.
+ * <P>
+ */
+ public void shutdown() {
+ try {
+ // After talking to NSS teamm, we should not call close databases
+ // which will call NSS_Shutdown. Web Server will call NSS_Shutdown
+ boolean isClosing = mConfig.getBoolean("closeDatabases", false);
+ if (isClosing) {
+ JSSDatabaseCloser closer = new JSSDatabaseCloser();
+ closer.closeDatabases();
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level, "JSS " + msg);
+ }
+
+ public PasswordCallback getPWCB() {
+ return mPWCB;
+ }
+
+ public String getInternalTokenName() throws EBaseException {
+ CryptoToken c = mCryptoManager.getInternalKeyStorageToken();
+ String name = "";
+
+ try {
+ name = c.getName();
+ } catch (TokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+
+ return name;
+ }
+
+ public String getTokenList() throws EBaseException {
+ String tokenList = "";
+ Enumeration tokens = mCryptoManager.getExternalTokens();
+ int num = 0;
+
+ try {
+ while (tokens.hasMoreElements()) {
+ CryptoToken c = (CryptoToken) tokens.nextElement();
+
+ // skip builtin object token
+ if (c.getName() != null && c.getName().equals("Builtin Object Token")) {
+ continue;
+ }
+
+ if (num++ == 0)
+ tokenList = tokenList + c.getName();
+ else
+ tokenList = tokenList + "," + c.getName();
+ }
+ } catch (TokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+
+ if (tokenList.equals(""))
+ return Constants.PR_INTERNAL_TOKEN;
+ else
+ return (tokenList + "," + Constants.PR_INTERNAL_TOKEN);
+ }
+
+ public boolean isTokenLoggedIn(String name) throws EBaseException {
+ try {
+ if (name.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ name = Constants.PR_FULL_INTERNAL_TOKEN_NAME;
+ CryptoToken ctoken = mCryptoManager.getTokenByName(name);
+
+ return ctoken.isLoggedIn();
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TOKEN_LOGGED_IN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR"));
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TOKEN_LOGGED_IN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ }
+ }
+
+ public void loggedInToken(String tokenName, String pwd) throws EBaseException {
+ try {
+ CryptoToken ctoken = mCryptoManager.getTokenByName(tokenName);
+ Password clk = new Password(pwd.toCharArray());
+
+ ctoken.login(clk);
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TOKEN_LOGGED_IN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR"));
+ } catch (IncorrectPasswordException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TOKEN_LOGGED_IN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_LOGIN_FAILED"));
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TOKEN_LOGGED_IN", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ }
+ }
+
+ public String getCertSubjectName(String tokenname, String nickname)
+ throws EBaseException {
+ try {
+ return KeyCertUtil.getCertSubjectName(tokenname, nickname);
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+ }
+
+ public String getAllCerts() throws EBaseException {
+ String certNames = "";
+
+ try {
+ Enumeration enums = mCryptoManager.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = (CryptoToken) enums.nextElement();
+ CryptoStore store = token.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ for (int i = 0; i < list.length; i++) {
+ String nickname = list[i].getNickname();
+
+ if (certNames.equals(""))
+ certNames = certNames + nickname;
+ else
+ certNames = certNames + "," + nickname;
+ }
+ }
+ } catch (TokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+
+ return certNames;
+ }
+
+ public String getCertListWithoutTokenName(String name) throws EBaseException {
+
+ CryptoToken c = null;
+ String certNames = "";
+
+ try {
+ if (name.equals(Constants.PR_INTERNAL_TOKEN)) {
+ c = mCryptoManager.getInternalKeyStorageToken();
+ } else {
+ c = mCryptoManager.getTokenByName(name);
+ }
+
+ if (c != null) {
+ CryptoStore store = c.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ if (list == null)
+ return "";
+
+ for (int i = 0; i < list.length; i++) {
+ String nickname = list[i].getNickname();
+ int index = nickname.indexOf(":");
+
+ if (index != -1)
+ nickname = nickname.substring(index + 1);
+ if (i == 0)
+ certNames = certNames + nickname;
+ else
+ certNames = certNames + "," + nickname;
+ }
+ return certNames;
+ } else
+ return "";
+
+ } catch (TokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ } catch (NoSuchTokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+ }
+
+ public String getCertList(String name) throws EBaseException {
+
+ CryptoToken c = null;
+ String certNames = "";
+
+ try {
+ if (name.equals(Constants.PR_INTERNAL_TOKEN)) {
+ c = mCryptoManager.getInternalKeyStorageToken();
+ } else {
+ c = mCryptoManager.getTokenByName(name);
+ }
+
+ if (c != null) {
+ CryptoStore store = c.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ if (list == null)
+ return "";
+
+ for (int i = 0; i < list.length; i++) {
+ String nickname = list[i].getNickname();
+
+ if (i == 0)
+ certNames = certNames + nickname;
+ else
+ certNames = certNames + "," + nickname;
+ }
+ return certNames;
+ } else
+ return "";
+
+ } catch (TokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ } catch (NoSuchTokenException e) {
+ String[] params = {mId, e.toString()};
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GENERAL_ERROR", ex.toString()));
+ throw ex;
+ }
+ }
+
+ public AlgorithmId getAlgorithmId(String algname, IConfigStore store)
+ throws EBaseException {
+ try {
+ if (algname.equals("DSA")) {
+ byte[] p = store.getByteArray("ca.dsaP", null);
+ byte[] q = store.getByteArray("ca.dsaQ", null);
+ byte[] g = store.getByteArray("ca.dsaG", null);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+
+ return new AlgIdDSA(P, Q, G);
+ }
+ }
+ return AlgorithmId.getAlgorithmId(algname);
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", ""));
+ }
+ }
+
+ public String getSignatureAlgorithm(String nickname) throws EBaseException {
+ try {
+ X509Certificate cert =
+ CryptoManager.getInstance().findCertByNickname(nickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+
+ return impl.getSigAlgName();
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_ALG", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_ALG", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_ALG", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_ALG", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+ }
+
+ public KeyPair getKeyPair(String nickname) throws EBaseException {
+ try {
+ X509Certificate cert =
+ CryptoManager.getInstance().findCertByNickname(nickname);
+ PrivateKey priKey =
+ CryptoManager.getInstance().findPrivKeyByCert(cert);
+ PublicKey publicKey = cert.getPublicKey();
+
+ return new KeyPair(publicKey, priKey);
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, "Key Pair Error " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, "Key Pair Error " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, "Key Pair Error " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ }
+ }
+
+ public KeyPair getKeyPair(String tokenName, String alg,
+ int keySize) throws EBaseException {
+ return getKeyPair(tokenName, alg, keySize, null);
+ }
+
+ public KeyPair getKeyPair(String tokenName, String alg,
+ int keySize, PQGParams pqg) throws EBaseException {
+
+ String t = tokenName;
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN))
+ t = Constants.PR_FULL_INTERNAL_TOKEN_NAME;
+ CryptoToken token = null;
+
+ try {
+ token = mCryptoManager.getTokenByName(t);
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, "Generate Key Pair Error " + e);
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", tokenName));
+ }
+
+ KeyPairAlgorithm kpAlg = null;
+
+ if (alg.equals("RSA"))
+ kpAlg = KeyPairAlgorithm.RSA;
+ else {
+ kpAlg = KeyPairAlgorithm.DSA;
+ }
+
+ try {
+ KeyPair kp = KeyCertUtil.generateKeyPair(token, kpAlg, keySize, pqg);
+
+ return kp;
+ } catch (InvalidParameterException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_KEY_PAIR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEYSIZE_PARAMS",
+ "" + keySize));
+ } catch (PQGParamGenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_KEY_PAIR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_KEY_PAIR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED",
+ kpAlg.toString()));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_KEY_PAIR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_KEY_GEN_FAILED"));
+ } catch (InvalidAlgorithmParameterException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_KEY_PAIR", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", "DSA"));
+ }
+ }
+
+ public void isX500DN(String dn) throws EBaseException {
+ try {
+ X500Name name = new X500Name(dn);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_X500_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_X500_NAME", dn));
+ }
+ }
+
+ public String getCertRequest(String subjectName, KeyPair kp)
+ throws EBaseException {
+ try {
+ netscape.security.pkcs.PKCS10 pkcs =
+ KeyCertUtil.getCertRequest(subjectName, kp);
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+
+ pkcs.print(ps);
+ return bs.toString();
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", ""));
+ } catch (NoSuchProviderException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PROVIDER_NOT_SUPPORTED"));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_REQ_FAILED"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT", e.toString()));
+ } catch (SignatureException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_REQUEST", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_SIGNATURE"));
+ }
+ }
+
+ public void importCert(String b64E, String nickname, String certType)
+ throws EBaseException {
+ try {
+ KeyCertUtil.importCert(b64E, nickname, certType);
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DECODE_CERT_FAILED"));
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (UserCertConflictException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_USERCERT_CONFLICT"));
+ } catch (NicknameConflictException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NICKNAME_CONFLICT"));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ }
+ }
+
+ public KeyPair getKeyPair(KeyCertData properties) throws EBaseException {
+ String tokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ String keyType = "RSA";
+ int keyLength = 512;
+
+ String tmp = (String) properties.get(Constants.PR_TOKEN_NAME);
+
+ if ((tmp != null) &&
+ (!tmp.equals(Constants.PR_INTERNAL_TOKEN)))
+ tokenname = tmp;
+ tmp = (String) properties.get(Constants.PR_KEY_TYPE);
+ if (tmp != null)
+ keyType = tmp;
+ tmp = (String) properties.get(Constants.PR_KEY_LENGTH);
+ if (tmp != null)
+ keyLength = Integer.parseInt(tmp);
+
+ KeyPair pair = getKeyPair(tokenname, keyType, keyLength);
+
+ return pair;
+ }
+
+ public KeyPair getECCKeyPair(KeyCertData properties) throws EBaseException {
+ String token = Constants.PR_INTERNAL_TOKEN_NAME;
+ String keyType = "ECC";
+ String keyCurve = "nistp512";
+ String certType = null;
+ KeyPair pair = null;
+
+ String tmp = (String) properties.get(Constants.PR_TOKEN_NAME);
+ if (tmp != null)
+ token = tmp;
+
+ tmp = (String) properties.get(Constants.PR_KEY_CURVENAME);
+ if (tmp != null)
+ keyCurve = tmp;
+
+ certType = (String) properties.get(Constants.RS_ID);
+
+ pair = getECCKeyPair(token, keyCurve, certType);
+
+ return pair;
+ }
+
+ public KeyPair getECCKeyPair(String token, String keyCurve, String certType) throws EBaseException {
+ KeyPair pair = null;
+
+ if ((token == null) || (token.equals("")))
+ token = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ if ((keyCurve == null) || (keyCurve.equals("")))
+ keyCurve = "nistp512";
+
+ String ectype = getECType(certType);
+
+ // ECDHE needs "SIGN" but no "DERIVE"
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
+ };
+
+ // ECDH needs "DERIVE" but no any kind of "SIGN"
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage ECDH_usages_mask[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER,
+ };
+
+ try {
+ if (ectype.equals("ECDHE"))
+ pair = CryptoUtil.generateECCKeyPair(token, keyCurve, null, usages_mask);
+ else
+ pair = CryptoUtil.generateECCKeyPair(token, keyCurve, null, ECDH_usages_mask);
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ECC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ECC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ECC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NO_SUCH_ALGORITHM", e.toString()));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ECC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ }
+
+ return pair;
+ }
+
+ public void importCert(X509CertImpl signedCert, String nickname,
+ String certType) throws EBaseException {
+
+ try {
+ KeyCertUtil.importCert(signedCert, nickname, certType);
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ENCODE_CERT_FAILED"));
+ } catch (UserCertConflictException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_USERCERT_CONFLICT"));
+ } catch (NicknameConflictException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NICKNAME_CONFLICT"));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ENCODE_CERT_FAILED"));
+ }
+ }
+
+ public NameValuePairs getCertInfo(String b64E) throws EBaseException {
+ try {
+ byte[] b = KeyCertUtil.convertB64EToByteArray(b64E);
+ X509CertImpl impl = new X509CertImpl(b);
+ NameValuePairs results = new NameValuePairs();
+
+ results.add(Constants.PR_CERT_SUBJECT_NAME, impl.getSubjectDN().getName());
+ results.add(Constants.PR_ISSUER_NAME, impl.getIssuerDN().getName());
+ results.add(Constants.PR_SERIAL_NUMBER, impl.getSerialNumber().toString());
+ results.add(Constants.PR_BEFORE_VALIDDATE, impl.getNotBefore().toString());
+ results.add(Constants.PR_AFTER_VALIDDATE, impl.getNotAfter().toString());
+
+ // fingerprint is using MD5 hash
+
+ return results;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_INFO", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DECODE_CERT_FAILED"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_CERT_INFO", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DECODE_CERT_FAILED"));
+ }
+ }
+
+ public void deleteUserCert(String nickname, String serialno, String issuername)
+ throws EBaseException {
+ try {
+ X509Certificate cert = getCertificate(nickname, serialno, issuername);
+ if (cert instanceof TokenCertificate) {
+ TokenCertificate tcert = (TokenCertificate) cert;
+ CryptoStore store = tcert.getOwningToken().getCryptoStore();
+
+CMS.debug("*** deleting this token cert");
+ tcert.getOwningToken().getCryptoStore().deleteCert(tcert);
+CMS.debug("*** finish deleting this token cert");
+ } else {
+ CryptoToken token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+
+CMS.debug("*** deleting this interna cert");
+ store.deleteCert(cert);
+CMS.debug("*** removing this interna cert");
+ }
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ }
+ }
+
+ public void deleteRootCert(String nickname, String serialno,
+ String issuername) throws EBaseException {
+ int index = nickname.indexOf(":");
+ String tokenname = nickname.substring(0, index);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nickname.substring(index+1);
+ }
+ try {
+ if (mNicknameMapCertsTable != null) {
+ X509Certificate[] certs = (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+
+ if (certs == null) {
+ EBaseException e = new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CA_CERT", e.toString()));
+ throw e;
+ } else {
+ for (int i = 0; i < certs.length; i++) {
+ X509Certificate cert = certs[i];
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+ String num = impl.getSerialNumber().toString();
+ String issuer = impl.getIssuerDN().toString();
+CMS.debug("*** num "+num);
+CMS.debug("*** issuer "+issuer);
+ if (num.equals(serialno) && issuername.equals(issuer)) {
+CMS.debug("*** removing root cert");
+ if (cert instanceof TokenCertificate) {
+ TokenCertificate tcert = (TokenCertificate) cert;
+ CryptoStore store = tcert.getOwningToken().getCryptoStore();
+
+CMS.debug("*** deleting this token cert");
+ tcert.getOwningToken().getCryptoStore().deleteCert(tcert);
+CMS.debug("*** finish deleting this token cert");
+ } else {
+ CryptoToken token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+
+CMS.debug("*** deleting this interna cert");
+ store.deleteCert(cert);
+CMS.debug("*** removing this interna cert");
+ }
+ mNicknameMapCertsTable.remove(nickname);
+ break;
+ }
+ }
+ }
+ }
+
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public NameValuePairs getRootCerts() throws EBaseException {
+ NameValuePairs nvps = new NameValuePairs();
+ try {
+ Enumeration enums = mCryptoManager.getAllTokens();
+ if (mNicknameMapCertsTable != null)
+ mNicknameMapCertsTable.clear();
+
+ // a temp hashtable with vectors
+ Hashtable vecTable = new Hashtable();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = (CryptoToken) enums.nextElement();
+ String tokenName = token.getName();
+
+ CryptoStore store = token.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ for (int i = 0; i < list.length; i++) {
+ try {
+ PrivateKey key =
+ CryptoManager.getInstance().findPrivKeyByCert(list[i]);
+ Debug.trace("JssSubsystem getRootCerts: find private key "
+ +list[i].getNickname());
+ } catch (ObjectNotFoundException e) {
+ String nickname = list[i].getNickname();
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = Constants.PR_INTERNAL_TOKEN_NAME+":"+nickname;
+ }
+ X509CertImpl impl = null;
+
+ try {
+ Vector v;
+ if (vecTable.containsKey((Object) nickname) == true) {
+ v = (Vector) vecTable.get(nickname);
+ } else {
+ v = new Vector();
+ }
+ v.addElement(list[i]);
+ vecTable.put(nickname, v);
+ impl = new X509CertImpl(list[i].getEncoded());
+ } catch (CertificateException ex) {
+ // skip bad certificate
+ CMS.debug("bad certificate - " + nickname);
+ continue;
+ }
+ String serialno = impl.getSerialNumber().toString();
+ String issuer = impl.getIssuerDN().toString();
+ nvps.add(nickname+","+serialno, issuer);
+ Debug.trace("getRootCerts: nickname="+nickname+", serialno="+
+ serialno+", issuer="+issuer);
+ continue;
+ } catch (CryptoManager.NotInitializedException e) {
+ continue;
+ }
+ }
+ // convert hashtable of vectors to hashtable of arrays
+ Enumeration elms = vecTable.keys();
+
+ while (elms.hasMoreElements()) {
+ String key = (String) elms.nextElement();
+ Vector v = (Vector) vecTable.get((Object) key);
+ X509Certificate[] a = new X509Certificate[v.size()];
+
+ v.copyInto((Object[]) a);
+ mNicknameMapCertsTable.put(key, a);
+ }
+ }
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ALL_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+
+ return nvps;
+
+ }
+
+ public NameValuePairs getUserCerts() throws EBaseException {
+ NameValuePairs nvps = new NameValuePairs();
+ try {
+ Enumeration enums = mCryptoManager.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = (CryptoToken) enums.nextElement();
+ String tokenName = token.getName();
+
+ CryptoStore store = token.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ for (int i = 0; i < list.length; i++) {
+ try {
+ PrivateKey key =
+ CryptoManager.getInstance().findPrivKeyByCert(list[i]);
+ String nickname = list[i].getNickname();
+ if (tokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME) ||
+ tokenName.equals(Constants.PR_FULL_INTERNAL_TOKEN_NAME)) {
+ nickname = Constants.PR_INTERNAL_TOKEN_NAME+":"+nickname;
+ }
+ X509CertImpl impl = null;
+
+ try {
+ impl = new X509CertImpl(list[i].getEncoded());
+ } catch (CertificateException e) {
+ // skip bad certificate
+ CMS.debug("bad certificate - " + nickname);
+ continue;
+ }
+ String serialno = impl.getSerialNumber().toString();
+ String issuer = impl.getIssuerDN().toString();
+ nvps.add(nickname+","+serialno, issuer);
+ Debug.trace("getUserCerts: nickname="+nickname+", serialno="+
+ serialno+", issuer="+issuer);
+ } catch (ObjectNotFoundException e) {
+ Debug.trace("JssSubsystem getUserCerts: cant find private key "
+ +list[i].getNickname());
+ continue;
+ } catch (CryptoManager.NotInitializedException e) {
+ continue;
+ }
+ }
+ }
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ALL_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+
+ return nvps;
+
+ }
+
+ /*
+ * get all certificates on all tokens for Certificate Database Management
+ */
+ public NameValuePairs getAllCertsManage() throws EBaseException {
+
+ /*
+ * first get all CA certs (internal only),
+ * then all user certs (both internal and external)
+ */
+
+ NameValuePairs pairs = getCACerts();
+
+ if (mNicknameMapUserCertsTable != null)
+ mNicknameMapUserCertsTable.clear();
+
+ try {
+ Enumeration enums = mCryptoManager.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = (CryptoToken) enums.nextElement();
+ String tokenName = token.getName();
+
+ CryptoStore store = token.getCryptoStore();
+ X509Certificate[] list = store.getCertificates();
+
+ for (int i = 0; i < list.length; i++) {
+ String nickname = list[i].getNickname();
+ X509Certificate[] certificates =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ mNicknameMapUserCertsTable.put(nickname, certificates);
+
+ X509CertImpl impl = null;
+
+ try {
+ impl = new X509CertImpl(list[i].getEncoded());
+ } catch (CertificateException e) {
+ // skip bad certificate
+ CMS.debug("bad certificate - " + nickname);
+ continue;
+ }
+ Date date = impl.getNotAfter();
+ String dateStr = mFormatter.format(date);
+ NameValuePair pair = pairs.getPair(nickname);
+
+ /* always user cert here*/
+ String certValue = dateStr + "," + "u";
+
+ if (pair == null)
+ pairs.add(nickname, certValue);
+ else {
+ String vvalue = pair.getValue();
+
+ if (vvalue.endsWith(",u")) {
+ pair.setValue(vvalue + ";" + certValue);
+ }
+ }
+
+ }
+ } /* while */
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ALL_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ // } catch (CertificateException e) {
+ // log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ALL_CERT", e.toString()));
+ // throw new EBaseException(BaseResources.CERT_ERROR);
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_ALL_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+
+ return pairs;
+ }
+
+ public NameValuePairs getCACerts() throws EBaseException {
+ NameValuePairs pairs = new NameValuePairs();
+
+ //InternalCertificate[] certs;
+ X509Certificate[] certs;
+
+ try {
+ certs =
+ CryptoManager.getInstance().getCACerts();
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ }
+
+ if( mNicknameMapCertsTable == null ) {
+ CMS.debug( "JssSubsystem::getCACerts() - "
+ + "mNicknameMapCertsTable is null!" );
+ throw new EBaseException( "mNicknameMapCertsTable is null" );
+ } else {
+ mNicknameMapCertsTable.clear();
+ }
+
+ // a temp hashtable with vectors
+ Hashtable vecTable = new Hashtable();
+
+ for (int i = 0; i < certs.length; i++) {
+ String nickname = certs[i].getNickname();
+
+ /* build a table of our own */
+ Vector v;
+
+ if (vecTable.containsKey((Object) nickname) == true) {
+ v = (Vector) vecTable.get(nickname);
+ } else {
+ v = new Vector();
+ }
+ v.addElement(certs[i]);
+ vecTable.put(nickname, v);
+ }
+
+ // convert hashtable of vectors to hashtable of arrays
+ Enumeration elms = vecTable.keys();
+
+ while (elms.hasMoreElements()) {
+ String key = (String) elms.nextElement();
+ Vector v = (Vector) vecTable.get((Object) key);
+ X509Certificate[] a = new X509Certificate[v.size()];
+
+ v.copyInto((Object[]) a);
+ mNicknameMapCertsTable.put(key, a);
+ }
+
+ Enumeration keys = mNicknameMapCertsTable.keys();
+
+ while (keys.hasMoreElements()) {
+ String nickname = (String) keys.nextElement();
+ X509Certificate[] value = (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+
+ for (int i = 0; i < value.length; i++) {
+ InternalCertificate icert = null;
+
+ if (value[i] instanceof InternalCertificate)
+ icert = (InternalCertificate) value[i];
+ else {
+ Debug.trace("cert is not an InternalCertificate");
+ Debug.trace("nickname: " + nickname + " index " + i);
+ Debug.trace("cert: " + value[i]);
+ continue;
+ }
+
+ int flag = icert.getSSLTrust();
+ String trust = "U";
+
+ if ((InternalCertificate.TRUSTED_CLIENT_CA & flag) ==
+ InternalCertificate.TRUSTED_CLIENT_CA)
+ trust = "T";
+ X509CertImpl impl = null;
+
+ try {
+ impl = new X509CertImpl(icert.getEncoded());
+ Date date = impl.getNotAfter();
+ String dateStr = mFormatter.format(date);
+ NameValuePair pair = pairs.getPair(nickname);
+ String certValue = dateStr + "," + trust;
+
+ if (pair == null)
+ pairs.add(nickname, certValue);
+ else {
+ String vvalue = pair.getValue();
+
+ pair.setValue(vvalue + ";" + certValue);
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_CA_CERT_FOR", nickname, e.toString()));
+ // allow it to continue with other certs even if one blows
+ // up
+ // throw new EBaseException(BaseResources.CERT_ERROR);
+ }
+ }
+ }
+ return pairs;
+ }
+
+ public void trustCert(String nickname, String date, String trust) throws
+ EBaseException {
+ try {
+ if (mNicknameMapCertsTable != null) {
+ X509Certificate[] certs = (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+
+ if (certs == null) {
+ EBaseException e = new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TRUST_CERT", e.toString()));
+ throw e;
+ } else {
+ for (int i = 0; i < certs.length; i++) {
+ X509Certificate cert = certs[i];
+ X509CertImpl certImpl = new X509CertImpl(cert.getEncoded());
+ Date notAfter = certImpl.getNotAfter();
+ Date qualifier = mFormatter.parse(date);
+
+ if (notAfter.equals(qualifier)) {
+ if (cert instanceof InternalCertificate) {
+ if (trust.equals("Trust")) {
+ int trustflag = InternalCertificate.TRUSTED_CA |
+ InternalCertificate.TRUSTED_CLIENT_CA |
+ InternalCertificate.VALID_CA;
+
+ ((InternalCertificate) cert).setSSLTrust(trustflag);
+ } else
+ ((InternalCertificate) cert).setSSLTrust(InternalCertificate.VALID_CA);
+ break;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+ }
+ }
+ }
+ }
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TRUST_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_TRUST_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Delete the CA certificate from the perm database.
+ * @param nickname The nickname of the CA certificate.
+ * @param notAfterTime The notAfter of the certificate. It is possible to get multiple
+ * certificates under the same nickname. If one of the certificates match the notAfterTime,
+ * then the certificate will get deleted. The format of the notAfterTime has to be
+ * in "MMMMM dd, yyyy HH:mm:ss" format.
+ */
+ public void deleteCACert(String nickname, String notAfterTime) throws EBaseException {
+ try {
+ if (mNicknameMapCertsTable != null) {
+ X509Certificate[] certs = (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+
+ if (certs == null) {
+ EBaseException e = new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CA_CERT", e.toString()));
+ throw e;
+ } else {
+ for (int i = 0; i < certs.length; i++) {
+ X509Certificate cert = certs[i];
+ X509CertImpl certImpl = new X509CertImpl(cert.getEncoded());
+ Date notAfter = certImpl.getNotAfter();
+ Date qualifier = mFormatter.parse(notAfterTime);
+
+ if (notAfter.equals(qualifier)) {
+ if (cert instanceof TokenCertificate) {
+ TokenCertificate tcert = (TokenCertificate) cert;
+ CryptoStore store = tcert.getOwningToken().getCryptoStore();
+
+ tcert.getOwningToken().getCryptoStore().deleteCert(tcert);
+ } else {
+ CryptoToken token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+
+ store.deleteCert(cert);
+ }
+ mNicknameMapCertsTable.remove(nickname);
+ break;
+ }
+ }
+ }
+ }
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Delete any certificate from the any token.
+ * @param nickname The nickname of the certificate.
+ * @param notAfterTime The notAfter of the certificate. It is possible to get multiple
+ * certificates under the same nickname. If one of the certificates match the notAfterTime,
+ * then the certificate will get deleted. The format of the notAfterTime has to be
+ * in "MMMMM dd, yyyy HH:mm:ss" format.
+ */
+ public void deleteCert(String nickname, String notAfterTime) throws EBaseException {
+ boolean isUserCert = false;
+ X509Certificate[] certs = null;;
+
+ try {
+ if (mNicknameMapCertsTable != null) {
+ certs =
+ (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+ }
+
+ if (certs == null) {
+ if (mNicknameMapUserCertsTable != null) {
+ certs =
+ (X509Certificate[]) mNicknameMapUserCertsTable.get(nickname);
+ if (certs != null) {
+ CMS.debug("in mNicknameMapUserCertsTable, isUserCert is true");
+ isUserCert = true;
+ }
+
+ } else
+ CMS.debug("mNicknameMapUserCertsTable is null");
+ }
+
+ if (certs == null) {
+ EBaseException e = new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw e;
+ } else {
+
+ for (int i = 0; i < certs.length; i++) {
+ X509Certificate cert = certs[i];
+ X509CertImpl certImpl = new X509CertImpl(cert.getEncoded());
+ Date notAfter = certImpl.getNotAfter();
+ Date qualifier = mFormatter.parse(notAfterTime);
+
+ if (notAfter.equals(qualifier)) {
+ if (cert instanceof TokenCertificate) {
+ TokenCertificate tcert = (TokenCertificate) cert;
+ CryptoStore store = tcert.getOwningToken().getCryptoStore();
+
+ tcert.getOwningToken().getCryptoStore().deleteCert(tcert);
+ } else {
+ CryptoToken token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ CryptoStore store = token.getCryptoStore();
+
+ store.deleteCert(cert);
+ }
+ if (isUserCert == true) {
+ mNicknameMapUserCertsTable.remove(nickname);
+ } else {
+ mNicknameMapCertsTable.remove(nickname);
+ }
+ break;
+ }
+ }
+ }
+
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public void deleteTokenCertificate(String nickname, String pathname) throws EBaseException {
+ try {
+ X509Certificate cert = CryptoManager.getInstance().findCertByNickname(nickname);
+ String issuerName = cert.getSubjectDN().getName();
+ Principal principal = cert.getSubjectDN();
+ DN dn = new DN(principal.getName());
+ BigInteger serialno = cert.getSerialNumber();
+ String suffix = "." + System.currentTimeMillis();
+ String b64E = com.netscape.osutil.OSUtil.BtoA(cert.getEncoded());
+ PrintStream stream = new PrintStream(new FileOutputStream(pathname + suffix));
+
+ stream.println("-----BEGIN CERTIFICATE-----");
+ stream.print(b64E);
+ stream.println("-----END CERTIFICATE-----");
+ stream.close();
+ if (cert instanceof TokenCertificate) {
+ TokenCertificate tcert = (TokenCertificate) cert;
+ CryptoStore store = tcert.getOwningToken().getCryptoStore();
+
+ tcert.getOwningToken().getCryptoStore().deleteCert(tcert);
+ } else
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NOT_TOKEN_CERT"));
+
+ int index = nickname.indexOf(":");
+
+ // the deleted certificate is on the hardware token. We should delete the same one from
+ // the internal token.
+ if (index > 0) {
+ CryptoToken cToken = CryptoManager.getInstance().getInternalKeyStorageToken();
+ CryptoStore store = cToken.getCryptoStore();
+ X509Certificate[] allcerts = CryptoManager.getInstance().getCACerts();
+
+ for (int i = 0; i < allcerts.length; i++) {
+ try {
+ X509CertImpl certImpl = new X509CertImpl(allcerts[i].getEncoded());
+ String certIssuerName = certImpl.getSubjectDN().getName();
+ Principal certPrincipal = certImpl.getSubjectDN();
+ DN certdn = new DN(certPrincipal.getName());
+ BigInteger certSerialNo = certImpl.getSerialNumber();
+
+ if (dn.equals(certdn) && certSerialNo.compareTo(serialno) == 0) {
+ store.deleteCert(allcerts[i]);
+ break;
+ }
+ } catch (Exception ee) {
+ Debug.trace("JssSubsystem:deleteTokenCertificate: " + ee.toString());
+ }
+ }
+ }
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NoSuchItemOnTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ITEM_NOT_FOUND_ON_TOKEN"));
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_DELETE_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public String getSubjectDN(String nickname) throws EBaseException {
+ try {
+ X509Certificate cert =
+ CryptoManager.getInstance().findCertByNickname(nickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+
+ return impl.getSubjectDN().getName();
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_SUBJECT_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public void setRootCertTrust(String nickname, String serialno,
+ String issuerName, String trust) throws EBaseException {
+
+ X509Certificate cert = getCertificate(nickname, serialno, issuerName);
+ if (cert instanceof InternalCertificate) {
+ if (trust.equals("trust")) {
+ int trustflag = InternalCertificate.TRUSTED_CA |
+ InternalCertificate.TRUSTED_CLIENT_CA |
+ InternalCertificate.VALID_CA;
+
+ ((InternalCertificate) cert).setSSLTrust(trustflag);
+ } else {
+ ((InternalCertificate) cert).setSSLTrust(InternalCertificate.VALID_CA);
+ }
+ }
+ }
+
+ public X509Certificate getCertificate(String nickname, String serialno,
+ String issuerName) throws EBaseException {
+
+ int index = nickname.indexOf(":");
+ String tokenname = nickname.substring(0, index);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nickname.substring(index+1);
+ }
+ try {
+ X509Certificate[] certs =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ X509CertImpl impl = null;
+ int i=0;
+ if (certs != null && certs.length > 0) {
+ for (; i < certs.length; i++) {
+ impl = new X509CertImpl(certs[i].getEncoded());
+ if (impl.getIssuerDN().toString().equals(issuerName) &&
+ impl.getSerialNumber().toString().equals(serialno))
+ return certs[i];
+ }
+ } else {
+ EBaseException e =
+ new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw e;
+ }
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", "")); } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+
+ return null;
+ }
+
+ public String getRootCertTrustBit(String nickname, String serialno,
+ String issuerName) throws EBaseException {
+ int index = nickname.indexOf(":");
+ String tokenname = nickname.substring(0, index);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nickname.substring(index+1);
+ }
+ try {
+ X509Certificate[] certs =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ X509CertImpl impl = null;
+ int i=0;
+ if (certs != null && certs.length > 0) {
+ for (; i < certs.length; i++) {
+ impl = new X509CertImpl(certs[i].getEncoded());
+ if (impl.getIssuerDN().toString().equals(issuerName) &&
+ impl.getSerialNumber().toString().equals(serialno))
+ break;
+ }
+ } else {
+ EBaseException e =
+ new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw e;
+ }
+
+ String trust = "U";
+ if (certs[i] instanceof InternalCertificate) {
+ InternalCertificate icert = (InternalCertificate)certs[i];
+ int flag = icert.getSSLTrust();
+ if ((InternalCertificate.TRUSTED_CLIENT_CA & flag) ==
+ InternalCertificate.TRUSTED_CLIENT_CA)
+ trust = "T";
+ } else
+ trust = "N/A";
+ return trust;
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", "")); } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public String getCertPrettyPrint(String nickname, String serialno,
+ String issuerName, Locale locale) throws EBaseException {
+ int index = nickname.indexOf(":");
+ String tokenname = nickname.substring(0, index);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nickname.substring(index+1);
+ }
+ try {
+ X509Certificate[] certs =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ X509CertImpl impl = null;
+ if (certs != null && certs.length > 0) {
+ for (int i = 0; i < certs.length; i++) {
+ impl = new X509CertImpl(certs[i].getEncoded());
+ if (impl.getIssuerDN().toString().equals(issuerName) &&
+ impl.getSerialNumber().toString().equals(serialno))
+ break;
+ }
+ } else {
+ EBaseException e =
+ new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw e;
+ }
+ CertPrettyPrint print = null;
+
+ if (impl != null)
+ print = new CertPrettyPrint(impl);
+
+ if (print != null)
+ return print.toString(locale);
+ else
+ return null;
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public String getCertPrettyPrintAndFingerPrint(String nickname, String serialno,
+ String issuerName, Locale locale) throws EBaseException {
+ int index = nickname.indexOf(":");
+ String tokenname = nickname.substring(0, index);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ nickname = nickname.substring(index+1);
+ }
+ try {
+ X509Certificate[] certs =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ X509CertImpl impl = null;
+ if (certs != null && certs.length > 0) {
+ for (int i = 0; i < certs.length; i++) {
+ impl = new X509CertImpl(certs[i].getEncoded());
+ if (impl.getIssuerDN().toString().equals(issuerName) &&
+ impl.getSerialNumber().toString().equals(serialno))
+ break;
+ }
+ } else {
+ EBaseException e =
+ new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw e;
+ }
+ CertPrettyPrint print = null;
+ String fingerPrint = "";
+
+ if (impl != null) {
+ print = new CertPrettyPrint(impl);
+ fingerPrint = CMS.getFingerPrints(impl.getEncoded());
+ }
+
+ if ((print != null) && (fingerPrint != "")) {
+ String pp = print.toString(locale) + "\n" +
+ "Certificate Fingerprints:"+ '\n' + fingerPrint;
+ return pp;
+ } else
+ return null;
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_NO_SUCH_ALGORITHM", e.toString()));
+ }
+ }
+
+ public String getCertPrettyPrint(String nickname, String date,
+ Locale locale) throws EBaseException {
+ try {
+ X509Certificate[] certs =
+ CryptoManager.getInstance().findCertsByNickname(nickname);
+
+ if ((certs == null || certs.length == 0) &&
+ mNicknameMapCertsTable != null) {
+ certs = (X509Certificate[]) mNicknameMapCertsTable.get(nickname);
+ }
+ if (certs == null) {
+ EBaseException e = new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw e;
+ }
+ X509CertImpl impl = null;
+ Date qualifier = mFormatter.parse(date);
+
+ for (int i = 0; i < certs.length; i++) {
+ impl = new X509CertImpl(certs[i].getEncoded());
+ Date d = impl.getNotAfter();
+
+ if (d.equals(qualifier))
+ break;
+ }
+
+ CertPrettyPrint print = null;
+
+ if (impl != null)
+ print = new CertPrettyPrint(impl);
+
+ if (print != null)
+ return print.toString(locale);
+ else
+ return null;
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public String getCertPrettyPrint(String b64E, Locale locale) throws EBaseException {
+ try {
+ try {
+ byte[] b = KeyCertUtil.convertB64EToByteArray(b64E);
+ X509CertImpl impl = new X509CertImpl(b);
+ CertPrettyPrint print = new CertPrettyPrint(impl);
+
+ return print.toString(locale);
+ } catch (CertificateException e) {
+ // failed to decode as a certificate, try decoding
+ // as a PKCS #7 blob
+ String content = "";
+ String noHeader = CertUtils.stripCertBrackets(b64E);
+ String normalized = CertUtils.normalizeCertStr(noHeader);
+ byte data[] = com.netscape.osutil.OSUtil.AtoB(normalized);
+
+ ContentInfo ci = (ContentInfo)
+ ASN1Util.decode(ContentInfo.getTemplate(), data);
+
+ if (!ci.getContentType().equals(ContentInfo.SIGNED_DATA)) {
+ throw new CertificateException(
+ "PKCS #7 structure is not a SignedData");
+ }
+ SignedData sd = (SignedData) ci.getInterpretedContent();
+
+ if (!sd.hasCertificates()) {
+ throw new CertificateException(
+ "No certificates in PKCS #7 structure");
+ }
+ SET certs = sd.getCertificates();
+
+ for (int i = 0; i < certs.size(); i++) {
+ Certificate cert = (Certificate) certs.elementAt(i);
+ X509CertImpl certImpl = new X509CertImpl(
+ ASN1Util.encode(cert));
+ CertPrettyPrint print = new CertPrettyPrint(certImpl);
+
+ content += print.toString(Locale.getDefault());
+ }
+
+ return content;
+ }
+ } catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR",
+ "Failed to decode"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.getMessage()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PRINT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+ }
+
+ public X509CertImpl getSignedCert(KeyCertData data, String certType, java.security.PrivateKey priKey)
+ throws EBaseException {
+ CertificateInfo cert = null;
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ cert = new CASigningCert(data);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ cert = new OCSPSigningCert(data);
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ cert = new SSLCert(data);
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ cert = new SSLSelfSignedCert(data);
+ }
+
+ if (cert == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+
+ X509CertInfo certInfo = null;
+ X509CertImpl signedCert = null;
+
+ try {
+ certInfo = cert.getCertInfo();
+ SignatureAlgorithm sigAlg =
+ (SignatureAlgorithm) data.get(Constants.PR_SIGNATURE_ALGORITHM);
+
+ signedCert = KeyCertUtil.signCert(priKey, certInfo, sigAlg);
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SIGN_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", ""));
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SIGN_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (PQGParamGenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_SIGN_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ }
+
+ return signedCert;
+ }
+
+ public boolean isCACert(String fullNickname) throws EBaseException {
+ try {
+ X509Certificate cert = mCryptoManager.findCertByNickname(fullNickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+ X509CertInfo certinfo = (X509CertInfo) impl.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ if (certinfo == null)
+ return false;
+ else {
+ CertificateExtensions exts =
+ (CertificateExtensions) certinfo.get(X509CertInfo.EXTENSIONS);
+
+ if (exts == null)
+ return false;
+ else {
+ try {
+ BasicConstraintsExtension ext = (BasicConstraintsExtension)
+ exts.get(BasicConstraintsExtension.NAME);
+
+ if (ext == null)
+ return false;
+ else {
+ Boolean bool = (Boolean) ext.get(BasicConstraintsExtension.IS_CA);
+
+ return bool.booleanValue();
+ }
+ } catch (IOException ee) {
+ return false;
+ }
+ }
+ }
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IS_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IS_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR"));
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IS_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IS_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IS_CA_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DECODE_CERT_FAILED"));
+ }
+ }
+
+ public CertificateExtensions getExtensions(String tokenname, String nickname)
+ throws EBaseException {
+ try {
+ return KeyCertUtil.getExtensions(tokenname, nickname);
+ } catch (NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_EXTENSIONS", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_EXTENSIONS", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR"));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_EXTENSIONS", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_EXTENSIONS", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_DECODE_CERT_FAILED"));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_EXTENSIONS", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ""));
+ }
+ }
+
+ public void checkCertificateExt(String ext) throws EBaseException {
+ KeyCertUtil.checkCertificateExt(ext);
+ }
+
+ public void checkKeyLength(String keyType, int keyLength, String certType, int minRSAKeyLen) throws EBaseException {
+ // KeyCertUtil.checkKeyLength(keyType, keyLength, certType, minRSAKeyLen);
+ }
+
+ public PQGParams getPQG(int keysize) {
+ return KeyCertUtil.getPQG(keysize);
+ }
+
+ public PQGParams getCAPQG(int keysize, IConfigStore store)
+ throws EBaseException {
+ return KeyCertUtil.getCAPQG(keysize, store);
+ }
+
+ public CertificateExtensions getCertExtensions(String tokenname, String nickname)
+ throws NotInitializedException, TokenException, ObjectNotFoundException,
+
+ IOException, CertificateException {
+ return KeyCertUtil.getExtensions(tokenname, nickname);
+ }
+}
+
+class JSSDatabaseCloser extends org.mozilla.jss.DatabaseCloser
+{
+ public JSSDatabaseCloser() throws Exception {
+ super();
+ }
+
+ public void closeDatabases() {
+ super.closeDatabases();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/security/KRATransportCert.java b/pki/base/common/src/com/netscape/cmscore/security/KRATransportCert.java
new file mode 100644
index 000000000..35b7cdf2b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/KRATransportCert.java
@@ -0,0 +1,110 @@
+// --- 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.cmscore.security;
+
+
+import java.io.IOException;
+import java.security.KeyPair;
+
+import netscape.security.x509.KeyUsageExtension;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.ConfigConstants;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.security.KeyCertData;
+
+
+/**
+ * KRA transport certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class KRATransportCert extends CertificateInfo {
+ public static final String SUBJECT_NAME =
+ "CN=Data Recovery Manager, O=Netscape Communications, C=US";
+ private String mTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ public KRATransportCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public KRATransportCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ String tmp = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+
+ if ((tmp != null) &&
+ (!tmp.equals(Constants.PR_INTERNAL_TOKEN)))
+ mTokenname = tmp;
+ mProperties.put(Constants.PR_AKI, Constants.TRUE);
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ cmsFileTmp.putString("kra.transportUnit.nickName", nickname);
+ else
+ cmsFileTmp.putString("kra.transportUnit.nickName", tokenname + ":" + nickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName =
+ (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "kraTransportCert " + instanceName;
+ }
+
+ /*
+ public SignatureAlgorithm getSigningAlgorithm() {
+ SignatureAlgorithm sAlg =
+ (SignatureAlgorithm)mProperties.get(Constants.PR_SIGNATURE_ALGORITHM);
+ if (sAlg != null) {
+ return sAlg;
+ }
+ String alg = (String)mProperties.get(Constants.PR_KEY_TYPE);
+
+ if (alg.equals("RSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+ */
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.KEY_ENCIPHERMENT, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java b/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
new file mode 100644
index 000000000..4f551cd26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
@@ -0,0 +1,1088 @@
+// --- 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.cmscore.security;
+
+
+import org.mozilla.jss.asn1.*;
+
+import java.security.PrivateKey;
+import java.security.*;
+import java.util.*;
+import java.security.interfaces.*;
+import java.io.IOException;
+import java.io.*;
+import java.security.cert.CertificateException;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.*;
+import java.math.*;
+//import java.security.cert.*;
+import org.mozilla.jss.crypto.X509Certificate;
+//import netscape.security.provider.DSAPublicKey;
+// ADDED next line by MLH on 1/9/99
+// REMOVED the line added by MLH on 1/10/99
+//import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.pkcs11.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import java.security.cert.CertificateEncodingException;
+import netscape.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmsutil.crypto.*;
+
+
+/**
+ * This class provides all the base methods to generate the key for different
+ * kinds of certificates.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class KeyCertUtil {
+
+ public static final String CA_SIGNINGCERT_NICKNAME = "caSigningCert";
+ private static final int MAX_DOMESTIC_SSL_KEY_LEN = 4096;
+ private static final int MAX_EXPORT_SSL_KEY_LEN = 512;
+ private static final int MIN_DSA_KEY_LEN = 512;
+ private static final int MAX_DSA_KEY_LEN = 1024;
+
+ public static void checkCertificateExt(String ext) throws EBaseException {
+ byte[] b = null;
+
+ if (ext != null) {
+ try {
+
+ b = (byte[]) (com.netscape.osutil.OSUtil.AtoB(ext));
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ Extension de = new Extension(b_der.data.getDerValue());
+ }
+ } catch (IOException e) {
+ try {
+ Extension de = new Extension(new DerValue(b));
+ } catch (IOException ex) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT_EXTENSION"));
+ }
+ }
+ }
+ }
+
+ public static String getTokenNames(CryptoManager manager)
+ throws TokenException {
+ String tokenList = "";
+ Enumeration tokens = manager.getExternalTokens();
+ int num = 0;
+
+ while (tokens.hasMoreElements()) {
+ CryptoToken c = (CryptoToken) tokens.nextElement();
+
+ if (num++ == 0)
+ tokenList = tokenList + c.getName();
+ else
+ tokenList = tokenList + "," + c.getName();
+ }
+
+ if (tokenList.equals(""))
+ return Constants.PR_INTERNAL_TOKEN;
+ else
+ return (tokenList + "," + Constants.PR_INTERNAL_TOKEN);
+ }
+
+ public static String base64Encode(byte[] bytes) throws IOException {
+ // All this streaming is lame, but Base64OutputStream needs a
+ // PrintStream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(new
+ PrintStream(new
+ FilterOutputStream(output)
+ )
+ );
+
+ b64.write(bytes);
+ b64.flush();
+
+ // This is internationally safe because Base64 chars are
+ // contained within 8859_1
+ return output.toString("8859_1");
+ }
+
+ public static byte[] makeDSSParms(BigInteger P, BigInteger Q, BigInteger G)
+ throws IOException {
+
+ // Write P, Q, G to a DER stream
+ DerOutputStream contents = new DerOutputStream();
+
+ contents.putInteger(new BigInt(P));
+ contents.putInteger(new BigInt(Q));
+ contents.putInteger(new BigInt(G));
+
+ // Make a sequence from the PQG stream
+ DerOutputStream sequence = new DerOutputStream();
+
+ sequence.write(DerValue.tag_Sequence, contents);
+
+ return sequence.toByteArray();
+ }
+
+ public static PrivateKey getPrivateKey(String tokenname, String nickname)
+ throws TokenException, EBaseException,
+ NoSuchTokenException, NotInitializedException, CertificateException,
+ CertificateEncodingException, EBaseException, ObjectNotFoundException {
+
+ /*
+ String caNickname = store.getString("ca.signing.tokenname");
+ String tokenName = store.getString("ca.signing.cacertnickname");
+ */
+ X509Certificate cert = getCertificate(tokenname, nickname);
+
+ return CryptoManager.getInstance().findPrivKeyByCert(cert);
+ }
+
+ public static String getCertSubjectName(String tokenname, String nickname)
+ throws TokenException, EBaseException, NoSuchTokenException,
+ NotInitializedException, CertificateException,
+ CertificateEncodingException, EBaseException {
+
+ X509Certificate cert = getCertificate(tokenname, nickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+
+ return impl.getSubjectDN().getName();
+ }
+
+ public static X509CertImpl signCert(PrivateKey privateKey, X509CertInfo certInfo,
+ SignatureAlgorithm sigAlg)
+ throws NoSuchTokenException, EBaseException, NotInitializedException {
+ try {
+ CertificateAlgorithmId sId = (CertificateAlgorithmId)
+ certInfo.get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId sigAlgId =
+ (AlgorithmId) sId.get(CertificateAlgorithmId.ALGORITHM);
+
+ org.mozilla.jss.crypto.PrivateKey priKey =
+ (org.mozilla.jss.crypto.PrivateKey) privateKey;
+ CryptoToken token = priKey.getOwningToken();
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream out = new DerOutputStream();
+
+ certInfo.encode(tmp);
+
+ Signature signer = token.getSignatureContext(sigAlg);
+
+ signer.initSign(priKey);
+ signer.update(tmp.toByteArray());
+ byte signed[] = signer.sign();
+
+ sigAlgId.encode(tmp);
+ tmp.putBitString(signed);
+
+ out.write(DerValue.tag_Sequence, tmp);
+
+ X509CertImpl signedCert = new X509CertImpl(out.toByteArray());
+
+ return signedCert;
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_SIGNED_FAILED", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", e.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
+ } catch (SignatureException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_SIGNED_FAILED", e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1", e.toString()));
+ } catch (CertificateException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public static SignatureAlgorithm getSigningAlgorithm(String keyType) {
+ SignatureAlgorithm sAlg = null;
+
+ if (keyType.equals("RSA"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ sAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+
+ return sAlg;
+ }
+
+ public static SignatureAlgorithm getSigningAlgorithm(String keyType, String hashtype) {
+ SignatureAlgorithm sAlg = null;
+
+ if (keyType.equals("RSA")) {
+ if (hashtype.equals("MD2"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD2Digest;
+ else if (hashtype.equals("MD5"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else if (hashtype.equals("SHA1"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ else if (hashtype.equals("SHA256"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ else if (hashtype.equals("SHA512"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA512Digest;
+ } else {
+ sAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+
+ return sAlg;
+ }
+
+ public static AlgorithmId getAlgorithmId(String algname, IConfigStore store)
+ throws EBaseException {
+ try {
+
+ if (algname.equals("DSA")) {
+ byte[] p = store.getByteArray("ca.dsaP", null);
+ byte[] q = store.getByteArray("ca.dsaQ", null);
+ byte[] g = store.getByteArray("ca.dsaG", null);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+
+ return new AlgIdDSA(P, Q, G);
+ }
+ }
+ return AlgorithmId.getAlgorithmId(algname);
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED"));
+ }
+ }
+
+ public static X509Certificate getCertificate(String tokenname,
+ String nickname) throws NotInitializedException, NoSuchTokenException,
+ EBaseException, TokenException {
+ CryptoManager manager = CryptoManager.getInstance();
+ CryptoToken token = null;
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ token = manager.getInternalKeyStorageToken();
+ } else {
+ token = manager.getTokenByName(tokenname);
+ }
+ StringBuffer certname = new StringBuffer();
+
+ if (!token.equals(manager.getInternalKeyStorageToken())) {
+ certname.append(tokenname);
+ certname.append(":");
+ }
+ certname.append(nickname);
+ try {
+ return manager.findCertByNickname(certname.toString());
+ } catch (ObjectNotFoundException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CA_SIGNINGCERT_NOT_FOUND"));
+ }
+ }
+
+ public static KeyPair getKeyPair(String tokenname, String nickname)
+ throws NotInitializedException, NoSuchTokenException, TokenException,
+ ObjectNotFoundException, EBaseException {
+ X509Certificate cert = getCertificate(tokenname, nickname);
+ PrivateKey priKey =
+ CryptoManager.getInstance().findPrivKeyByCert(cert);
+ PublicKey publicKey = cert.getPublicKey();
+
+ return new KeyPair(publicKey, priKey);
+ }
+
+ public static PQGParams getPQG(int keysize) {
+ try {
+ return PQGParams.generate(keysize);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static PQGParams getCAPQG(int keysize, IConfigStore store)
+ throws EBaseException {
+ if (store != null) {
+ try {
+ int pqgKeySize = store.getInteger("ca.dsaPQG.keyLength", 0);
+
+ if ((pqgKeySize > 0) && (pqgKeySize == keysize)) {
+ byte[] p = store.getByteArray("ca.dsaP", null);
+ byte[] q = store.getByteArray("ca.dsaQ", null);
+ byte[] g = store.getByteArray("ca.dsaG", null);
+ byte[] seed = store.getByteArray("ca.dsaSeed", null);
+ byte[] H = store.getByteArray("ca.dsaH", null);
+ int counter = store.getInteger("ca.dsaCounter", 0);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+ BigInteger pqgSeed = new BigInteger(seed);
+ BigInteger pqgH = new BigInteger(H);
+
+ return new PQGParams(P, Q, G, pqgSeed, counter, pqgH);
+ }
+ }
+ PQGParams pqg = PQGParams.generate(keysize);
+
+ store.putInteger("ca.dsaPQG.keyLength", keysize);
+ store.putString("ca.dsaP", KeyCertUtil.base64Encode(
+ pqg.getP().toByteArray()));
+ store.putString("ca.dsaQ", KeyCertUtil.base64Encode(
+ pqg.getQ().toByteArray()));
+ store.putString("ca.dsaG", KeyCertUtil.base64Encode(
+ pqg.getG().toByteArray()));
+ store.putString("ca.dsaSeed", KeyCertUtil.base64Encode(
+ pqg.getSeed().toByteArray()));
+ store.putInteger("ca.dsaCounter", pqg.getCounter());
+ store.putString("ca.dsaH", KeyCertUtil.base64Encode(
+ pqg.getH().toByteArray()));
+ store.putString("ca.DSSParms",
+ KeyCertUtil.base64Encode(
+ KeyCertUtil.makeDSSParms(pqg.getP(), pqg.getQ(), pqg.getG())));
+ store.commit(false);
+ return pqg;
+ } catch (IOException ee) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ } catch (EBaseException ee) {
+ throw ee;
+ } catch (PQGParamGenException ee) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ }
+ }
+ return null;
+ }
+
+ public static KeyPair generateKeyPair(CryptoToken token,
+ KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
+ throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
+ InvalidParameterException, PQGParamGenException {
+
+ KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
+
+ if (kpAlg == KeyPairAlgorithm.DSA) {
+ if (pqg == null) {
+ kpGen.initialize(keySize);
+ } else {
+ kpGen.initialize(pqg);
+ }
+ } else {
+ kpGen.initialize(keySize);
+ }
+
+ if (pqg == null) {
+ return kpGen.genKeyPair();
+ } else {
+ // DSA
+ KeyPair kp = null;
+
+ do {
+ // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
+ kp = kpGen.genKeyPair();
+ }
+ while (isBadDSAKeyPair(kp));
+ return kp;
+ }
+ }
+
+ /**
+ * Test for a DSA key pair that will trigger a bug in NSS.
+ * The problem occurs when the first byte of the key is 0. This
+ * happens when the value otherwise would have been negative, and a
+ * zero byte is prepended to force it to be positive.
+ * This is blackflag bug 602548.
+ */
+ public static boolean isBadDSAKeyPair(KeyPair pair) {
+ try {
+ byte[] pubkBytes = pair.getPublic().getEncoded();
+ SEQUENCE.Template outerSeq = new SEQUENCE.Template();
+
+ outerSeq.addElement(new ANY.Template()); // algid
+ outerSeq.addElement(new BIT_STRING.Template()); // key value
+ SEQUENCE seq = (SEQUENCE) ASN1Util.decode(outerSeq, pubkBytes);
+
+ BIT_STRING bs = (BIT_STRING) seq.elementAt(1);
+ byte[] bits = bs.getBits();
+ ByteArrayInputStream bitstream = new ByteArrayInputStream(bs.getBits());
+ ASN1Header wrapper = new ASN1Header(bitstream);
+ byte[] valBytes = new byte[ (int) wrapper.getContentLength() ];
+
+ ASN1Util.readFully(valBytes, bitstream);
+
+ boolean isBroken = (valBytes[0] == 0);
+
+ return isBroken;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public static KeyPair generateKeyPair(String tokenName, String alg,
+ int keySize, PQGParams pqg) throws EBaseException {
+
+ CryptoToken token = null;
+
+ if (tokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN))
+ tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ try {
+ if (tokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN)) {
+ token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ } else {
+ token = CryptoManager.getInstance().getTokenByName(tokenName);
+ }
+ } catch (NoSuchTokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", tokenName));
+ } catch (NotInitializedException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ }
+
+ KeyPairAlgorithm kpAlg = null;
+
+ if (alg.equals("RSA"))
+ kpAlg = KeyPairAlgorithm.RSA;
+ else
+ kpAlg = KeyPairAlgorithm.DSA;
+
+ try {
+ KeyPair kp = generateKeyPair(token, kpAlg, keySize, pqg);
+
+ return kp;
+ } catch (InvalidParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEYSIZE_PARAMS",
+ "" + keySize));
+ } catch (PQGParamGenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED",
+ kpAlg.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", "DSA"));
+ }
+ }
+
+ public static PKCS10 getCertRequest(String subjectName, KeyPair keyPair)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+ String alg;
+
+ if (pubk instanceof RSAPublicKey) {
+ alg = "MD5/RSA";
+ } else if (pubk instanceof PK11ECPublicKey) {
+ alg = "SHA256withEC";
+ } else {
+ alg = "DSA";
+ }
+ java.security.Signature sig =
+ java.security.Signature.getInstance(alg, "Mozilla-JSS");
+
+ sig.initSign(keyPair.getPrivate());
+
+ PKCS10 pkcs10 = new PKCS10(key);
+
+ X500Name name = new X500Name(subjectName);
+ X500Signer signer = new X500Signer(sig, name);
+
+ pkcs10.encodeAndSign(signer);
+
+ return pkcs10;
+ }
+
+ public static PKCS10 getCertRequest(String subjectName, KeyPair
+ keyPair, Extensions
+ exts)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+ String alg;
+
+ if (pubk instanceof RSAPublicKey) {
+ alg = "MD5/RSA";
+ } else if (pubk instanceof PK11ECPublicKey) {
+ alg = "SHA256withEC";
+ } else {
+ alg = "DSA";
+ }
+ java.security.Signature sig =
+ java.security.Signature.getInstance(alg, "Mozilla-JSS");
+
+ sig.initSign(keyPair.getPrivate());
+
+ PKCS10 pkcs10 = null;
+
+ if (exts != null) {
+ PKCS10Attribute attr = new
+ PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID,
+ (CertAttrSet) exts);
+ PKCS10Attributes attrs = new PKCS10Attributes();
+
+ attrs.setAttribute(attr.getAttributeValue().getName(), attr);
+
+ pkcs10 = new PKCS10(key, attrs);
+ } else {
+ pkcs10 = new PKCS10(key);
+ }
+
+ X500Name name = new X500Name(subjectName);
+ X500Signer signer = new X500Signer(sig, name);
+
+ pkcs10.encodeAndSign(signer);
+
+ return pkcs10;
+ }
+
+ public static X509Key convertPublicKeyToX509Key(PublicKey pubk)
+ throws InvalidKeyException {
+
+ X509Key xKey;
+
+ if (pubk instanceof RSAPublicKey) {
+ RSAPublicKey rsaKey = (RSAPublicKey) pubk;
+
+ // REMOVED constructors from parameters by MLH on 1/9/99
+ xKey = new netscape.security.provider.RSAPublicKey(
+ new BigInt(rsaKey.getModulus()),
+ new BigInt(rsaKey.getPublicExponent()));
+ } else if (pubk instanceof PK11ECPublicKey) {
+ byte encoded[] = pubk.getEncoded();
+ xKey = CryptoUtil.getPublicX509ECCKey(encoded);
+
+ } else {
+ DSAPublicKey dsaKey = (DSAPublicKey) pubk;
+ DSAParams params = dsaKey.getParams();
+
+ xKey = new netscape.security.provider.DSAPublicKey(
+ dsaKey.getY(),
+ params.getP(),
+ params.getQ(),
+ params.getG());
+ }
+ return xKey;
+ }
+
+ public static X509Certificate
+ importCert(X509CertImpl signedCert, String nickname,
+ String certType) throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ return importCert(signedCert.getEncoded(), nickname, certType);
+ }
+
+ public static X509Certificate
+ importCert(String b64E, String nickname, String certType)
+ throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ byte b[] = b64E.getBytes();
+ X509Certificate cert = getInternalCertificate(b, nickname, certType);
+
+ if (cert instanceof InternalCertificate) {
+ setTrust(certType, (InternalCertificate) cert);
+ }
+ return cert;
+ }
+
+ public static X509Certificate
+ importCert(byte[] b, String nickname, String certType)
+ throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ X509Certificate cert = getInternalCertificate(b, nickname, certType);
+
+ if (cert instanceof InternalCertificate) {
+ setTrust(certType, (InternalCertificate) cert);
+ }
+ return cert;
+ }
+
+ public static X509Certificate getInternalCertificate(byte[] b, String nickname, String certType)
+ throws NotInitializedException, TokenException, CertificateEncodingException,
+ UserCertConflictException, NicknameConflictException, NoSuchItemOnTokenException,
+ CertificateException {
+ X509Certificate cert = null;
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ cert = CryptoManager.getInstance().importUserCACertPackage(b,
+ nickname);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_KRA_TRANSPORT_CERT) ||
+ certType.equals(Constants.PR_OCSP_SIGNING_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM) ||
+ certType.equals(Constants.PR_OTHER_CERT) ||
+ certType.equals(Constants.PR_SUBSYSTEM_CERT)) {
+ cert = CryptoManager.getInstance().importCertPackage(b,
+ nickname);
+ } else if (certType.equals(Constants.PR_SERVER_CERT_CHAIN)) {
+ cert = CryptoManager.getInstance().importCACertPackage(b);
+ } else if (certType.equals(Constants.PR_TRUSTED_CA_CERT)) {
+ cert = CryptoManager.getInstance().importCACertPackage(b);
+ X509Certificate[] certchain = CryptoManager.getInstance().buildCertificateChain(cert);
+
+ if (certchain != null) {
+ cert = certchain[certchain.length - 1];
+ }
+ }
+ return cert;
+ }
+
+ public static void setTrust(String certType, InternalCertificate inCert) {
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ int flag = InternalCertificate.VALID_CA |
+ InternalCertificate.TRUSTED_CA |
+ InternalCertificate.USER |
+ InternalCertificate.TRUSTED_CLIENT_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SUBSYSTEM_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_TRUSTED_CA_CERT)) {
+ inCert.setSSLTrust(InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA |
+ InternalCertificate.VALID_CA);
+ //inCert.setEmailTrust(InternalCertificate.TRUSTED_CA);
+
+ // cannot set this bit. If set, then the cert will not appear when you called getCACerts().
+ //inCert.setObjectSigningTrust(InternalCertificate.TRUSTED_CA);
+ }
+ }
+
+ public static byte[] convertB64EToByteArray(String b64E)
+ throws CertificateException, IOException {
+ String str = CertUtils.stripCertBrackets(b64E);
+ byte bCert[] = (byte[]) (com.netscape.osutil.OSUtil.AtoB(str));
+
+ /*
+ java.security.cert.X509Certificate cert =
+ java.security.cert.X509Certificate.getInstance(bCert);
+ return cert;
+ */
+ return bCert;
+ }
+
+ /**
+ * ASN.1 structure:
+ * 0 30 142: SEQUENCE {
+ * 3 30 69: SEQUENCE {
+ * 5 06 3: OBJECT IDENTIFIER issuerAltName (2 5 29 18)
+ * 10 04 62: OCTET STRING
+ * : 30 3C 82 01 61 82 01 61 A4 10 30 0E 31 0C 30 0A
+ * : 06 03 55 04 03 13 03 64 73 61 87 04 01 01 01 01
+ * : 86 01 61 81 14 74 68 6F 6D 61 73 6B 40 6E 65 74
+ * : 73 63 61 70 65 2E 63 6F 6D 88 03 29 01 01
+ * : }
+ * 74 30 69: SEQUENCE {
+ * 76 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17)
+ * 81 04 62: OCTET STRING
+ * : 30 3C 82 01 61 82 01 61 A4 10 30 0E 31 0C 30 0A
+ * : 06 03 55 04 03 13 03 64 73 61 87 04 01 01 01 01
+ * : 86 01 61 81 14 74 68 6F 6D 61 73 6B 40 6E 65 74
+ * : 73 63 61 70 65 2E 63 6F 6D 88 03 29 01 01
+ * : }
+ * : }
+ * Uses the following to test with configuration wizard:
+ * MIGOMEUGA1UdEQQ+MDyCAWGCAWGkEDAOMQwwCgYDVQQDEwNkc2GHBAEBAQGGAWGB
+ * FHRob21hc2tAbmV0c2NhcGUuY29tiAMpAQEwRQYDVR0SBD4wPIIBYYIBYaQQMA4x
+ * DDAKBgNVBAMTA2RzYYcEAQEBAYYBYYEUdGhvbWFza0BuZXRzY2FwZS5jb22IAykB
+ * AQ==
+ */
+ public static void setDERExtension(
+ CertificateExtensions ext, KeyCertData properties)
+ throws IOException {
+
+ String b64E = properties.getDerExtension();
+
+ if (b64E != null) {
+ byte[] b = (byte[]) (com.netscape.osutil.OSUtil.AtoB(b64E));
+
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ try {
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ Extension de = new Extension(b_der.data.getDerValue());
+
+ ext.set(de.getExtensionId().toString(), de);
+ }
+ } catch (IOException e) {
+ Extension de = new Extension(new DerValue(b));
+
+ ext.set(de.getExtensionId().toString(), de);
+ }
+ }
+ }
+
+ public static void setBasicConstraintsExtension(
+ CertificateExtensions ext, KeyCertData properties)
+ throws IOException {
+ String isCA = properties.isCA();
+ String certLen = properties.getCertLen();
+
+ if (isCA == null)
+ return; // isCA is not optional
+ if (isCA.equals("null"))
+ return; // no BasicConstraints requested
+ if ((isCA == null) && (certLen == null))
+ return;
+ int len = 0;
+ boolean bool = false;
+
+ if ((certLen == null) || (certLen.equals("")))
+ len = 0;
+ else
+ len = Integer.parseInt(certLen);
+
+ if ((isCA == null) || (isCA.equals("")) ||
+ (isCA.equals(Constants.FALSE)))
+ bool = false;
+ else
+ bool = true;
+
+ BasicConstraintsExtension basic = new BasicConstraintsExtension(
+ bool, len);
+
+ ext.set(BasicConstraintsExtension.NAME, basic);
+ }
+
+ public static void setExtendedKeyUsageExtension(
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ CertificateException {
+ ExtendedKeyUsageExtension ns = new ExtendedKeyUsageExtension();
+ boolean anyExt = false;
+
+ String sslClient = properties.getSSLClientBit();
+
+ if ((sslClient != null) && (sslClient.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.2"));
+ anyExt = true;
+ }
+
+ String sslServer = properties.getSSLServerBit();
+
+ if ((sslServer != null) && (sslServer.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.1"));
+ anyExt = true;
+ }
+
+ String sslMail = properties.getSSLMailBit();
+
+ if ((sslMail != null) && (sslMail.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.4"));
+ anyExt = true;
+ }
+
+ String objectSigning = properties.getObjectSigningBit();
+
+ if ((objectSigning != null) && (objectSigning.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.3"));
+ anyExt = true;
+ }
+
+ String timestamping = properties.getTimeStampingBit();
+ if ((timestamping != null) && (timestamping.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.8"));
+ anyExt = true;
+ }
+
+ String ocspSigning = properties.getOCSPSigning();
+
+ if ((ocspSigning != null) && (ocspSigning.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.9"));
+ anyExt = true;
+ }
+
+ if (anyExt)
+ ext.set(ExtendedKeyUsageExtension.NAME, ns);
+ }
+
+ public static void setNetscapeCertificateExtension(
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ CertificateException {
+
+ NSCertTypeExtension ns = new NSCertTypeExtension();
+ boolean anyExt = false;
+
+ String sslClient = properties.getSSLClientBit();
+
+ if ((sslClient != null) && (sslClient.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_CLIENT, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslServer = properties.getSSLServerBit();
+
+ if ((sslServer != null) && (sslServer.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_SERVER, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslMail = properties.getSSLMailBit();
+
+ if ((sslMail != null) && (sslMail.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.EMAIL, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslCA = properties.getSSLCABit();
+
+ if ((sslCA != null) && (sslCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_CA, new Boolean(true));
+ anyExt = true;
+ }
+
+ String objectSigning = properties.getObjectSigningBit();
+
+ if ((objectSigning != null) && (objectSigning.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.OBJECT_SIGNING, new Boolean(true));
+ anyExt = true;
+ }
+
+ String mailCA = properties.getMailCABit();
+
+ if ((mailCA != null) && (mailCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.EMAIL_CA, new Boolean(true));
+ anyExt = true;
+ }
+
+ String objectSigningCA = properties.getObjectSigningCABit();
+
+ if ((objectSigningCA != null) && (objectSigningCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.OBJECT_SIGNING_CA, new Boolean(true));
+ anyExt = true;
+ }
+ if (anyExt)
+ ext.set(NSCertTypeExtension.NAME, ns);
+ }
+
+ public static void setOCSPNoCheck(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String noCheck = properties.getOCSPNoCheck();
+
+ if ((noCheck != null) && (noCheck.equals(Constants.TRUE))) {
+ OCSPNoCheckExtension noCheckExt =
+ new OCSPNoCheckExtension();
+
+ ext.set(OCSPNoCheckExtension.NAME, noCheckExt);
+ }
+ }
+
+ public static void setOCSPSigning(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String signing = properties.getOCSPSigning();
+
+ if ((signing != null) && (signing.equals(Constants.TRUE))) {
+ Vector oidSet = new Vector();
+ oidSet.addElement(
+ ObjectIdentifier.getObjectIdentifier(
+ ExtendedKeyUsageExtension.OID_OCSPSigning));
+ ExtendedKeyUsageExtension ocspExt =
+ new ExtendedKeyUsageExtension(false, oidSet);
+ ext.set(ExtendedKeyUsageExtension.NAME, ocspExt);
+ }
+ }
+
+ public static void setAuthInfoAccess(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String aia = properties.getAIA();
+
+ if ((aia != null) && (aia.equals(Constants.TRUE))) {
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ AuthInfoAccessExtension aiaExt = new AuthInfoAccessExtension(false);
+ if (hostname != null && port != null) {
+ String location = "http://"+hostname+":"+port+"/ca/ocsp";
+ GeneralName ocspName = new GeneralName(new URIName(location));
+ aiaExt.addAccessDescription(AuthInfoAccessExtension.METHOD_OCSP, ocspName);
+ }
+
+ ext.set(AuthInfoAccessExtension.NAME, aiaExt);
+ }
+ }
+
+ public static void setAuthorityKeyIdentifier(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String aki = properties.getAKI();
+
+ if ((aki != null) && (aki.equals(Constants.TRUE))) {
+ KeyIdentifier id = createKeyIdentifier(keypair);
+ AuthorityKeyIdentifierExtension akiExt =
+ new AuthorityKeyIdentifierExtension(id, null, null);
+
+ ext.set(AuthorityKeyIdentifierExtension.NAME, akiExt);
+ }
+ }
+
+ public static void setSubjectKeyIdentifier(KeyPair keypair,
+ CertificateExtensions ext,
+ KeyCertData properties) throws IOException, NoSuchAlgorithmException,
+ InvalidKeyException {
+ String ski = properties.getSKI();
+
+ if ((ski != null) && (ski.equals(Constants.TRUE))) {
+ KeyIdentifier id = createKeyIdentifier(keypair);
+ SubjectKeyIdentifierExtension skiExt =
+ new SubjectKeyIdentifierExtension(id.getIdentifier());
+
+ ext.set(SubjectKeyIdentifierExtension.NAME, skiExt);
+ }
+ }
+
+ public static void setKeyUsageExtension(CertificateExtensions ext,
+ KeyUsageExtension keyUsage) throws IOException {
+ ext.set(KeyUsageExtension.NAME, keyUsage);
+ }
+
+ public static KeyIdentifier createKeyIdentifier(KeyPair keypair)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ X509Key subjectKeyInfo = convertPublicKeyToX509Key(
+ keypair.getPublic());
+
+ //md.update(subjectKeyInfo.getEncoded());
+ md.update(subjectKeyInfo.getKey());
+ return new KeyIdentifier(md.digest());
+ }
+
+ public static BigInteger getSerialNumber(LDAPConnection conn, String baseDN)
+ throws LDAPException {
+ String dn = "ou=certificateRepository,ou=ca," + baseDN;
+ BigInteger serialno = null;
+ LDAPEntry entry = conn.read(dn);
+ String serialnoStr = (String) entry.getAttribute(
+ "serialno").getStringValues().nextElement();
+
+ serialno = BigIntegerMapper.BigIntegerFromDB(serialnoStr);
+ LDAPAttribute attr = new LDAPAttribute("serialno");
+
+ attr.addValue(BigIntegerMapper.BigIntegerToDB(
+ serialno.add(new BigInteger("1"))));
+ LDAPModification mod = new LDAPModification(
+ LDAPModification.REPLACE, attr);
+
+ conn.modify(dn, mod);
+
+ return serialno;
+ }
+
+ public static void setSerialNumber(LDAPConnection conn,
+ String baseDN, BigInteger serial)
+ throws LDAPException {
+ String dn = "ou=certificateRepository,ou=ca," + baseDN;
+ LDAPAttribute attr = new LDAPAttribute("serialno");
+
+ // the serial number should already be set
+ attr.addValue(BigIntegerMapper.BigIntegerToDB(
+ serial));
+ LDAPModification mod = new LDAPModification(
+ LDAPModification.REPLACE, attr);
+
+ conn.modify(dn, mod);
+
+ }
+
+ public static void addCertToDB(LDAPConnection conn, String dn, X509CertImpl cert)
+ throws LDAPException, EBaseException {
+ BigInteger serialno = cert.getSerialNumber();
+ X509CertImplMapper mapper = new X509CertImplMapper();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ mapper.mapObjectToLDAPAttributeSet(null, null,
+ cert, attrs);
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass",
+ "certificateRecord"));
+ attrs.add(new LDAPAttribute("serialno",
+ BigIntegerMapper.BigIntegerToDB(
+ serialno)));
+ attrs.add(new LDAPAttribute("dateOfCreate",
+ DateMapper.dateToDB((CMS.getCurrentDate()))));
+ attrs.add(new LDAPAttribute("dateOfModify",
+ DateMapper.dateToDB((CMS.getCurrentDate()))));
+ attrs.add(new LDAPAttribute("certStatus",
+ "VALID"));
+ attrs.add(new LDAPAttribute("autoRenew",
+ "ENABLED"));
+ attrs.add(new LDAPAttribute("issuedBy",
+ "installation"));
+ LDAPEntry entry = new LDAPEntry("cn=" + serialno.toString() + "," + dn, attrs);
+
+ conn.add(entry);
+ }
+
+ public static CertificateExtensions getExtensions(String tokenname, String nickname)
+ throws NotInitializedException, TokenException, ObjectNotFoundException,
+ IOException, CertificateException {
+ String fullnickname = nickname;
+
+ if (!tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ fullnickname = tokenname + ":" + nickname;
+ CryptoManager manager = CryptoManager.getInstance();
+ X509Certificate cert = manager.findCertByNickname(fullnickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+ X509CertInfo info = (X509CertInfo) impl.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ return (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java b/pki/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java
new file mode 100644
index 000000000..279a62347
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java
@@ -0,0 +1,147 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.cert.*;
+import java.security.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.*;
+
+
+/**
+ * OCSP signing certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class OCSPSigningCert extends CertificateInfo {
+ public static final String SUBJECT_NAME =
+ "CN=Certificate Authority, O=Netscape Communications, C=US";
+
+ public OCSPSigningCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public OCSPSigningCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ /* included in console UI
+ try {
+ if (mProperties.get(Constants.PR_OCSP_SIGNING) == null) {
+ mProperties.put(Constants.PR_OCSP_SIGNING, Constants.TRUE);
+ }
+ if (mProperties.get(Constants.PR_OCSP_NOCHECK) == null) {
+ mProperties.put(Constants.PR_OCSP_NOCHECK, Constants.TRUE);
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_OCSP_SIGNING, Constants.TRUE);
+ mProperties.put(Constants.PR_OCSP_NOCHECK, Constants.TRUE);
+ }
+ */
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ // get PQG params from the configuration file
+ public static PQGParams getPQGParams() throws EBaseException, IOException,
+ PQGParamGenException {
+
+ byte[] p = mConfig.getByteArray("ca.dsaP", null);
+ byte[] q = mConfig.getByteArray("ca.dsaQ", null);
+ byte[] g = mConfig.getByteArray("ca.dsaG", null);
+ byte[] seed = mConfig.getByteArray("ca.dsaSeed", null);
+ byte[] H = mConfig.getByteArray("ca.dsaH", null);
+ int counter = mConfig.getInteger("ca.dsaCounter", 0);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+ BigInteger pqgSeed = new BigInteger(seed);
+ BigInteger pqgH = new BigInteger(H);
+
+ return new PQGParams(P, Q, G, pqgSeed, counter, pqgH);
+ }
+ return null;
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+
+ cmsFileTmp.putString("ca.signing.tokenname", tokenname);
+ String keyType = (String) mProperties.get(Constants.PR_KEY_TYPE);
+ String alg;
+
+ if (keyType.equals("RSA"))
+ alg = "SHA1withRSA";
+ else if (keyType.equals("DSA"))
+ alg = "SHA1withDSA";
+ else
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", keyType));
+
+ cmsFileTmp.putString("ca.signing.defaultSigningAlgorithm", alg);
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ cmsFileTmp.putString("ca.signing.cacertnickname", nickname);
+ else
+ cmsFileTmp.putString("ca.signing.cacertnickname",
+ tokenname + ":" + nickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName = (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "ocspSigningCert " + instanceName;
+ }
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ extension.set(KeyUsageExtension.NON_REPUDIATION, new Boolean(true));
+ extension.set(KeyUsageExtension.KEY_CERTSIGN, new Boolean(true));
+ extension.set(KeyUsageExtension.CRL_SIGN, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/PWCBsdr.java b/pki/base/common/src/com/netscape/cmscore/security/PWCBsdr.java
new file mode 100644
index 000000000..299b9f6e6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/PWCBsdr.java
@@ -0,0 +1,276 @@
+// --- 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.cmscore.security;
+
+
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.SecretDecoderRing;
+import org.mozilla.jss.crypto.TokenException;
+import java.io.*;
+import java.lang.*;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+import com.netscape.cmscore.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+
+
+/*
+ * A class to retrieve passwords from the SDR password cache
+ *
+ * @author Christina Fu
+ * @version $Revision$, $Date$
+ */
+
+public class PWCBsdr implements PasswordCallback {
+ InputStream in = null;
+ OutputStream out = null;
+ String mprompt = "";
+ boolean firsttime = true;
+ private PasswordCallback mCB = null;
+ private String mPWcachedb = null;
+ private ILogger mLogger = null;
+
+ public PWCBsdr() {
+ this(null);
+ }
+
+ public PWCBsdr(String prompt) {
+ in = System.in;
+ out = System.out;
+ mprompt = prompt;
+
+ /* to get the test program work
+ System.out.println("before CMS.getLogger");
+ try {
+ */
+ mLogger = CMS.getLogger();
+
+ /*
+ } catch (NullPointerException e) {
+ System.out.println("after CMS.getLoggergot NullPointerException ... testing ok");
+ }
+ System.out.println("after CMS.getLogger");
+ */
+ // get path to password cache
+ try {
+ mPWcachedb = CMS.getConfigStore().getString("pwCache");
+ CMS.debug("got pwCache from configstore: " +
+ mPWcachedb);
+ } catch (NullPointerException e) {
+ System.out.println("after CMS.getConfigStore got NullPointerException ... testing ok");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_CONFIG"));
+ // let it fall through
+ }
+
+ // System.out.println("after CMS.getConfigStore");
+ if (File.separator.equals("/")) {
+ // Unix
+ mCB = new PWsdrConsolePasswordCallback(prompt);
+ } else {
+ mCB = new PWsdrConsolePasswordCallback(prompt);
+ // mCB = new PWsdrDialogPasswordCallback( prompt );
+ }
+
+ // System.out.println( "Created PWCBsdr with prompt of "
+ // + mprompt );
+ }
+
+ /* We are now assuming that PasswordCallbackInfo.getname() returns
+ * the tag we are hoping to match in the cache.
+ */
+
+ public Password getPasswordFirstAttempt(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+
+ CMS.debug("in getPasswordFirstAttempt");
+
+ /* debugging code to see if token is logged in
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token =
+ cm.getInternalKeyStorageToken();
+ if (token.isLoggedIn() == false) {
+ // missed it.
+ CMS.debug("token not yet logged in!!");
+ } else {
+ CMS.debug("token logged in.");
+ }
+ } catch (Exception e) {
+ CMS.debug("crypto manager error:"+e.toString());
+ }
+ CMS.debug("still in getPasswordFirstAttempt");
+ */
+ Password pw = null;
+ String tmpPrompt = info.getName();
+
+ String skip_token = System.getProperty("cms.skip_token");
+
+ if (skip_token != null) {
+ if (tmpPrompt.equals(skip_token)) {
+ throw new PasswordCallback.GiveUpException();
+ }
+ }
+
+ try {
+ String defpw = System.getProperty("cms.defaultpassword");
+
+ if (defpw != null) {
+ return new Password(defpw.toCharArray());
+ }
+
+ /* mprompt has precedence over info.name */
+ if (!(mprompt == null)) {
+ tmpPrompt = mprompt;
+ }
+
+ if (tmpPrompt == null) { /* no name, fail */
+ System.out.println("Shouldn't get here");
+ throw new PasswordCallback.GiveUpException();
+ } else { /* get password from password cache */
+
+ CMS.debug("getting tag = " + tmpPrompt);
+ PWsdrCache pwc = new PWsdrCache(mPWcachedb, mLogger);
+
+ pw = pwc.getEntry(tmpPrompt);
+
+ if (pw != null) {
+ CMS.debug("non-null password returned in first attempt");
+ String tmp = new String(pw.getCharCopy());
+
+ return (pw);
+ } else { /* password not found */
+ // we don't want caller to do getPasswordAgain, for now
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_THROW_CALLBACK"));
+ throw new PasswordCallback.GiveUpException();
+ }
+ }
+ } catch (Throwable e) {
+ // System.out.println( "BUG HERE!!!!first!!!!!!!!!!!!!!!!!" );
+ // e.printStackTrace();
+ throw new PasswordCallback.GiveUpException();
+ }
+ }
+
+ /* The password cache has failed to return a password (or a usable password.
+ * Now we will try and get the password from the user and hopefully add
+ * the password to the cache pw cache
+ */
+ public Password getPasswordAgain(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+
+ CMS.debug("in getPasswordAgain");
+ try {
+ Password pw = null;
+
+ try {
+ if (firsttime) {
+ try {
+ firsttime = false;
+
+ pw = mCB.getPasswordFirstAttempt(info);
+ } catch (PasswordCallback.GiveUpException e) {
+ throw new PasswordCallback.GiveUpException();
+ }
+ } else {
+ pw = mCB.getPasswordAgain(info);
+ }
+ return (pw);
+ } catch (PasswordCallback.GiveUpException e) {
+ throw new PasswordCallback.GiveUpException();
+ }
+ } catch (Throwable e) {
+ // System.out.println( "BUG HERE!! in the password again!!"
+ // + "!!!!!!!!!!!" );
+ // e.printStackTrace();
+ throw new PasswordCallback.GiveUpException();
+ }
+ }
+
+ public void log(int level, String msg) {
+ if (mLogger == null) {
+ System.out.println(msg);
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level, "PWCBsdr " + msg);
+ }
+ }
+}
+
+
+class PWsdrConsolePasswordCallback implements PasswordCallback {
+ private String mPrompt = null;
+
+ public PWsdrConsolePasswordCallback(String p) {
+ mPrompt = p;
+ }
+
+ public String getPrompt() {
+ return mPrompt;
+ }
+
+ public Password getPasswordFirstAttempt(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+ if (mPrompt == null) {
+ System.out.println("Get password " + info.getName());
+ } else {
+ System.out.println(getPrompt());
+ }
+
+ Password tmppw = PWUtil.readPasswordFromStream();
+
+ return (tmppw);
+ }
+
+ public Password getPasswordAgain(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+ System.out.println("Password Incorrect.");
+ if (mPrompt == null) {
+ System.out.println("Get password " + info.getName());
+ } else {
+ System.out.println(getPrompt());
+ }
+
+ Password tmppw = PWUtil.readPasswordFromStream();
+
+ return (tmppw);
+ }
+}
+
+
+class PWsdrDialogPasswordCallback extends JDialogPasswordCallback {
+ private String mPrompt = null;
+
+ public PWsdrDialogPasswordCallback(String p) {
+ super();
+ mPrompt = p;
+ }
+
+ public String getPrompt(PasswordCallbackInfo info) {
+ if (mPrompt == null) {
+ return super.getPrompt(info);
+ } else {
+ return mPrompt;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/PWUtil.java b/pki/base/common/src/com/netscape/cmscore/security/PWUtil.java
new file mode 100644
index 000000000..afba0a4db
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/PWUtil.java
@@ -0,0 +1,83 @@
+// --- 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.cmscore.security;
+
+
+import java.lang.*;
+import java.io.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+
+
+public class
+PWUtil {
+ public static Password
+ readPasswordFromStream()
+ throws PasswordCallback.GiveUpException {
+ BufferedReader in;
+
+ in = new BufferedReader(new InputStreamReader(System.in));
+
+ StringBuffer buf = new StringBuffer();
+ String passwordString = new String();
+ int c;
+
+ try {
+ // System.out.println( "about to do read" );
+ try {
+ while ((c = System.in.read()) != -1) {
+ char ch = (char) c;
+
+ // System.out.println( "read [" + ch + "]" );
+ // System.out.println( "char is [" + ch + "]" );
+ if (ch != '\r') {
+ if (ch != '\n') {
+ buf.append(ch);
+ } else {
+ passwordString = buf.toString();
+ buf.setLength(0);
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("READ EXCEPTION");
+ }
+
+ // memory problem?
+ // String passwordString = in.readLine();
+ // System.out.println( "done read" );
+ // System.out.println( " password recieved is ["
+ // + passwordString + "]" );
+ if (passwordString == null) {
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ if (passwordString.equals("")) {
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ // System.out.println( "returning pw" );
+ return (new Password(passwordString.toCharArray()));
+ } catch (Exception e) {
+ throw new PasswordCallback.GiveUpException();
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/PWsdrCache.java b/pki/base/common/src/com/netscape/cmscore/security/PWsdrCache.java
new file mode 100644
index 000000000..309978f28
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/PWsdrCache.java
@@ -0,0 +1,639 @@
+// --- 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.cmscore.security;
+
+
+import org.mozilla.jss.SecretDecoderRing.KeyManager;
+import org.mozilla.jss.SecretDecoderRing.Encryptor;
+import org.mozilla.jss.SecretDecoderRing.Decryptor;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.Base64OutputStream;
+import java.io.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import com.netscape.cmscore.base.*;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+
+/*
+ * A class for managing passwords in the SDR password cache
+ *
+ * @author Christina Fu
+ * @version $Revision$, $Date$
+ */
+public class PWsdrCache {
+ public static final String PROP_PWC_TOKEN_NAME = "pwcTokenname";
+ public static final String PROP_PWC_KEY_ID = "pwcKeyid";
+ public static final String PROP_PWC_NICKNAME = "sso_key";
+
+ private ILogger mLogger = null;
+ private String mPWcachedb = null;
+ // mTool tells if this is called from the PasswordCache tool
+ private boolean mIsTool = false;
+ private byte[] mKeyID = null;
+ private String mTokenName = null;
+ private CryptoToken mToken = null;
+
+ // for CMSEngine
+ public PWsdrCache() throws EBaseException {
+ mLogger = CMS.getLogger();
+ try {
+ mPWcachedb = CMS.getConfigStore().getString("pwCache");
+ CMS.debug("got pwCache file path from configstore");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_GET_CONFIG"));
+ // let it fall through
+ }
+ initToken();
+ initKey();
+ }
+
+ private void initToken() throws EBaseException {
+ if (mToken == null) {
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ mTokenName = CMS.getConfigStore().getString(PROP_PWC_TOKEN_NAME);
+ log (ILogger.LL_DEBUG, "pwcTokenname specified. Use token for SDR key. tokenname= "+mTokenName);
+ mToken = cm.getTokenByName(mTokenName);
+ } catch (NotInitializedException e) {
+ log (ILogger.LL_FAILURE, e.toString());
+ throw new EBaseException(e.toString());
+ } catch (Exception e) {
+ log (ILogger.LL_DEBUG, "no pwcTokenname specified, use internal token for SDR key");
+ mToken = cm.getInternalKeyStorageToken();
+ }
+ }
+ }
+
+ // called from PWCBsdr or CMSEngine only
+ private void initKey() throws EBaseException {
+ if (mKeyID == null) {
+ try {
+ String keyID = CMS.getConfigStore().getString(PROP_PWC_KEY_ID);
+ log (ILogger.LL_DEBUG, "retrieved PWC SDR key");
+ mKeyID = base64Decode(keyID);
+
+ } catch (Exception e) {
+ log (ILogger.LL_DEBUG, "no pwcSDRKey specified");
+ throw new EBaseException(e.toString());
+ }
+ }
+ }
+
+ // for PasswordCache tool (isTool == true)
+ // and installation wizard (isTool == false)
+ // Do not use for PWCBsdr, since we don't want to mistakenly
+ // generate SDR keys in case of configuration errors
+ public PWsdrCache(String pwCache, String pwcTokenname, byte[] keyId,
+ boolean isTool) throws Exception {
+ mPWcachedb = pwCache;
+ mIsTool = isTool;
+ mTokenName = pwcTokenname;
+ CryptoManager cm = null;
+
+ if (keyId != null) {
+ mKeyID = keyId;
+ }
+
+ cm = CryptoManager.getInstance();
+ if (mTokenName != null) {
+ mToken = cm.getTokenByName(mTokenName);
+ mToken = cm.getInternalKeyStorageToken();
+ debug("PWsdrCache: mToken = "+mTokenName);
+ } else {
+ mToken = cm.getInternalKeyStorageToken();
+ debug("PWsdrCache: mToken = internal");
+ }
+ }
+
+ public byte[] getKeyId() {
+ return mKeyID;
+ }
+
+ public String getTokenName() {
+ return mTokenName;
+ }
+
+ public void deleteUniqueNamedKey( String nickName )
+ throws Exception
+ {
+ KeyManager km = new KeyManager( mToken );
+ km.deleteUniqueNamedKey( nickName );
+ }
+
+ public byte[] generateSDRKey () throws Exception {
+ return generateSDRKeyWithNickName(PROP_PWC_NICKNAME);
+ }
+
+ public byte[] generateSDRKeyWithNickName (String nickName)
+ throws Exception
+ {
+ try {
+
+ if (mIsTool != true) {
+ // generate SDR key
+ KeyManager km = new KeyManager(mToken);
+ try {
+ // Bugscape Bug #54838: Due to the CMS cloning feature,
+ // we must check for the presence of
+ // a uniquely named symmetric key
+ // prior to making an attempt to
+ // generate it!
+ //
+ if( !( km.uniqueNamedKeyExists( nickName ) ) ) {
+ mKeyID = km.generateUniqueNamedKey( nickName );
+ }
+ } catch (TokenException e) {
+ log (0, "generateSDRKey() failed on "+e.toString());
+ throw e;
+ }
+ }
+ } catch (Exception e) {
+ log (ILogger.LL_FAILURE, e.toString());
+ throw e;
+ }
+ return mKeyID;
+ }
+
+ public byte[] base64Decode(String s) throws IOException {
+ byte[] d = com.netscape.osutil.OSUtil.AtoB(s);
+ return d;
+ }
+
+ public static String base64Encode(byte[] bytes) throws IOException {
+ // All this streaming is lame, but Base64OutputStream needs a
+ // PrintStream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(new
+ PrintStream(new
+ FilterOutputStream(output)
+ )
+ );
+
+ b64.write(bytes);
+ b64.flush();
+
+ // This is internationally safe because Base64 chars are
+ // contained within 8859_1
+ return output.toString("8859_1");
+ }
+
+
+ // for PWCBsdr
+ public PWsdrCache(String pwCache, ILogger logger) throws
+ EBaseException {
+ mLogger = logger;
+ mPWcachedb = pwCache;
+ initToken();
+ initKey();
+ }
+
+ public void addEntry(String tag, String pwd) throws EBaseException {
+ addEntry(tag, pwd, (Hashtable) null);
+ }
+
+ /*
+ * Store passwd in pwcache.
+ */
+ public void addEntry(Hashtable ht) throws EBaseException {
+ addEntry((String) null, (String) null, ht);
+ }
+
+ /*
+ * add passwd in pwcache.
+ */
+ public void addEntry(String tag, String pwd, Hashtable tagPwds) throws EBaseException {
+
+ String stringToAdd = null;
+ String bufs = null;
+
+ if (tagPwds == null) {
+ stringToAdd = tag + ":" + pwd + "\n";
+ } else {
+ Enumeration enum1 = tagPwds.keys();
+
+ while (enum1.hasMoreElements()) {
+ tag = (String) enum1.nextElement();
+ pwd = (String) tagPwds.get(tag);
+ debug("password tag: " + tag + " stored in " + mPWcachedb);
+
+ if (stringToAdd == null) {
+ stringToAdd = tag + ":" + pwd + "\n";
+ } else {
+ stringToAdd += tag + ":" + pwd + "\n";
+ }
+ }
+ }
+
+ String dcrypts = readPWcache();
+
+ if (dcrypts != null) {
+ // converts to Hashtable, replace if tag exists, add
+ // if tag doesn't exist
+ Hashtable ht = string2Hashtable(dcrypts);
+
+ if (ht.containsKey(tag) == false) {
+ debug("adding new tag: " + tag);
+ ht.put(tag, pwd);
+ } else {
+ debug("replacing tag: " + tag);
+ ht.put(tag, pwd);
+ }
+ bufs = hashtable2String(ht);
+ } else {
+ debug("adding new tag: " + tag);
+ bufs = stringToAdd;
+ }
+
+ // write update to cache
+ writePWcache(bufs);
+ }
+
+ /*
+ * delete passwd in pwcache.
+ */
+ public void deleteEntry(String tag) throws EBaseException {
+ String bufs = null;
+
+ String dcrypts = readPWcache();
+
+ if (dcrypts != null) {
+ // converts to Hashtable, replace if tag exists, add
+ // if tag doesn't exist
+ Hashtable ht = string2Hashtable(dcrypts);
+
+ if (ht.containsKey(tag) == false) {
+ debug("tag: " + tag + " does not exist");
+ return;
+ } else {
+ debug("deleting tag: " + tag);
+ ht.remove(tag);
+ }
+ bufs = hashtable2String(ht);
+ } else {
+ debug("password cache contains no tags");
+ return;
+ }
+
+ // write update to cache
+ writePWcache(bufs);
+ }
+
+ /*
+ * reads and decrypts the pwcache.db content
+ */
+ public String readPWcache() throws EBaseException {
+ debug("about to read password cache");
+ String dcrypts = null;
+ Decryptor sdr = new Decryptor(mToken);
+
+ // not used, but could used for debugging
+ int totalRead = 0;
+ FileInputStream inputs = null;
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try {
+ // for SDR -> read, decrypt, append, and write
+ inputs = new FileInputStream(mPWcachedb);
+ byte[] readbuf = new byte[2048]; // for now
+ int numRead = 0;
+
+ while ((numRead = inputs.read(readbuf)) != -1) {
+ bos.write(readbuf, 0, numRead);
+ totalRead += numRead;
+ }
+ inputs.close();
+ } catch (FileNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_FILE", mPWcachedb, e.toString()));
+ throw new EBaseException(e.toString() + ": " + mPWcachedb);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_FILE", mPWcachedb, e.toString()));
+ throw new EBaseException(e.toString() + ": " + mPWcachedb);
+ }
+
+ if (totalRead > 0) {
+ try {
+ // decrypt it first to append
+ byte[] dcryptb = sdr.decrypt(bos.toByteArray());
+
+ dcrypts = new String(dcryptb, "UTF-8");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_DECRYPT", e.toString()));
+ e.printStackTrace();
+ throw new EBaseException("password cache decrypt failed");
+ }
+ }
+
+ return dcrypts;
+ }
+
+ /*
+ * encrypts and writes the whole String buf into pwcache.db
+ */
+ public void writePWcache(String bufs) throws EBaseException {
+ try {
+ Encryptor sdr = new Encryptor(mToken, mKeyID,
+ Encryptor.DEFAULT_ENCRYPTION_ALG);
+
+ byte[] writebuf = null;
+
+ try {
+ // now encrypt it again
+ writebuf = sdr.encrypt(bufs.getBytes("UTF-8"));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_ENCRYPT", e.toString()));
+ e.printStackTrace();
+ throw new EBaseException("password cache encrypt failed");
+ }
+
+ File tmpPWcache = new File(mPWcachedb + ".tmp");
+
+ if (tmpPWcache.exists()) {
+ // it wasn't removed?
+ tmpPWcache.delete();
+ tmpPWcache = new File(mPWcachedb + ".tmp");
+ }
+ FileOutputStream outstream = new FileOutputStream(mPWcachedb + ".tmp");
+
+ outstream.write(writebuf);
+ outstream.close();
+
+ File origFile = new File(mPWcachedb);
+
+ try {
+ if( Utils.isNT() ) {
+ // NT is very picky on the path
+ Utils.exec( "copy " +
+ tmpPWcache.getAbsolutePath().replace( '/',
+ '\\' ) +
+ " " +
+ origFile.getAbsolutePath().replace( '/',
+ '\\' ) );
+ } else {
+ // Create a copy of the original file which
+ // preserves the original file permissions.
+ Utils.exec( "cp -p " + tmpPWcache.getAbsolutePath() + " " +
+ origFile.getAbsolutePath() );
+ }
+
+ // Remove the original file if and only if
+ // the backup copy was successful.
+ if( origFile.exists() ) {
+ if( !Utils.isNT() ) {
+ try {
+ Utils.exec( "chmod 00660 " +
+ origFile.getCanonicalPath() );
+ } catch( IOException e ) {
+ CMS.debug( "Unable to change file permissions on "
+ + origFile.toString() );
+ }
+ }
+ tmpPWcache.delete();
+ debug( "operation completed for " + mPWcachedb );
+ }
+ } catch (Exception exx) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_CACHE", exx.toString()));
+ throw new EBaseException(exx.toString() + ": " + mPWcachedb);
+ }
+ } catch (FileNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_FILE", mPWcachedb, e.toString()));
+ throw new EBaseException(e.toString() + ": " + mPWcachedb);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_FILE", mPWcachedb, e.toString()));
+ throw new EBaseException(e.toString() + ": " + mPWcachedb);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_FILE", mPWcachedb, e.toString()));
+ throw new EBaseException(e.toString() + ": " + mPWcachedb);
+ }
+ }
+
+ public String hashtable2String(Hashtable ht) {
+ Enumeration enum1 = ht.keys();
+ String returnString = null;
+
+ while (enum1.hasMoreElements()) {
+ String tag = (String) enum1.nextElement();
+ String pwd = (String) ht.get(tag);
+
+ if (returnString == null) {
+ returnString = tag + ":" + pwd + "\n";
+ } else {
+ returnString += tag + ":" + pwd + "\n";
+ }
+ }
+ return returnString;
+ }
+
+ public Hashtable string2Hashtable(String cache) {
+ Hashtable ht = new Hashtable();
+
+ // first, break into lines
+ StringTokenizer st = new StringTokenizer(cache, "\n");
+
+ while (st.hasMoreTokens()) {
+ String line = (String) st.nextToken();
+ // break into tag:password format for each line
+ int colonIdx = line.indexOf(":");
+
+ if (colonIdx != -1) {
+ String tag = line.substring(0, colonIdx);
+ String passwd = line.substring(colonIdx + 1,
+ line.length());
+
+ ht.put(tag.trim(), passwd.trim());
+ } else {
+ //invalid format...log or throw...later
+ }
+ }
+ return ht;
+ }
+
+ /*
+ * get password from cache. This one supplies cache file name
+ */
+ public Password getEntry(String fileName, String tag) {
+ mPWcachedb = fileName;
+ return getEntry(tag);
+ }
+
+ /*
+ * if tag found with pwd, return it
+ * if tag not found, return null, which will cause it to give up
+ */
+ public Password getEntry(String tag) {
+ Hashtable pwTable = null;
+ String pw = null;
+
+ debug("in getEntry, tag=" + tag);
+
+ if (mPWcachedb == null) {
+ debug("mPWcachedb file path name is not initialized");
+ return null;
+ }
+
+ String dcrypts = null;
+
+ try {
+ dcrypts = readPWcache();
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_READ", e.toString()));
+ return null;
+ }
+
+ if (dcrypts != null) {
+ // parse the cache
+ String cache = dcrypts;
+
+ // this is created and destroyed at each use
+ pwTable = string2Hashtable(cache);
+ debug("in getEntry, pw cache parsed");
+ pw = (String) pwTable.get(tag);
+ }
+
+ if (pw != null) {
+ debug("getEntry gotten password for " + tag);
+ return new Password(pw.toCharArray());
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_TAG", tag));
+ return null;
+ }
+ }
+
+ //copied from IOUtil.java
+ /**
+ * Checks if this is NT.
+ */
+ public static boolean isNT() {
+ return ((File.separator).equals("\\"));
+ }
+
+ public static boolean exec(String cmd) throws EBaseException {
+ try {
+ String cmds[] = null;
+
+ if (isNT()) {
+ // NT
+ cmds = new String[3];
+ cmds[0] = "cmd";
+ cmds[1] = "/c";
+ cmds[2] = cmd;
+ } else {
+ // UNIX
+ cmds = new String[3];
+ cmds[0] = "/bin/sh";
+ cmds[1] = "-c";
+ cmds[2] = cmd;
+ }
+ Process process = Runtime.getRuntime().exec(cmds);
+
+ process.waitFor();
+ BufferedReader pOut = null;
+ String l = null;
+
+ if (process.exitValue() == 0) {
+
+ /**
+ pOut = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ while ((l = pOut.readLine()) != null) {
+ System.out.println(l);
+ }
+ **/
+ return true;
+ } else {
+
+ /**
+ pOut = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ l = null;
+ while ((l = pOut.readLine()) != null) {
+ System.out.println(l);
+ }
+ **/
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public void debug(String msg) {
+ if (mLogger != null) {
+ CMS.debug(msg);
+ }
+ }
+
+ public void log(int level, String msg) {
+ if (mLogger != null) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level,
+ "PWsdrCache " + msg);
+ } else if (mIsTool) {
+ System.out.println(msg);
+ } // else it's most likely the installation wizard...no logging
+ }
+
+ /*
+ * list passwds in pwcache.
+ */
+ public boolean pprint() {
+ String bufs = null;
+ String dcrypts = null;
+
+ try {
+ dcrypts = readPWcache();
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_PW_READ", e.toString()));
+ return false;
+ }
+
+ debug("----- Password Cache Content -----");
+
+ if (dcrypts != null) {
+ // first, break into lines
+ StringTokenizer st = new StringTokenizer(dcrypts, "\n");
+
+ while (st.hasMoreTokens()) {
+ String line = (String) st.nextToken();
+ // break into tag:password format for each line
+ int colonIdx = line.indexOf(":");
+
+ if (colonIdx != -1) {
+ String tag = line.substring(0, colonIdx);
+ String passwd = line.substring(colonIdx + 1,
+ line.length());
+
+ debug(tag.trim() +
+ " : " + passwd.trim());
+ } else {
+ //invalid format...log or throw...later
+ debug("invalid format");
+ }
+ }
+ } // else print nothing
+ return true;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/security/Provider.java b/pki/base/common/src/com/netscape/cmscore/security/Provider.java
new file mode 100644
index 000000000..3e343c78c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/Provider.java
@@ -0,0 +1,53 @@
+// --- 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.cmscore.security;
+
+
+public class Provider extends java.security.Provider {
+
+ public Provider() {
+ super("CMS", 1.4,
+ "Provides Signature and Message Digesting");
+
+ /////////////////////////////////////////////////////////////
+ // Signature
+ /////////////////////////////////////////////////////////////
+
+ put("Signature.SHA1withDSA", "org.mozilla.jss.provider.DSASignature");
+
+ put("Alg.Alias.Signature.DSA", "SHA1withDSA");
+ put("Alg.Alias.Signature.DSS", "SHA1withDSA");
+ put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
+ put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
+ put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
+ put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
+ put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
+
+ put("Signature.MD5/RSA", "org.mozilla.jss.provider.MD5RSASignature");
+ put("Signature.MD2/RSA", "org.mozilla.jss.provider.MD2RSASignature");
+ put("Signature.SHA-1/RSA",
+ "org.mozilla.jss.provider.SHA1RSASignature");
+
+ put("Alg.Alias.Signature.SHA1/RSA", "SHA-1/RSA");
+
+ /////////////////////////////////////////////////////////////
+ // Message Digesting
+ /////////////////////////////////////////////////////////////
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/security/RASigningCert.java b/pki/base/common/src/com/netscape/cmscore/security/RASigningCert.java
new file mode 100644
index 000000000..c6f2f7cbc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/RASigningCert.java
@@ -0,0 +1,125 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.*;
+import java.io.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.crypto.*;
+import java.security.cert.*;
+
+
+/**
+ * RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class RASigningCert extends CertificateInfo {
+ public static final String SUBJECT_NAME =
+ "CN=Registration Authority, O=Netscape Communications, C=US";
+ private String mTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ public RASigningCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public RASigningCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ String tmp = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+
+ if ((tmp != null) &&
+ (!tmp.equals(Constants.PR_INTERNAL_TOKEN)))
+ mTokenname = tmp;
+ try {
+ if (mProperties.get(Constants.PR_AKI) == null) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ cmsFileTmp.putString("ra.certNickname", nickname);
+ else
+ cmsFileTmp.putString("ra.certNickname", tokenname + ":" + nickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName =
+ (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "raSigningCert " + instanceName;
+ }
+
+ /*
+ public SignatureAlgorithm getSigningAlgorithm() {
+ SignatureAlgorithm sAlg =
+ (SignatureAlgorithm)mProperties.get(Constants.PR_SIGNATURE_ALGORITHM);
+ if (sAlg != null) {
+ return sAlg;
+ }
+ String alg = (String)mProperties.get(Constants.PR_KEY_TYPE);
+
+ if (alg.equals("RSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+ */
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/SSLCert.java b/pki/base/common/src/com/netscape/cmscore/security/SSLCert.java
new file mode 100644
index 000000000..0967b0930
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/SSLCert.java
@@ -0,0 +1,137 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.*;
+import java.io.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.crypto.*;
+import java.security.cert.*;
+
+
+/**
+ * SSL server certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class SSLCert extends CertificateInfo {
+ public static final String SUBJECT_NAME =
+ "CN=SSL, O=Netscape Communications, C=US";
+ private String mTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ public SSLCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public SSLCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ String tmp = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+
+ if ((tmp != null) &&
+ (!tmp.equals(Constants.PR_INTERNAL_TOKEN)))
+ mTokenname = tmp;
+ try {
+ if (mProperties.get(Constants.PR_AKI) == null) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_AKI, Constants.FALSE);
+ }
+
+ // 020598: The server bit has to be turned on. Otherwise, it might
+ // crash jss.
+ //mProperties.put(Constants.PR_SSL_SERVER_BIT, Constants.TRUE);
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+ String fullNickname = "";
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ fullNickname = nickname;
+ } else {
+ fullNickname = tokenname + ":" + nickname;
+ }
+ cmsFileTmp.putString("agent.nickName", fullNickname);
+ cmsFileTmp.putString("ee.nickName", fullNickname);
+ cmsFileTmp.putString("radm.nickName", fullNickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName =
+ (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "Server-Cert " + instanceName;
+ }
+
+ /*
+ public SignatureAlgorithm getSigningAlgorithm() {
+ SignatureAlgorithm sAlg =
+ (SignatureAlgorithm)mProperties.get(Constants.PR_SIGNATURE_ALGORITHM);
+ if (sAlg != null) {
+ return sAlg;
+ }
+ String alg = (String)mProperties.get(Constants.PR_KEY_TYPE);
+
+ if (alg.equals("RSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+ */
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ extension.set(KeyUsageExtension.NON_REPUDIATION, new Boolean(true));
+ extension.set(KeyUsageExtension.KEY_ENCIPHERMENT, new Boolean(true));
+ extension.set(KeyUsageExtension.DATA_ENCIPHERMENT, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java b/pki/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java
new file mode 100644
index 000000000..d38b35b44
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java
@@ -0,0 +1,131 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.*;
+import java.io.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.base.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.crypto.*;
+import java.security.cert.*;
+
+
+/**
+ * SSL server certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class SSLSelfSignedCert extends CertificateInfo {
+ public static final String SUBJECT_NAME =
+ "CN=SSL, O=Netscape Communications, C=US";
+ private String mTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ public SSLSelfSignedCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public SSLSelfSignedCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ String tmp = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+
+ if ((tmp != null) &&
+ (!tmp.equals(Constants.PR_INTERNAL_TOKEN)))
+ mTokenname = tmp;
+ mProperties.remove(Constants.PR_AKI);
+
+ // 020599: This SSL server bit has to be turned on. Otherwise, it
+ // might crash jss.
+ mProperties.put(Constants.PR_SSL_SERVER_BIT, Constants.TRUE);
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ String tokenname = (String) mProperties.get(Constants.PR_TOKEN_NAME);
+ String nickname = getNickname();
+ String fullNickname = "";
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ fullNickname = nickname;
+ } else {
+ fullNickname = tokenname + ":" + nickname;
+ }
+ cmsFileTmp.putString("radm.https.nickName", fullNickname);
+ cmsFileTmp.commit(false);
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName =
+ (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "Remote Admin Server-Cert " + instanceName;
+ }
+
+ /*
+ public SignatureAlgorithm getSigningAlgorithm() {
+ SignatureAlgorithm sAlg =
+ (SignatureAlgorithm)mProperties.get(Constants.PR_SIGNATURE_ALGORITHM);
+ if (sAlg != null) {
+ return sAlg;
+ }
+ String alg = (String)mProperties.get(Constants.PR_KEY_TYPE);
+
+ if (alg.equals("RSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+ */
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ public void signed() {
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ //extension.set(KeyUsageExtension.NON_REPUDIATION, new Boolean(true));
+ extension.set(KeyUsageExtension.KEY_ENCIPHERMENT, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/security/SubsystemCert.java b/pki/base/common/src/com/netscape/cmscore/security/SubsystemCert.java
new file mode 100644
index 000000000..4244d0212
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/SubsystemCert.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.security;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.PrivateKey;
+import java.security.InvalidKeyException;
+import java.security.SignatureException;
+import java.security.cert.*;
+import java.security.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.CryptoManager.*;
+import org.mozilla.jss.*;
+
+
+/**
+ * Subsystem certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class SubsystemCert extends CertificateInfo {
+
+ public SubsystemCert(KeyCertData properties) {
+ this(properties, null);
+ }
+
+ public SubsystemCert(KeyCertData properties, KeyPair pair) {
+ super(properties, pair);
+ try {
+ if (mProperties.get(Constants.PR_SSL_CLIENT_BIT) == null)
+ mProperties.put(Constants.PR_SSL_CLIENT_BIT, Constants.TRUE);
+ } catch (Exception e) {
+ mProperties.put(Constants.PR_SSL_CLIENT_BIT, Constants.TRUE);
+ }
+ }
+
+ public String getSubjectName() {
+ return (String) mProperties.get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public void updateConfig(IConfigStore cmsFileTmp) throws EBaseException {
+ }
+
+ public String getNickname() {
+ String name = (String) mProperties.get(Constants.PR_NICKNAME);
+ String instanceName = (String) mProperties.get(ConfigConstants.PR_CERT_INSTANCE_NAME);
+
+ if (name != null)
+ return name;
+ return "subsystemCert " + instanceName;
+ }
+
+ public String getKeyAlgorithm() {
+ return (String) mProperties.get(Constants.PR_KEY_TYPE);
+ }
+
+ protected KeyUsageExtension getKeyUsageExtension() throws IOException {
+ KeyUsageExtension extension = new KeyUsageExtension();
+
+ extension.set(KeyUsageExtension.DIGITAL_SIGNATURE, new Boolean(true));
+ extension.set(KeyUsageExtension.NON_REPUDIATION, new Boolean(true));
+ extension.set(KeyUsageExtension.KEY_ENCIPHERMENT, new Boolean(true));
+ return extension;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java b/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java
new file mode 100644
index 000000000..22e4044ac
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java
@@ -0,0 +1,139 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cmscore.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a single element in
+ * an ordered list of self test instances.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class SelfTestOrderedInstance {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+ private static final String ELEMENT_DELIMITER = ":";
+ private static final String CRITICAL = "critical";
+
+ ////////////////////////////////////////
+ // SelfTestOrderedInstance parameters //
+ ////////////////////////////////////////
+
+ private String mInstanceName = null;
+ private boolean mCritical = false;
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Constructs a single element within an ordered list of self tests.
+ * A "listElement" contains a string of the form "[instanceName]" or
+ * "[instanceName]:critical".
+ * <P>
+ *
+ * @param listElement a string containing the "instanceName" and
+ * information indictating whether or not the instance is "critical"
+ */
+ public SelfTestOrderedInstance(String listElement) {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (listElement != null) {
+ listElement = listElement.trim();
+ } else {
+ // no listElement is present
+ return;
+ }
+
+ StringTokenizer token = new StringTokenizer(listElement,
+ ELEMENT_DELIMITER);
+
+ // extract the mInstanceName
+ if (token.hasMoreTokens()) {
+ // prior to the ELEMENT_DELIMITER
+ mInstanceName = token.nextToken().trim();
+
+ // extract the mCritical indicator
+ if (token.hasMoreTokens()) {
+ // something exists after the ELEMENT_DELIMITER
+ if (token.nextToken().trim().equals(CRITICAL)) {
+ mCritical = true;
+ }
+ }
+ } else {
+ // no ELEMENT_DELIMITER is present
+ mInstanceName = listElement;
+ }
+
+ }
+
+ /////////////////////////////////////
+ // SelfTestOrderedInstance methods //
+ /////////////////////////////////////
+
+ /**
+ * Returns the name associated with this self test; may be null.
+ * <P>
+ *
+ * @return instanceName of this self test
+ */
+ public String getSelfTestName() {
+ return mInstanceName;
+ }
+
+ /**
+ * Returns the criticality associated with this self test.
+ * <P>
+ *
+ * @return true if failure of this self test is fatal when
+ * it is executed; otherwise return false
+ */
+ public boolean isSelfTestCritical() {
+ return mCritical;
+ }
+
+ /**
+ * Sets/resets the criticality associated with this self test.
+ * <P>
+ *
+ * @param criticalMode the criticality of this self test
+ */
+ public void setSelfTestCriticalMode(boolean criticalMode) {
+ mCritical = criticalMode;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java b/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
new file mode 100644
index 000000000..5c75d8fd5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
@@ -0,0 +1,1907 @@
+// --- 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 statement //
+///////////////////////
+
+package com.netscape.cmscore.selftests;
+
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.io.*;
+import java.util.*;
+import java.text.MessageFormat;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.selftests.*;
+
+
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * This class implements a container for self tests.
+ * <P>
+ *
+ * @author mharmsen
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class SelfTestSubsystem
+ implements ISelfTestSubsystem {
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+
+
+ ///////////////////////
+ // helper parameters //
+ ///////////////////////
+
+
+
+ //////////////////////////////////
+ // SelfTestSubsystem parameters //
+ //////////////////////////////////
+
+ private ISubsystem mOwner = null;
+ private IConfigStore mConfig = null;
+ private ILogEventListener mLogger = null;
+ private ILogger mErrorLogger = CMS.getLogger();
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private String mRootPrefix = null;
+ private String mPrefix = null;
+
+ public Hashtable mSelfTestInstances = new Hashtable();
+ public Vector mOnDemandOrder = new Vector();
+ public Vector mStartupOrder = new Vector();
+
+ ///////////////////////////
+ // ISubsystem parameters //
+ ///////////////////////////
+
+ private static final String LIST_DELIMITER = ",";
+
+ private static final String ELEMENT_DELIMITER = ":";
+ private static final String CRITICAL = "critical";
+
+ private static final String LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION =
+ "LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION_2";
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+
+
+ ////////////////////
+ // helper methods //
+ ////////////////////
+
+ /**
+ * Signed Audit Log
+ *
+ * This helper method is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ private void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * This helper method returns the "full" property name (the corresponding
+ * substore name prepended in front of the plugin/parameter name). This
+ * method may return null.
+ * <P>
+ *
+ * @param instancePrefix full name of configuration store
+ * @param instanceName instance name of self test
+ * @return fullname of this self test plugin
+ */
+ private String getFullName(String instancePrefix,
+ String instanceName) {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instancePrefix != null) {
+ instancePrefix = instancePrefix.trim();
+ }
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ }
+
+ if ((instancePrefix != null) &&
+ (instancePrefix != "")) {
+ if ((instanceName != null) &&
+ (instanceName != "")) {
+ instanceFullName = instancePrefix
+ + "."
+ + instanceName;
+ }
+ } else {
+ instanceFullName = instanceName;
+ }
+
+ return instanceFullName;
+ }
+
+ /**
+ * This helper method checks to see if an instance name/value
+ * pair exists for the corresponding ordered list element.
+ * <P>
+ *
+ * @param element owner of this subsystem
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ private void checkInstance(SelfTestOrderedInstance element)
+ throws EInvalidSelfTestException, EMissingSelfTestException {
+ String instanceFullName = null;
+ String instanceName = null;
+ String instanceValue = null;
+
+ String instancePath = PROP_CONTAINER + "." + PROP_INSTANCE;
+ IConfigStore instanceConfig = mConfig.getSubStore(instancePath);
+
+ instanceName = element.getSelfTestName();
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ try {
+ // extract the self test plugin value(s)
+ instanceValue = instanceConfig.getString(instanceName);
+
+ if ((instanceValue == null) ||
+ (instanceValue.equals(""))) {
+ // self test plugin instance property name exists,
+ // but it contains no value(s)
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_VALUES",
+ instanceFullName));
+
+ throw new
+ EMissingSelfTestException(instanceFullName,
+ instanceValue);
+ } else {
+ instanceValue = instanceValue.trim();
+ }
+
+ } catch (EPropertyNotFound e) {
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ } catch (EBaseException e) {
+ // self test plugin instance EBaseException
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
+ instanceFullName,
+ instanceValue));
+
+ throw new EInvalidSelfTestException(instanceFullName,
+ instanceValue);
+ }
+ }
+
+ ///////////////////////////////
+ // SelfTestSubsystem methods //
+ ///////////////////////////////
+
+ //
+ // methods associated with the list of on demand self tests
+ //
+
+ /**
+ * List the instance names of all the self tests enabled to run on demand
+ * (in execution order); may return null.
+ * <P>
+ *
+ * @return list of self test instance names run on demand
+ */
+ public String[] listSelfTestsEnabledOnDemand() {
+ String[] mList;
+
+ int numElements = mOnDemandOrder.size();
+
+ if (numElements != 0) {
+ mList = new String[numElements];
+ } else {
+ return null;
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ int i = 0;
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ mList[i] = instance.getSelfTestName();
+ if (mList[i] != null) {
+ mList[i] = mList[i].trim();
+ }
+ i++;
+ }
+
+ return mList;
+ }
+
+ /**
+ * Enable the specified self test to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void enableSelfTestOnDemand(String instanceName,
+ boolean isCritical)
+ throws EInvalidSelfTestException, EMissingSelfTestException {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ instance.setSelfTestCriticalMode(isCritical);
+ return;
+ }
+ }
+
+ // append a new element to the on-demand ordered list
+ String elementName = null;
+
+ if (isCritical) {
+ elementName = instanceName
+ + ELEMENT_DELIMITER
+ + CRITICAL;
+ } else {
+ elementName = instanceName;
+ }
+
+ SelfTestOrderedInstance element;
+
+ element = new SelfTestOrderedInstance(elementName);
+
+ // SANITY CHECK: find the corresponding instance property
+ // name for this self test plugin
+ checkInstance(element);
+
+ // store this self test plugin in on-demand order
+ mOnDemandOrder.add(element);
+ }
+
+ /**
+ * Disable the specified self test from being able to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public void disableSelfTestOnDemand(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ mOnDemandOrder.remove(instance);
+ return;
+ }
+ }
+
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+
+ /**
+ * Determine if the specified self test is enabled to be executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if the specified self test is enabled on demand
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestEnabledOnDemand(String instanceName)
+ throws EMissingSelfTestException {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if failure of the specified self test is fatal when
+ * it is executed on demand.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if failure of the specified self test is fatal when
+ * it is executed on demand
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestCriticalOnDemand(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ if (instance.isSelfTestCritical()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+
+ /**
+ * Execute all self tests specified to be run on demand.
+ * <P>
+ *
+ * @exception EMissingSelfTestException subsystem has missing name
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTestsOnDemand()
+ throws EMissingSelfTestException, ESelfTestException {
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsOnDemand():"
+ + " ENTERING . . .");
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed on demand
+ Enumeration instances = mOnDemandOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ String instanceFullName = null;
+ String instanceName = instance.getSelfTestName();
+
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ if (mSelfTestInstances.containsKey(instanceName)) {
+ ISelfTest test = (ISelfTest)
+ mSelfTestInstances.get(instanceName);
+
+ try {
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsOnDemand():"
+ + " running \""
+ + test.getSelfTestName()
+ + "\"");
+ }
+
+ test.runSelfTest(mLogger);
+ } catch (ESelfTestException e) {
+ // Check to see if the self test was critical:
+ if (isSelfTestCriticalOnDemand(instanceName)) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_RUN_ON_DEMAND_FAILED",
+ instanceFullName));
+
+ // shutdown the system gracefully
+ CMS.shutdown();
+
+ return;
+ }
+ }
+ } else {
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+ }
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsOnDemand():"
+ + " EXITING.");
+ }
+ }
+
+ //
+ // methods associated with the list of startup self tests
+ //
+
+ /**
+ * List the instance names of all the self tests enabled to run
+ * at server startup (in execution order); may return null.
+ * <P>
+ *
+ * @return list of self test instance names run at server startup
+ */
+ public String[] listSelfTestsEnabledAtStartup() {
+ String[] mList;
+
+ int numElements = mStartupOrder.size();
+
+ if (numElements != 0) {
+ mList = new String[numElements];
+ } else {
+ return null;
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ int i = 0;
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ mList[i] = instance.getSelfTestName();
+ if (mList[i] != null) {
+ mList[i] = mList[i].trim();
+ }
+ i++;
+ }
+
+ return mList;
+ }
+
+ /**
+ * Enable the specified self test at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void enableSelfTestAtStartup(String instanceName,
+ boolean isCritical)
+ throws EInvalidSelfTestException, EMissingSelfTestException {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ instance.setSelfTestCriticalMode(isCritical);
+ return;
+ }
+ }
+
+ // append a new element to the startup ordered list
+ String elementName = null;
+
+ if (isCritical) {
+ elementName = instanceName
+ + ELEMENT_DELIMITER
+ + CRITICAL;
+ } else {
+ elementName = instanceName;
+ }
+
+ SelfTestOrderedInstance element;
+
+ element = new SelfTestOrderedInstance(elementName);
+
+ // SANITY CHECK: find the corresponding instance property
+ // name for this self test plugin
+ checkInstance(element);
+
+ // store this self test plugin in startup order
+ mStartupOrder.add(element);
+ }
+
+ /**
+ * Disable the specified self test at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public void disableSelfTestAtStartup(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ mStartupOrder.remove(instance);
+ return;
+ }
+ }
+
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+
+ /**
+ * Determine if the specified self test is executed automatically
+ * at server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if the specified self test is executed at server startup
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestEnabledAtStartup(String instanceName)
+ throws EMissingSelfTestException {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if failure of the specified self test is fatal to
+ * server startup.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return true if failure of the specified self test is fatal to
+ * server startup
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public boolean isSelfTestCriticalAtStartup(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ if (instance.isSelfTestCritical()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+
+ /**
+ * Execute all self tests specified to be run at server startup.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION used when self
+ * tests are run at server startup
+ * </ul>
+ * @exception EMissingSelfTestException subsystem has missing name
+ * @exception ESelfTestException self test exception
+ */
+ public void runSelfTestsAtStartup()
+ throws EMissingSelfTestException, ESelfTestException {
+ String auditMessage = null;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
+ + " ENTERING . . .");
+ }
+
+ // loop through all self test plugin instances
+ // specified to be executed at server startup
+ Enumeration instances = mStartupOrder.elements();
+
+ while (instances.hasMoreElements()) {
+ SelfTestOrderedInstance instance = (SelfTestOrderedInstance)
+ instances.nextElement();
+
+ String instanceFullName = null;
+ String instanceName = instance.getSelfTestName();
+
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ throw new EMissingSelfTestException();
+ }
+
+ if (mSelfTestInstances.containsKey(instanceName)) {
+ ISelfTest test = (ISelfTest)
+ mSelfTestInstances.get(instanceName);
+
+ try {
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
+ + " running \""
+ + test.getSelfTestName()
+ + "\"");
+ }
+
+ test.runSelfTest(mLogger);
+ } catch (ESelfTestException e) {
+ // Check to see if the self test was critical:
+ if (isSelfTestCriticalAtStartup(instanceName)) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_RUN_AT_STARTUP_FAILED",
+ instanceFullName));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // shutdown the system gracefully
+ CMS.shutdown();
+
+ return;
+ }
+ }
+ } else {
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ throw new EMissingSelfTestException(instanceFullName);
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.SUCCESS);
+
+ audit(auditMessage);
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
+ + " EXITING.");
+ }
+ } catch (EMissingSelfTestException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (ESelfTestException eAudit2) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+ ILogger.SYSTEM_UID,
+ ILogger.FAILURE);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ }
+ }
+
+ public void log(int level, String msg) {
+ }
+
+ //
+ // methods associated with the list of self test instances
+ //
+
+ /**
+ * Retrieve an individual self test from the instances list
+ * given its instance name. This method may return null.
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @return individual self test
+ */
+ public ISelfTest getSelfTest(String instanceName) {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ } else {
+ return null;
+ }
+
+ // loop through all self test plugin instances
+ Enumeration instances = mSelfTestInstances.elements();
+
+ while (instances.hasMoreElements()) {
+ ISelfTest instance = (ISelfTest) instances.nextElement();
+
+ if (instanceName.equals(instance.getSelfTestName())) {
+ return instance;
+ }
+ }
+
+ return null;
+ }
+
+ //
+ // methods associated with multiple self test lists
+ //
+
+ /**
+ * Returns the ILogEventListener of this subsystem.
+ * This method may return null.
+ * <P>
+ *
+ * @return ILogEventListener of this subsystem
+ */
+ public ILogEventListener getSelfTestLogger() {
+ return mLogger;
+ }
+
+ /**
+ * This method represents the log interface for the self test subsystem.
+ * <P>
+ *
+ * @param logger log event listener
+ * @param msg self test log message
+ */
+ public void log(ILogEventListener logger, String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (logger != null) {
+ // log the message to the "selftests.log" log
+ AuditEvent ev = new AuditEvent(msg);
+
+ ev.setSource(ILogger.S_OTHER);
+ ev.setLevel(ILogger.LL_INFO);
+ try {
+ logger.log(ev);
+ } catch( ELogException le ) {
+ // log the message to the "transactions" log
+ mErrorLogger.log(ILogger.EV_AUDIT,
+ null,
+ ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ msg + " - " + le.toString() );
+ }
+ } else {
+ // log the message to the "transactions" log
+ mErrorLogger.log(ILogger.EV_AUDIT,
+ null,
+ ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ msg);
+ }
+ }
+
+ /**
+ * Register an individual self test on the instances list AND
+ * on the "on demand" list (note that the specified self test
+ * will be appended to the end of each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @param instance individual self test
+ * @exception EDuplicateSelfTestException subsystem has duplicate name
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void registerSelfTestOnDemand(String instanceName,
+ boolean isCritical,
+ ISelfTest instance)
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ if (mSelfTestInstances.containsKey(instanceName)) {
+ // self test plugin instance property name is a duplicate
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME",
+ instanceFullName));
+
+ throw new EDuplicateSelfTestException(instanceFullName);
+ } else {
+ // append this self test plugin instance to the end of the list
+ mSelfTestInstances.put(instanceName, instance);
+ }
+
+ // register the individual self test on the "on demand" list
+ enableSelfTestOnDemand(instanceName, isCritical);
+ }
+
+ /**
+ * Deregister an individual self test on the instances list AND
+ * on the "on demand" list (note that the specified self test
+ * will be removed from each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public void deregisterSelfTestOnDemand(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // deregister the individual self test from the instances list
+ ISelfTest test = getSelfTest(instanceName);
+
+ if (test == null) {
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ } else {
+ // append this self test plugin instance to the end of the list
+ mSelfTestInstances.remove(instanceName);
+ }
+
+ // deregister the individual self test from the "on demand" list
+ disableSelfTestOnDemand(instanceName);
+ }
+
+ /**
+ * Register an individual self test on the instances list AND
+ * on the "startup" list (note that the specified self test
+ * will be appended to the end of each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @param isCritical isCritical is either a critical failure (true) or
+ * a non-critical failure (false)
+ * @param instance individual self test
+ * @exception EDuplicateSelfTestException subsystem has duplicate name
+ * @exception EInvalidSelfTestException subsystem has invalid name/value
+ * @exception EMissingSelfTestException subsystem has missing name/value
+ */
+ public void registerSelfTestAtStartup(String instanceName,
+ boolean isCritical,
+ ISelfTest instance)
+ throws EDuplicateSelfTestException,
+ EInvalidSelfTestException,
+ EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ if (mSelfTestInstances.containsKey(instanceName)) {
+ // self test plugin instance property name is a duplicate
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME",
+ instanceFullName));
+
+ throw new EDuplicateSelfTestException(instanceFullName);
+ } else {
+ // append this self test plugin instance to the end of the list
+ mSelfTestInstances.put(instanceName, instance);
+ }
+
+ // register the individual self test on the "startup" list
+ enableSelfTestAtStartup(instanceName, isCritical);
+ }
+
+ /**
+ * Deregister an individual self test on the instances list AND
+ * on the "startup" list (note that the specified self test
+ * will be removed from each list).
+ * <P>
+ *
+ * @param instanceName instance name of self test
+ * @exception EMissingSelfTestException subsystem has missing name
+ */
+ public void deregisterSelfTestAtStartup(String instanceName)
+ throws EMissingSelfTestException {
+ String instanceFullName = null;
+
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ // deregister the individual self test from the instances list
+ ISelfTest test = getSelfTest(instanceName);
+
+ if (test == null) {
+ // self test plugin instance property name is not present
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+ instanceFullName));
+
+ throw new EMissingSelfTestException(instanceFullName);
+ } else {
+ // append this self test plugin instance to the end of the list
+ mSelfTestInstances.remove(instanceName);
+ }
+
+ // deregister the individual self test from the "startup" list
+ disableSelfTestAtStartup(instanceName);
+ }
+
+ ////////////////////////
+ // ISubsystem methods //
+ ////////////////////////
+
+ /**
+ * This method retrieves the name of this subsystem. This method
+ * may return null.
+ * <P>
+ *
+ * @return identification of this subsystem
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * This method sets information specific to this subsystem.
+ * <P>
+ *
+ * @param id identification of this subsystem
+ * @exception EBaseException base CMS exception
+ */
+ public void setId(String id)
+ throws EBaseException {
+ // strip preceding/trailing whitespace
+ // from passed-in String parameters
+ if (id != null) {
+ id = id.trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EBaseException("id is null");
+ }
+
+ // nothing needs to be done
+ }
+
+ /**
+ * This method initializes this subsystem.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException base CMS exception
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " ENTERING . . .");
+ }
+
+ if( config == null ) {
+ CMS.debug( "SelfTestSubsystem::init() - config is null!" );
+ throw new EBaseException( "config is null" );
+ }
+
+ mOwner = owner;
+ mConfig = config;
+
+ if ((mConfig != null) &&
+ (mConfig.getName() != null) &&
+ (mConfig.getName() != "")) {
+ mRootPrefix = mConfig.getName().trim();
+ }
+
+ int loadStatus = 0;
+
+ // NOTE: Obviously, we must load the self test logger parameters
+ // first, since the "selftests.log" log file does not
+ // exist until this is accomplished!!!
+
+ ////////////////////////////////////
+ // loggerPropertyName=loggerValue //
+ ////////////////////////////////////
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " loading self test logger parameters");
+ }
+
+ String loggerPrefix = null;
+ String loggerFullName = null;
+ String loggerName = PROP_LOGGER_CLASS;
+ String loggerValue = null;
+
+ // compose self test plugins logger property prefix
+ String loggerPath = PROP_CONTAINER + "." + PROP_LOGGER;
+ IConfigStore loggerConfig = mConfig.getSubStore(loggerPath);
+
+ if ((loggerConfig != null) &&
+ (loggerConfig.getName() != null) &&
+ (loggerConfig.getName() != "")) {
+ loggerPrefix = loggerConfig.getName().trim();
+ } else {
+ // NOTE: These messages can only be logged to the "transactions"
+ // log, since the "selftests.log" will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ Enumeration loggerInstances = loggerConfig.getPropertyNames();
+
+ if (loggerInstances.hasMoreElements()) {
+ loadStatus++;
+
+ try {
+ loggerFullName = getFullName(loggerPrefix,
+ loggerName);
+
+ // retrieve the associated logger class
+ loggerValue = loggerConfig.getString(loggerName);
+ if (loggerValue != null) {
+ loggerValue = loggerValue.trim();
+ } else {
+ // self test plugin instance property name exists,
+ // but it contains no value(s)
+
+ // NOTE: This message can only be logged to the
+ // "transactions" log, since the "selftests.log"
+ // will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_VALUES",
+ loggerFullName));
+
+ throw new
+ EMissingSelfTestException(loggerFullName,
+ loggerValue);
+ }
+
+ Object o = Class.forName(loggerValue).newInstance();
+
+ if (!(o instanceof ILogEventListener)) {
+ // NOTE: These messages can only be logged to the
+ // "transactions" log, since the "selftests.log"
+ // will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_INVALID_INSTANCE",
+ loggerFullName,
+ loggerValue));
+
+ throw new EInvalidSelfTestException(loggerFullName,
+ loggerValue);
+ }
+
+ // initialize the self tests logger
+ mLogger = (ILogEventListener) o;
+ mLogger.init(this, loggerConfig);
+ } catch (EBaseException e) {
+ // self test property name EBaseException
+
+ // NOTE: These messages can only be logged to the
+ // "transactions" log, since the "selftests.log"
+ // will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
+ loggerFullName,
+ loggerValue));
+
+ throw new EInvalidSelfTestException(loggerFullName,
+ loggerValue);
+ } catch (Exception e) {
+ // NOTE: These messages can only be logged to the
+ // "transactions" log, since the "selftests.log"
+ // will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EXCEPTION",
+ loggerFullName,
+ loggerValue));
+
+ CMS.debugStackTrace();
+
+ throw new EInvalidSelfTestException(loggerFullName,
+ loggerValue);
+ }
+ }
+
+ // Barring any exceptions thrown above, we begin logging messages
+ // to either the "transactions" log, or the "selftests.log" log.
+ if (loadStatus == 0) {
+ // NOTE: These messages can only be logged to the
+ // "transactions" log, since the "selftests.log"
+ // will not exist!
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_DONT_LOAD_LOGGER_PARAMETERS"));
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_LOAD_LOGGER_PARAMETERS"));
+ }
+
+ ////////////////////////////////////////
+ // instancePropertyName=instanceValue //
+ ////////////////////////////////////////
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " loading self test plugins");
+ }
+
+ // compose self test plugins instance property prefix
+ String instancePath = PROP_CONTAINER + "." + PROP_INSTANCE;
+ IConfigStore instanceConfig = mConfig.getSubStore(instancePath);
+
+ if ((instanceConfig != null) &&
+ (instanceConfig.getName() != null) &&
+ (instanceConfig.getName() != "")) {
+ mPrefix = instanceConfig.getName().trim();
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ Enumeration instances = instanceConfig.getPropertyNames();
+
+ if (instances.hasMoreElements()) {
+ loadStatus++;
+
+ log(mLogger,
+ CMS.getLogMessage("CMSCORE_SELFTESTS_LOAD_PLUGINS"));
+ } else {
+ log(mLogger,
+ CMS.getLogMessage("CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS"));
+ }
+
+ // load all self test plugin instances
+ String instanceFullName = null;
+ String instanceName = null;
+ String instanceValue = null;
+ boolean first_time = true;
+
+ while (instances.hasMoreElements()) {
+ // the instance property name should be unique
+ instanceName = (String) instances.nextElement();
+ if (instanceName != null) {
+ instanceName = instanceName.trim();
+ instanceFullName = getFullName(mPrefix,
+ instanceName);
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+
+ throw new EMissingSelfTestException();
+ }
+
+ if (mSelfTestInstances.containsKey(instanceName)) {
+ // self test plugin instance property name is a duplicate
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME",
+ instanceFullName));
+
+ throw new EDuplicateSelfTestException(instanceFullName);
+ }
+
+ // an associated instance property value, a class, must exist
+ try {
+ instanceValue = instanceConfig.getString(instanceName);
+ if (instanceValue != null) {
+ instanceValue = instanceValue.trim();
+ } else {
+ // self test plugin instance property name exists,
+ // but it contains no value(s)
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_MISSING_VALUES",
+ instanceFullName));
+
+ throw new
+ EMissingSelfTestException(instanceFullName,
+ instanceValue);
+ }
+ } catch (EBaseException e) {
+ // self test property name EBaseException
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
+ instanceFullName,
+ instanceValue));
+
+ throw new EInvalidSelfTestException(instanceFullName,
+ instanceValue);
+ }
+
+ // verify that the associated class is a valid instance of ISelfTest
+ Object o;
+
+ try {
+ o = Class.forName(instanceValue).newInstance();
+
+ if (!(o instanceof ISelfTest)) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_INVALID_INSTANCE",
+ instanceFullName,
+ instanceValue));
+
+ throw new EInvalidSelfTestException(instanceFullName,
+ instanceValue);
+ }
+ } catch (Exception e) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EXCEPTION",
+ instanceFullName,
+ instanceValue));
+
+ CMS.debugStackTrace();
+
+ throw new EInvalidSelfTestException(instanceFullName,
+ instanceValue);
+ }
+
+ // retrieve all ISelfTest parameters associated with this class
+ try {
+ if (first_time) {
+ first_time = false;
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " loading self test plugin parameters");
+ }
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_LOAD_PLUGIN_PARAMETERS"));
+ }
+
+ ISelfTest test = (ISelfTest) o;
+
+ test.initSelfTest(this, instanceName, mConfig);
+
+ // store this self test plugin instance
+ mSelfTestInstances.put(instanceName, test);
+ } catch (EDuplicateSelfTestException e) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PLUGIN_DUPLICATE_PARAMETER",
+ instanceFullName,
+ e.getInstanceParameter()));
+
+ throw e;
+ } catch (EMissingSelfTestException e) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PLUGIN_MISSING_PARAMETER",
+ instanceFullName,
+ e.getInstanceParameter()));
+
+ throw e;
+ } catch (EInvalidSelfTestException e) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PLUGIN_INVALID_PARAMETER",
+ instanceFullName,
+ e.getInstanceParameter()));
+
+ throw e;
+ }
+ }
+
+ //////////////////////////////////////////////////////////
+ // onDemandOrderPropertyName=onDemandOrderValue1, . . . //
+ //////////////////////////////////////////////////////////
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " loading on demand self tests");
+ }
+
+ // compose self test plugins on-demand ordering property name
+ String onDemandOrderName = PROP_CONTAINER + "."
+ + PROP_ORDER + "."
+ + PROP_ON_DEMAND;
+ String onDemandOrderFullName = getFullName(mRootPrefix,
+ onDemandOrderName);
+ String onDemandOrderValues = null;
+
+ try {
+ // extract all self test plugins on-demand
+ // ordering property values
+ onDemandOrderValues = mConfig.getString(onDemandOrderName);
+ if (onDemandOrderValues != null) {
+ onDemandOrderValues = onDemandOrderValues.trim();
+ }
+
+ loadStatus++;
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_LOAD_PLUGINS_ON_DEMAND"));
+
+ if ((onDemandOrderValues == null) ||
+ (onDemandOrderValues.equals(""))) {
+ // self test plugins on-demand ordering property name
+ // exists, but it contains no values, which means that
+ // no self tests are configured to run on-demand
+ if( ( onDemandOrderFullName != null ) &&
+ ( !onDemandOrderFullName.equals( "" ) ) ) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_MISSING_ON_DEMAND_VALUES",
+ onDemandOrderFullName));
+ }
+ throw new EBaseException( "onDemandOrderValues is null "
+ + "or empty" );
+ }
+
+ StringTokenizer tokens = new StringTokenizer(onDemandOrderValues,
+ LIST_DELIMITER);
+
+ while (tokens.hasMoreTokens()) {
+ // create a new element in the on-demand ordered list
+ SelfTestOrderedInstance element;
+
+ element = new SelfTestOrderedInstance(
+ tokens.nextToken().trim());
+
+ // SANITY CHECK: find the corresponding instance property
+ // name for this self test plugin
+ checkInstance(element);
+
+ // store this self test plugin in on-demand order
+ mOnDemandOrder.add(element);
+ }
+
+ } catch (EPropertyNotFound e) {
+ // self test plugins on-demand ordering property name
+ // is not present
+
+ // presently, we merely log this fact
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS_ON_DEMAND"));
+
+ // throw new EMissingSelfTestException( onDemandOrderFullName );
+ } catch (EBaseException e) {
+ // self test property name EBaseException
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
+ onDemandOrderFullName,
+ onDemandOrderValues));
+
+ throw new EInvalidSelfTestException(onDemandOrderFullName,
+ onDemandOrderValues);
+ }
+
+ ////////////////////////////////////////////////////////
+ // startupOrderPropertyName=startupOrderValue1, . . . //
+ ////////////////////////////////////////////////////////
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " loading startup self tests");
+ }
+
+ // compose self test plugins startup ordering property name
+ String startupOrderName = PROP_CONTAINER + "."
+ + PROP_ORDER + "."
+ + PROP_STARTUP;
+ String startupOrderFullName = getFullName(mRootPrefix,
+ startupOrderName);
+ String startupOrderValues = null;
+
+ try {
+ // extract all self test plugins startup ordering
+ // property values
+ startupOrderValues = mConfig.getString(startupOrderName);
+ if (startupOrderValues != null) {
+ startupOrderValues = startupOrderValues.trim();
+ }
+
+ loadStatus++;
+
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_LOAD_PLUGINS_AT_STARTUP"));
+
+ if ((startupOrderValues == null) ||
+ (startupOrderValues.equals(""))) {
+ // self test plugins startup ordering property name
+ // exists, but it contains no values, which means that
+ // no self tests are configured to run at server startup
+ if( ( startupOrderFullName != null ) &&
+ ( !startupOrderFullName.equals( "" ) ) ) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_MISSING_STARTUP_VALUES",
+ startupOrderFullName));
+ }
+ }
+
+ StringTokenizer tokens = new StringTokenizer(startupOrderValues,
+ LIST_DELIMITER);
+
+ while (tokens.hasMoreTokens()) {
+ // create a new element in the startup ordered list
+ SelfTestOrderedInstance element;
+
+ element = new SelfTestOrderedInstance(
+ tokens.nextToken().trim());
+
+ // SANITY CHECK: find the corresponding instance property
+ // name for this self test plugin
+ checkInstance(element);
+
+ // store this self test plugin in startup order
+ mStartupOrder.add(element);
+ }
+
+ } catch (EPropertyNotFound e) {
+ // self test plugins startup ordering property name is
+ // not present
+
+ // presently, we merely log this fact
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_DONT_LOAD_PLUGINS_AT_STARTUP"));
+
+ // throw new EMissingSelfTestException( startupOrderFullName );
+ } catch (EBaseException e) {
+ // self test property name EBaseException
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
+ startupOrderFullName,
+ startupOrderValues));
+
+ throw new EInvalidSelfTestException(startupOrderFullName,
+ startupOrderValues);
+ }
+
+ // notify user whether or not self test plugins have been loaded
+ if (loadStatus == 0) {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PLUGINS_NONE_LOADED"));
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_PLUGINS_LOADED"));
+ }
+
+ if (CMS.debugOn()) {
+ CMS.debug("SelfTestSubsystem::init():"
+ + " EXITING.");
+ }
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ * <P>
+ *
+ * @exception EBaseException base CMS exception
+ */
+ public void startup()
+ throws EBaseException {
+ // loop through all self test plugin instances
+ Enumeration instances = mSelfTestInstances.elements();
+
+ while (instances.hasMoreElements()) {
+ ISelfTest instance = (ISelfTest) instances.nextElement();
+
+ instance.startupSelfTest();
+ }
+
+ if (!CMS.isPreOpMode()) {
+ // run all self test plugin instances (designated at startup)
+ Enumeration selftests = mStartupOrder.elements();
+
+ if (selftests.hasMoreElements()) {
+ // log that execution of startup self tests has begun
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_RUN_AT_STARTUP"));
+
+ // execute all startup self tests
+ runSelfTestsAtStartup();
+
+ // log that execution of all "critical" startup self tests
+ // has completed "successfully"
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_RUN_AT_STARTUP_SUCCEEDED"));
+ } else {
+ log(mLogger,
+ CMS.getLogMessage(
+ "CMSCORE_SELFTESTS_NOT_RUN_AT_STARTUP"));
+ }
+ }
+ }
+
+ /**
+ * Stops this subsystem. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown() {
+ // reverse order of all self test plugin instances
+ Collection collection = mSelfTestInstances.values();
+ Vector list = new Vector(collection);
+
+ Collections.reverse(list);
+
+ // loop through all self test plugin instances
+ ListIterator instances = list.listIterator();
+
+ while (instances.hasNext()) {
+ ISelfTest instance = (ISelfTest) instances.next();
+
+ instance.shutdownSelfTest();
+ }
+ }
+
+ /**
+ * Returns the root configuration storage of this subsystem.
+ * This method may return null.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java b/pki/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java
new file mode 100644
index 000000000..0427d82d7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java
@@ -0,0 +1,30 @@
+// --- 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.cmscore.time;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+
+
+public class SimpleTimeSource implements ITimeSource {
+
+ public Date getCurrentDate() {
+ return new Date();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java b/pki/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java
new file mode 100644
index 000000000..f9312c1c4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java
@@ -0,0 +1,76 @@
+// --- 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.cmscore.usrgrp;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+
+
+/**
+ * This interface defines a strategy on how to match
+ * the incoming certificate(s) with the certificate(s)
+ * in the scope. It matches the "certdn" field which contains
+ * the subject dn of the certificate
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CertDNCertUserLocator implements ICertUserLocator {
+ private IUGSubsystem mUG = null;
+ protected static final String LDAP_ATTR_CERTDN = "seeAlso";
+
+ /**
+ * Constructs certificate matching agent.
+ */
+ public CertDNCertUserLocator() {
+ }
+
+ /**
+ * Retrieves description.
+ */
+ public String getDescription() {
+ return "A subject is authenticated if its first" +
+ " certificate can be matched with one of the" +
+ " certificate in the scope";
+ }
+
+ /**
+ * Do the cert-user mapping
+ */
+ public IUser locateUser(Certificates certs) throws
+ EUsrGrpException, LDAPException, ELdapException {
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ X509Certificate certificates[] = certs.getCertificates();
+
+ if (certificates == null)
+ return null;
+
+ String filter = LDAP_ATTR_CERTDN + "=" +
+ certificates[0].getSubjectDN();
+
+ return mUG.findUsersByCert(filter);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java b/pki/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java
new file mode 100644
index 000000000..0fb4d0d98
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java
@@ -0,0 +1,82 @@
+// --- 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.cmscore.usrgrp;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+
+
+/**
+ * This interface defines a strategy on how to match
+ * the incoming certificate(s) with the certificate(s)
+ * in the scope. It matches the "description" field which contains a
+ * stringied certificate.
+ *
+ * @author thomask
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class ExactMatchCertUserLocator implements ICertUserLocator {
+ private IUGSubsystem mUG = null;
+
+ /**
+ * Constructs certificate matching agent.
+ */
+ public ExactMatchCertUserLocator() {
+ }
+
+ /**
+ * Retrieves description.
+ */
+ public String getDescription() {
+ return "A subject is authenticated if its first" +
+ " certificate can be matched with one of the" +
+ " certificate in the scope";
+ }
+
+ /**
+ * Do the cert-user mapping
+ */
+ public IUser locateUser(Certificates certs) throws
+ EUsrGrpException, LDAPException, ELdapException {
+ mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ X509Certificate certificates[] = certs.getCertificates();
+
+ if (certificates == null)
+ return null;
+ int pos = 0;
+
+ if (certificates[0].getSubjectDN().toString().equals(
+ certificates[0].getIssuerDN().toString())) {
+ pos = certificates.length - 1;
+ }
+
+ String filter = "description=" +
+ mUG.getCertificateString(certificates[pos]);
+
+ return mUG.findUsersByCert(filter);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/usrgrp/Group.java b/pki/base/common/src/com/netscape/cmscore/usrgrp/Group.java
new file mode 100644
index 000000000..05aec23dc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/usrgrp/Group.java
@@ -0,0 +1,119 @@
+// --- 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.cmscore.usrgrp;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a group.
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class Group implements IGroup {
+ private IUsrGrp mBase = null;
+ private String mName = null;
+ private Vector mMembers = new Vector();
+ private String mDescription = null;
+
+ private static final Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_NAME);
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_DESCRIPTION);
+ mNames.addElement(ATTR_MEMBERS);
+ }
+
+ /**
+ * Constructs local group.
+ */
+ public Group(IUsrGrp base, String name) {
+ mBase = base;
+ mName = name;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getGroupID() {
+ return mName;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public void addMemberName(String name) {
+ mMembers.addElement(name);
+ }
+
+ public Enumeration getMemberNames() {
+ return mMembers.elements();
+ }
+
+ public boolean isMember(String name) {
+ for (int i = 0; i < mMembers.size(); i++) {
+ String id = (String) mMembers.elementAt(i);
+
+ if (name.equals(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void set(String name, Object object) throws EBaseException {
+ if (name.equals(ATTR_NAME)) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ } else if (name.equals(ATTR_ID)) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ } else if (name.equals(ATTR_MEMBERS)) {
+ mMembers = (Vector) object;
+ } else if (name.equals(ATTR_DESCRIPTION)) {
+ mDescription = (String) object;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public Object get(String name) throws EBaseException {
+ if (name.equals(ATTR_NAME)) {
+ return getName();
+ } else if (name.equals(ATTR_ID)) {
+ return getGroupID();
+ } else if (name.equals(ATTR_MEMBERS)) {
+ return mMembers;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java b/pki/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
new file mode 100644
index 000000000..d19cbf2d3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
@@ -0,0 +1,1747 @@
+// --- 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.cmscore.usrgrp;
+
+
+import java.util.*;
+import java.lang.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.ldap.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * This class defines low-level LDAP usr/grp management
+ * usr/grp information is located remotely on another
+ * LDAP server.
+ *
+ * @author thomask
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public final class UGSubsystem implements IUGSubsystem {
+
+ public static final String ID = "usrgrp";
+ private ICertUserLocator mCertUserLocator = null;
+ private String mId = ID;
+
+ protected static final String OBJECTCLASS_ATTR = "objectclass";
+ protected static final String MEMBER_ATTR = "uniquemember";
+ protected static final String GROUP_ATTR_VALUE = "groupofuniquenames";
+
+ protected static final String LDAP_ATTR_USER_CERT_STRING = "description";
+ // protected static final String LDAP_ATTR_CERTDN = "seeAlso";
+ protected static final String LDAP_ATTR_USER_CERT = "userCertificate";
+
+ protected static final String PROP_BASEDN = "basedn";
+
+ protected IConfigStore mConfig = null;
+ protected LdapBoundConnFactory mLdapConnFactory = null;
+ protected String mBaseDN = null;
+ protected static UGSubsystem mUG = null;
+ private static final String PROP_IMPL = "impl";
+ private static final String PROP_CLASS = "class";
+ private static final String PROP_PASSWORD_CHECKER = "PasswordChecker";
+
+ private ILogger mLogger = null;
+
+ // singleton enforcement
+
+ private static UGSubsystem mInstance = new UGSubsystem();
+
+ public static UGSubsystem getInstance() {
+ return mInstance;
+ }
+
+ // end singleton enforcement.
+
+ /**
+ * Constructs LDAP based usr/grp management
+ */
+ private UGSubsystem() {
+ }
+
+ /**
+ * Retrieves identifier of this scope.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Sets identifier of this manager
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Connects to LDAP server.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mLogger = CMS.getLogger();
+ mConfig = config;
+
+ // initialize LDAP connection factory
+ try {
+ IConfigStore ldapConfig = mConfig.getSubStore("ldap");
+
+ mBaseDN = ldapConfig.getString(PROP_BASEDN, null);
+
+ mLdapConnFactory = new LdapBoundConnFactory();
+ mLdapConnFactory.init(ldapConfig);
+ IConfigStore c = config.getSubStore(PROP_IMPL);
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+ }
+
+ /**
+ * Starts up this service.
+ */
+ public void startup() throws EBaseException {
+ // register admin servlet
+
+ }
+
+ /**
+ * Disconnects usr/grp manager from the LDAP
+ */
+ public void shutdown() {
+ try {
+ if (mLdapConnFactory != null) {
+ mLdapConnFactory.reset();
+ mLdapConnFactory = null;
+ }
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LDAP_SHUT", e.toString()));
+ }
+ }
+
+ public IUser createUser(String id) {
+ return new User(this, id);
+ }
+
+ public IGroup createGroup(String id) {
+ return new Group(this, id);
+ }
+
+ /**
+ * Retrieves configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves the description of this scope.
+ */
+ public String getDescription() {
+ return "User/Group Manager";
+ }
+
+ /**
+ * Retrieves a user from LDAP
+ */
+ public IUser getUser(String userid) throws EUsrGrpException {
+ if (userid == null) {
+ return null;
+ }
+
+ try {
+ if (userid.indexOf('=') == -1) {
+ Enumeration e = findUsers(userid);
+
+ if (e != null && e.hasMoreElements()) {
+ IUser u = (IUser) e.nextElement();
+
+ return u;
+ } else {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_USER_NOT_FOUND"));
+ }
+ } else {
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ // read DN
+ LDAPSearchResults res =
+ ldapconn.search(userid,
+ LDAPv2.SCOPE_SUB, "(objectclass=*)", null, false);
+ Enumeration e = buildUsers(res);
+
+ if (e.hasMoreElements()) {
+ return (IUser) e.nextElement();
+ }
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_GET_USER", e.toString()));
+ // throws...
+ }
+ return null;
+ }
+
+ /**
+ * Locates a user by certificate.
+ */
+ public User findUser(X509Certificate cert) throws EUsrGrpException {
+ if (cert == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ String filter = LDAP_ATTR_USER_CERT_STRING + "=" + getCertificateString(cert);
+ LDAPSearchResults res =
+ ldapconn.search(getUserBaseDN(),
+ LDAPConnection.SCOPE_SUB, filter, null, false);
+ Enumeration e = buildUsers(res);
+
+ return (User) e.nextElement();
+ } catch (LDAPException e) {
+ String errMsg = "findUser()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findUser: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USER", e.toString()));
+ } catch (ELdapException e) {
+ String errMsg =
+ "find User: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_INTERNAL_DB", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return null;
+ }
+
+ /**
+ * Searchs for identities that matches the certificate locater
+ * generated filter.
+ */
+ public IUser findUsersByCert(String filter) throws
+ EUsrGrpException, LDAPException {
+ if (filter == null) {
+ return null;
+ }
+
+ // To handle \ in the issuer DN or subject DN
+ // (see also RFC 2254, and bug #348303
+ int hasSlash = filter.indexOf('\\');
+
+ if (hasSlash != -1) {
+ String up = filter;
+ String stripped = "";
+
+ hasSlash = up.indexOf('\\');
+ while (hasSlash != -1) {
+ stripped += up.substring(0, hasSlash) +
+ "\\5c";;
+ up = up.substring(hasSlash + 1);
+ hasSlash = up.indexOf('\\');
+ }
+ filter = stripped + up;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ LDAPSearchResults res = ldapconn.search(getUserBaseDN(),
+ LDAPv2.SCOPE_SUB, "(" + filter + ")",
+ null, false);
+
+ Enumeration e = buildUsers(res);
+
+ return (User) e.nextElement();
+ } catch (LDAPException e) {
+ String errMsg = "findUsersByCert()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findUsersByCert: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USER_BY_CERT", e.toString()));
+ } catch (ELdapException e) {
+ String errMsg =
+ "find Users By Cert: " +
+ "Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USER_BY_CERT", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+
+ return null;
+ }
+
+ /**
+ * Searchs for identities that matches the filter.
+ */
+ public Enumeration findUsers(String filter) throws EUsrGrpException {
+ if (filter == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ LDAPSearchResults res = ldapconn.search(getUserBaseDN(),
+ LDAPv2.SCOPE_SUB, "(uid=" + filter + ")",
+ null, false);
+
+ Enumeration e = buildUsers(res);
+
+ return e;
+ } catch (LDAPException e) {
+ String errMsg = "findUsers()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findUsersByCert: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USERS", e.toString()));
+ } catch (ELdapException e) {
+ String errMsg =
+ "find Users: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USERS", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+
+ return null;
+ }
+
+ /**
+ * Searchs for identities that matches the filter.
+ * retrieves uid only, for efficiency of user listing
+ */
+ public Enumeration listUsers(String filter) throws EUsrGrpException {
+ if (filter == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ String attrs[] = new String[2];
+
+ attrs[0] = "uid";
+ attrs[1] = "cn";
+
+ ldapconn = getConn();
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(0);
+ LDAPSearchResults res = ldapconn.search(getUserBaseDN(),
+ LDAPv2.SCOPE_SUB, "(uid=" + filter + ")", attrs, false, cons);
+ Enumeration e = lbuildUsers(res);
+
+ return e;
+ } catch (LDAPException e) {
+ String errMsg = "listUsers()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findUsersByCert: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_USERS", e.toString()));
+ } catch (Exception e) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_INTERNAL_ERROR"));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+
+ return null;
+ }
+
+ protected Enumeration lbuildUsers(LDAPSearchResults res) throws
+ EUsrGrpException {
+ Vector v = new Vector();
+
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ IUser user = lbuildUser(entry);
+
+ v.addElement(user);
+ }
+ return v.elements();
+ }
+
+ protected Enumeration buildUsers(LDAPSearchResults res) throws
+ EUsrGrpException {
+ Vector v = new Vector();
+
+ if (res != null) {
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ IUser user = buildUser(entry);
+
+ v.addElement(user);
+ }
+ }
+
+ // if v contains nothing, just throw exception
+ if (v.size() == 0) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_USER_NOT_FOUND"));
+ }
+
+ return v.elements();
+ }
+
+ /**
+ * builds a User instance. Sets only uid for user entry retrieved
+ * from LDAP server. for listing efficiency only.
+ * @return the User entity.
+ */
+ protected IUser lbuildUser(LDAPEntry entry) throws EUsrGrpException {
+ IUser id = createUser(this, (String)
+ entry.getAttribute("uid").getStringValues().nextElement());
+ LDAPAttribute cnAttr = entry.getAttribute("cn");
+
+ if (cnAttr != null) {
+ String cn = (String) cnAttr.getStringValues().nextElement();
+
+ if (cn != null) {
+ id.setFullName(cn);
+ }
+
+ }
+
+ LDAPAttribute certAttr =
+ entry.getAttribute(LDAP_ATTR_USER_CERT);
+
+ if (certAttr != null) {
+ Vector certVector = new Vector();
+ Enumeration e = certAttr.getByteValues();
+
+ try {
+ for (; e != null && e.hasMoreElements();) {
+ X509Certificate cert = new X509CertImpl(
+ (byte[]) e.nextElement());
+
+ certVector.addElement(cert);
+ }
+ } catch (Exception ex) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_INTERNAL_ERROR"));
+ }
+
+ if (certVector != null && certVector.size() != 0) {
+ // Make an array of certs
+ X509Certificate[] certArray = new X509Certificate[certVector.size()];
+ Enumeration en = certVector.elements();
+ int i = 0;
+
+ while (en.hasMoreElements()) {
+ certArray[i++] = (X509Certificate)
+ en.nextElement();
+ }
+
+ id.setX509Certificates(certArray);
+ }
+ }
+
+ return id;
+ }
+
+ /**
+ * builds a User instance. Set all attributes retrieved from
+ * LDAP server and set them on User.
+ * @return the User entity.
+ */
+ protected IUser buildUser(LDAPEntry entry) throws EUsrGrpException {
+ IUser id = createUser(this, (String)
+ entry.getAttribute("uid").getStringValues().nextElement());
+ LDAPAttribute cnAttr = entry.getAttribute("cn");
+
+ if (cnAttr != null) {
+ String cn = (String) cnAttr.getStringValues().nextElement();
+
+ if (cn != null) {
+ id.setFullName(cn);
+ }
+ }
+
+ String userdn = entry.getDN();
+
+ if (userdn != null) {
+ id.setUserDN(userdn);
+ } else { // the impossible
+ String errMsg = "buildUser(): user DN not found: " +
+ userdn;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_BUILD_USER"));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_INTERNAL_ERROR"));
+ }
+
+ /*
+ LDAPAttribute certdnAttr = entry.getAttribute(LDAP_ATTR_CERTDN);
+ if (certdnAttr != null) {
+ String cdn = (String)certdnAttr.getStringValues().nextElement();
+ if (cdn != null) {
+ id.setCertDN(cdn);
+ }
+ }
+ */
+ LDAPAttribute mailAttr = entry.getAttribute("mail");
+
+ if (mailAttr != null) {
+ Enumeration en = mailAttr.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String mail = (String) en.nextElement();
+
+ if (mail != null) {
+ id.setEmail(mail);
+ }
+ }
+ }
+ if (id.getEmail() == null) {
+ id.setEmail(""); // safety net
+ }
+
+ LDAPAttribute pwdAttr = entry.getAttribute("userpassword");
+
+ if (pwdAttr != null) {
+ String pwd = (String) pwdAttr.getStringValues().nextElement();
+
+ if (pwd != null) {
+ id.setPassword(pwd);
+ }
+ }
+ LDAPAttribute phoneAttr = entry.getAttribute("telephonenumber");
+
+ if (phoneAttr != null) {
+ Enumeration en = phoneAttr.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String phone = (String) en.nextElement();
+
+ if (phone != null) {
+ id.setPhone(phone);
+ }
+ }
+ }
+ if (id.getPhone() == null) {
+ id.setPhone(""); // safety net
+ }
+
+ LDAPAttribute userTypeAttr = entry.getAttribute("usertype");
+
+ if (userTypeAttr == null)
+ id.setUserType("");
+ else {
+ Enumeration en = userTypeAttr.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String userType = (String) en.nextElement();
+
+ if ((userType != null) && (! userType.equals("undefined")))
+ id.setUserType(userType);
+ else
+ id.setUserType("");
+
+ }
+ }
+
+ LDAPAttribute userStateAttr = entry.getAttribute("userstate");
+
+ if (userStateAttr == null)
+ id.setState("");
+ else {
+ Enumeration en = userStateAttr.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String userState = (String) en.nextElement();
+
+ if (userState != null)
+ id.setState(userState);
+ else
+ id.setState("");
+
+ }
+ }
+
+ LDAPAttribute certAttr =
+ entry.getAttribute(LDAP_ATTR_USER_CERT);
+
+ if (certAttr != null) {
+ Vector certVector = new Vector();
+ Enumeration e = certAttr.getByteValues();
+
+ try {
+ for (; e != null && e.hasMoreElements();) {
+ X509Certificate cert = new X509CertImpl(
+ (byte[]) e.nextElement());
+
+ certVector.addElement(cert);
+ }
+ } catch (Exception ex) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_INTERNAL_ERROR"));
+ }
+
+ if (certVector != null && certVector.size() != 0) {
+ // Make an array of certs
+ X509Certificate[] certArray = new X509Certificate[certVector.size()];
+ Enumeration en = certVector.elements();
+ int i = 0;
+
+ while (en.hasMoreElements()) {
+ certArray[i++] = (X509Certificate)
+ en.nextElement();
+ }
+
+ id.setX509Certificates(certArray);
+ }
+ }
+
+ return id;
+ }
+
+ protected IUser createUser(IUsrGrp base, String id) {
+ return new User(base, id);
+ }
+
+ /**
+ * Adds identity. Certificates handled by a separate call to
+ * addUserCert()
+ */
+ public void addUser(IUser identity) throws EUsrGrpException, LDAPException {
+ User id = (User) identity;
+
+ if (id == null) {
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_USER_FAIL"));
+ }
+
+ if (id.getUserID() == null) {
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_USER_FAIL_NO_UID"));
+ }
+
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc[] = {"top", "person", "organizationalPerson",
+ "inetOrgPerson", "cmsuser" };
+
+ attrs.add(new LDAPAttribute("objectclass", oc));
+ attrs.add(new LDAPAttribute("uid", id.getUserID()));
+ attrs.add(new LDAPAttribute("sn", id.getFullName()));
+ attrs.add(new LDAPAttribute("cn", id.getFullName()));
+ attrs.add(new LDAPAttribute("mail", id.getEmail()));
+
+ if (id.getPhone() != null) {
+ // DS syntax checking requires a value for PrintableString syntax
+ if (! id.getPhone().equals("")) {
+ attrs.add(new LDAPAttribute("telephonenumber", id.getPhone()));
+ }
+ }
+
+ attrs.add(new LDAPAttribute("userpassword",
+ id.getPassword()));
+
+ if (id.getUserType() != null) {
+ // DS syntax checking requires a value for Directory String syntax
+ // but usertype is a MUST attribute, so we need to add something here
+ // if it is undefined.
+
+ if (! id.getUserType().equals("")) {
+ attrs.add(new LDAPAttribute("usertype", id.getUserType()));
+ } else {
+ attrs.add(new LDAPAttribute("usertype", "undefined"));
+ }
+ }
+
+ if (id.getState() != null) {
+ // DS syntax checking requires a value for Directory String syntax
+ if (! id.getState().equals("")) {
+ attrs.add(new LDAPAttribute("userstate", id.getState()));
+ }
+ }
+
+ LDAPEntry entry = new LDAPEntry("uid=" + id.getUserID() +
+ "," + getUserBaseDN(), attrs);
+ // for audit log
+ SessionContext sessionContext = SessionContext.getContext();
+ String adminId = (String) sessionContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERFORMAT,
+ new Object[] {adminId, id.getUserID()}
+ );
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ ldapconn.add(entry);
+ } catch (ELdapException e) {
+ String errMsg =
+ "add User: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ /**
+ * adds a user certificate to user
+ */
+ public void addUserCert(IUser identity) throws EUsrGrpException,
+ LDAPException {
+ User user = (User) identity;
+
+ if (user == null) {
+ return;
+ }
+
+ X509Certificate cert[] = null;
+ LDAPModificationSet addCert = new LDAPModificationSet();
+
+ if ((cert = user.getX509Certificates()) != null) {
+ LDAPAttribute attrCertStr = new
+ LDAPAttribute(LDAP_ATTR_USER_CERT_STRING);
+
+ /*
+ LDAPAttribute attrCertDNStr = new
+ LDAPAttribute(LDAP_ATTR_CERTDN);
+ */
+ LDAPAttribute attrCertBin = new
+ LDAPAttribute(LDAP_ATTR_USER_CERT);
+
+ try {
+ attrCertBin.addValue(cert[0].getEncoded());
+ attrCertStr.addValue(getCertificateString(cert[0]));
+ // attrCertDNStr.addValue(cert[0].getSubjectDN().toString());
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER_CERT", e.toString()));
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_USR_CERT_ERROR"));
+ }
+
+ addCert.add(LDAPModification.ADD, attrCertStr);
+ //addCert.add(LDAPModification.ADD, attrCertDNStr);
+ addCert.add(LDAPModification.ADD, attrCertBin);
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ ldapconn.modify("uid=" + user.getUserID() +
+ "," + getUserBaseDN(), addCert);
+ // for audit log
+ SessionContext sessionContext = SessionContext.getContext();
+ String adminId = (String) sessionContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERCERTFORMAT,
+ new Object[] {adminId, user.getUserID(),
+ cert[0].getSubjectDN().toString(),
+ cert[0].getSerialNumber().toString(16)}
+ );
+
+ } catch (LDAPException e) {
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ String errMsg = "addUserCert():" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findUsersByCert: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ throw e;
+ } catch (ELdapException e) {
+ String errMsg =
+ "add User Cert: " +
+ "Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Removes a user certificate for a user entry
+ * given a user certificate DN (actually, a combination of version,
+ * serialNumber, issuerDN, and SubjectDN), and it gets removed
+ */
+ public void removeUserCert(IUser identity) throws EUsrGrpException {
+ User user = (User) identity;
+ User ldapUser = null;
+
+ if (user == null) {
+ return;
+ }
+
+ // retrieve all certs of the user, then match the cert String for
+ // removal
+ ldapUser = (User) getUser(user.getUserID());
+
+ if (ldapUser == null) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_USER_NOT_FOUND"));
+ }
+
+ X509Certificate[] certs = ldapUser.getX509Certificates();
+
+ if (certs == null) {
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_CERT_NOT_FOUND"));
+ }
+
+ String delCertdn = user.getCertDN();
+
+ if (delCertdn == null) {
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_CERT_NOT_FOUND"));
+ }
+
+ LDAPAttribute certAttr = new
+ LDAPAttribute(LDAP_ATTR_USER_CERT);
+ LDAPAttribute certAttrS = new
+ LDAPAttribute(LDAP_ATTR_USER_CERT_STRING);
+
+ //LDAPAttribute certDNAttrS = new LDAPAttribute(LDAP_ATTR_CERTDN);
+
+ int certCount = 0;
+
+ for (int i = 0; i < certs.length; i++) {
+ LDAPModificationSet attrs = new LDAPModificationSet();
+
+ String certStr = null;
+
+ if (delCertdn.startsWith("-1;")) {
+ certStr = getCertificateStringWithoutVersion(certs[i]);
+ } else {
+ certStr = getCertificateString(certs[i]);
+ }
+ if (delCertdn.equalsIgnoreCase(certStr)) {
+ try {
+ certAttr.addValue(certs[i].getEncoded());
+ certAttrS.addValue(getCertificateString(certs[i]));
+ // certDNAttrS.addValue(certs[i].getSubjectDN().toString());
+ } catch (CertificateEncodingException e) {
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_USR_CERT_ERROR"));
+ }
+
+ attrs.add(LDAPModification.DELETE, certAttr);
+ attrs.add(LDAPModification.DELETE, certAttrS);
+ //attrs.add(LDAPModification.DELETE, certDNAttrS);
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ ldapconn.modify("uid=" + user.getUserID() +
+ "," + getUserBaseDN(), attrs);
+ certCount++;
+ // for audit log
+ SessionContext sessionContext = SessionContext.getContext();
+ String adminId = (String) sessionContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_USRGRP,
+ AuditFormat.LEVEL,
+ AuditFormat.REMOVEUSERCERTFORMAT,
+ new Object[] {adminId, user.getUserID(),
+ certs[0].getSubjectDN().toString(),
+ certs[i].getSerialNumber().toString(16)}
+ );
+
+ } catch (LDAPException e) {
+ String errMsg = "removeUserCert():" + e;
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg =
+ "removeUserCert: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER", e.toString()));
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_MOD_USER_FAIL"));
+ } catch (ELdapException e) {
+ String errMsg =
+ "remove User Cert: " +
+ "Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+ }
+
+ if (certCount == 0) {
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_CERT_NOT_FOUND"));
+ }
+
+ return;
+ }
+
+ public void removeUserFromGroup(IGroup grp, String userid)
+ throws EUsrGrpException {
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ String groupDN = "cn=" + grp.getGroupID() +
+ "," + getGroupBaseDN();
+ LDAPAttribute memberAttr = new LDAPAttribute(
+ "uniquemember", "uid=" + userid + "," + getUserBaseDN());
+ LDAPModification singleChange = new LDAPModification(
+ LDAPModification.DELETE, memberAttr);
+
+ ldapconn.modify(groupDN, singleChange);
+ } catch (LDAPException e) {
+ String errMsg = "removeUserFromGroup()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "removeUser: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER_FROM_GROUP", e.toString()));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_REMOVE_USER_FAIL"));
+ } catch (ELdapException e) {
+ String errMsg =
+ "removeUserFromGroup: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER_FROM_GROUP", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ /**
+ * Removes identity.
+ */
+ public void removeUser(String userid) throws EUsrGrpException {
+ if (userid == null) {
+ return;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ ldapconn.delete("uid=" + userid + "," + getUserBaseDN());
+ // for audit log
+ SessionContext sessionContext = SessionContext.getContext();
+ String adminId = (String) sessionContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.REMOVEUSERFORMAT,
+ new Object[] {adminId, userid}
+ );
+
+ } catch (LDAPException e) {
+ String errMsg = "removeUser()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "removeUser: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER", e.toString()));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_REMOVE_USER_FAIL"));
+ } catch (ELdapException e) {
+ String errMsg =
+ "remove User: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_USER", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ /**
+ * modifies user attributes. Certs are handled separately
+ */
+ public void modifyUser(IUser identity) throws EUsrGrpException {
+ User user = (User) identity;
+ String st = null;
+
+ /**
+ X509Certificate certs[] = null;
+ **/
+ LDAPModificationSet attrs = new LDAPModificationSet();
+
+ if (user == null) {
+ return;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ if ((st = user.getFullName()) != null) {
+ attrs.add(LDAPModification.REPLACE,
+ new LDAPAttribute("sn", st));
+ attrs.add(LDAPModification.REPLACE,
+ new LDAPAttribute("cn", st));
+ }
+ if ((st = user.getEmail()) != null) {
+ LDAPAttribute ld = new LDAPAttribute("mail", st);
+
+ attrs.add(LDAPModification.REPLACE, ld);
+ }
+ if ((st = user.getPassword()) != null && (!st.equals(""))) {
+ attrs.add(LDAPModification.REPLACE,
+ new LDAPAttribute("userpassword", st));
+ }
+ if ((st = user.getPhone()) != null) {
+ if (! st.equals("")) {
+ attrs.add(LDAPModification.REPLACE,
+ new LDAPAttribute("telephonenumber", st));
+ } else {
+ try {
+ LDAPModification singleChange = new LDAPModification(
+ LDAPModification.DELETE, new LDAPAttribute("telephonenumber"));
+ ldapconn.modify("uid=" + user.getUserID() +
+ "," + getUserBaseDN(), singleChange);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != LDAPException.NO_SUCH_ATTRIBUTE) {
+ CMS.debug("modifyUser: Error in deleting telephonenumber");
+ throw e;
+ }
+ }
+ }
+ }
+
+ if ((st = user.getState()) != null) {
+ if (! st.equals("")) {
+ attrs.add(LDAPModification.REPLACE,
+ new LDAPAttribute("userstate", st));
+ } else {
+ try {
+ LDAPModification singleChange = new LDAPModification(
+ LDAPModification.DELETE, new LDAPAttribute("userstate"));
+ ldapconn.modify("uid=" + user.getUserID() +
+ "," + getUserBaseDN(), singleChange);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != LDAPException.NO_SUCH_ATTRIBUTE) {
+ CMS.debug("modifyUser: Error in deleting userstate");
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ if ((certs = user.getCertificates()) != null) {
+ LDAPAttribute attrCertStr = new
+ LDAPAttribute("description");
+ LDAPAttribute attrCertBin = new
+ LDAPAttribute(LDAP_ATTR_USER_CERT);
+ for (int i = 0 ; i < certs.length; i++) {
+ attrCertBin.addValue(certs[i].getEncoded());
+ attrCertStr.addValue(getCertificateString(certs[i]));
+ }
+ attrs.add(attrCertStr);
+
+ if (user.getCertOp() == OpDef.ADD) {
+ attrs.add(LDAPModification.ADD, attrCertBin);
+ } else if (user.getCertOp() == OpDef.DELETE) {
+ attrs.add(LDAPModification.DELETE, attrCertBin);
+ } else {
+ throw new EUsrGrpException(UsrGrpResources.USR_MOD_ILL_CERT_OP);
+ }
+ }
+ **/
+ ldapconn.modify("uid=" + user.getUserID() +
+ "," + getUserBaseDN(), attrs);
+ // for audit log
+ SessionContext sessionContext = SessionContext.getContext();
+ String adminId = (String) sessionContext.get(SessionContext.USER_ID);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.MODIFYUSERFORMAT,
+ new Object[] {adminId, user.getUserID()}
+ );
+
+ } catch (Exception e) {
+ //e.printStackTrace();
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_MOD_USER_FAIL"));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ protected Enumeration buildGroups(LDAPSearchResults res) {
+ Vector v = new Vector();
+
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ v.addElement(buildGroup(entry));
+ }
+ return v.elements();
+ }
+
+ /**
+ * Finds groups.
+ */
+ public Enumeration findGroups(String filter) {
+ if (filter == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ LDAPSearchResults res =
+ ldapconn.search(getGroupBaseDN(), LDAPv2.SCOPE_SUB,
+ "(&(objectclass=groupofuniquenames)(cn=" + filter + "))",
+ null, false);
+
+ return buildGroups(res);
+ } catch (LDAPException e) {
+ String errMsg =
+ "findGroups: could not find group " + filter + ". Error " + e;
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "findGroups: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_GROUPS", e.toString()));
+ return null;
+ } catch (ELdapException e) {
+ String errMsg =
+ "find Groups: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_GROUPS", e.toString()));
+ return null;
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ public IGroup findGroup(String filter) {
+ Enumeration groups = findGroups(filter);
+
+ if (groups == null || !groups.hasMoreElements())
+ return null;
+ return (Group) groups.nextElement();
+ }
+
+ /**
+ * List groups. more efficient than find Groups. only retrieves
+ * group names and description.
+ */
+ public Enumeration listGroups(String filter) throws EUsrGrpException {
+ if (filter == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ String attrs[] = new String[2];
+
+ attrs[0] = "cn";
+ attrs[1] = "description";
+
+ ldapconn = getConn();
+ LDAPSearchResults res =
+ ldapconn.search(getGroupBaseDN(), LDAPv2.SCOPE_SUB,
+ "(&(objectclass=groupofuniquenames)(cn=" + filter + "))",
+ attrs, false);
+
+ return buildGroups(res);
+ } catch (LDAPException e) {
+ String errMsg = "listGroups()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "listGroups: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_GROUPS", e.toString()));
+ } catch (ELdapException e) {
+ String errMsg =
+ "list Groups: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_GROUPS", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return null;
+ }
+
+ /**
+ * builds an instance of a Group entry
+ */
+ protected IGroup buildGroup(LDAPEntry entry) {
+ String groupName = (String)entry.getAttribute("cn").getStringValues().nextElement();
+ IGroup grp = createGroup(this, groupName);
+
+ LDAPAttribute grpDesc = entry.getAttribute("description");
+
+ if (grpDesc != null) {
+ Enumeration en = grpDesc.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String desc = (String) en.nextElement();
+
+ if (desc != null) {
+ try {
+ grp.set("description", desc);
+ } catch (EBaseException ex) {
+ // later...
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_BUILD_GROUP", ex.toString()));
+ }
+ }
+ }
+ }
+ if (grp.getDescription() == null) {
+ try {
+ grp.set("description", ""); // safety net
+ } catch (EBaseException ex) {
+ // later...
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_BUILD_GROUP", ex.toString()));
+ }
+ }
+
+ // parser member (should use late-materialization)
+ LDAPAttribute attr = entry.getAttribute("uniquemember");
+
+ if (attr == null) {
+ return grp;
+ }
+
+ Enumeration e = attr.getStringValues();
+
+ while (e.hasMoreElements()) {
+ String v = (String) e.nextElement();
+
+ // grp.addMemberName(v);
+ // DOES NOT SUPPORT NESTED GROUPS...
+
+ /* BAD_GROUP_MEMBER message goes to system log
+ * We are testing unique member attribute for
+ * 1. presence of uid string
+ * 2. presence and sequence of equal sign and comma
+ * 3. absence of equal sign between previously found equal sign and comma
+ * 4. absence of non white space characters between uid string and equal sign
+ */
+ int i = -1;
+ int j = -1;
+ if (v == null || v.length() < 3 || (!(v.substring(0,3)).equalsIgnoreCase("uid")) ||
+ ((i = v.indexOf('=')) < 0) || ((j = v.indexOf(',')) < 0) || i > j ||
+ (v.substring(i+1, j)).indexOf('=') > -1 || ((v.substring(3, i)).trim()).length() > 0) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_BAD_GROUP_MEMBER", groupName, v));
+ } else {
+ grp.addMemberName(v.substring(v.indexOf('=') + 1, v.indexOf(',')));
+ }
+ }
+
+ return grp;
+ }
+
+ protected IGroup createGroup(IUsrGrp scope, String id) {
+ return new Group(scope, id);
+ }
+
+ /**
+ * Retrieves a group from LDAP
+ * NOTE - this takes just the group name.
+ */
+ public IGroup getGroupFromName(String name) {
+ return getGroup("cn=" + name + "," + getGroupBaseDN());
+ }
+
+ /**
+ * Retrieves a group from LDAP
+ * NOTE - LH This takes a full LDAP DN.
+ */
+ public IGroup getGroup(String name) {
+ if (name == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ // read the group object
+ LDAPSearchResults res = ldapconn.search(name,
+ LDAPConnection.SCOPE_BASE, "(objectclass=*)", null, false);
+ Enumeration e = buildGroups(res);
+
+ if (e == null || e.hasMoreElements() == false)
+ return null;
+ return (IGroup) e.nextElement();
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_GET_GROUP", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return null;
+ }
+
+ /**
+ * Checks if the given group exists
+ */
+ public boolean isGroupPresent(String name) {
+ if (name == null) {
+ return false;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ LDAPEntry entry = ldapconn.read(name);
+ LDAPAttribute attr = entry.getAttribute(OBJECTCLASS_ATTR);
+
+ if (attr == null) {
+ return false;
+ }
+ Enumeration en = attr.getStringValues();
+
+ for (; en.hasMoreElements();) {
+ String v = (String) en.nextElement();
+
+ if (v.equalsIgnoreCase(GROUP_ATTR_VALUE)) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_IS_GROUP_PRESENT", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return false;
+ }
+
+ public boolean isMemberOf(String userid, String groupname)
+ {
+ try {
+ IUser user = getUser(userid);
+ return isMemberOfLdapGroup(user.getUserDN(), groupname);
+ } catch (Exception e) {
+ /* do nothing */
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the given user is a member of the given group
+ * (now runs an ldap search to find the user, instead of
+ * fetching the entire group entry)
+ */
+ public boolean isMemberOf(IUser id, String name) {
+ if (id == null) {
+ log(ILogger.LL_WARN, "isMemberOf(): id is null");
+ return false;
+ }
+
+ if (name == null) {
+ log(ILogger.LL_WARN, "isMemberOf(): name is null");
+ return false;
+ }
+
+ Debug.trace("UGSubsystem.isMemberOf() using new lookup code");
+ return isMemberOfLdapGroup(id.getUserDN(),name);
+ }
+
+
+ /**
+ * checks if the given user DN is in the specified group
+ * by running an ldap search for the user in the group
+ */
+ protected boolean isMemberOfLdapGroup(String userid,String groupname)
+ {
+ String basedn = "cn="+groupname+",ou=groups,"+mBaseDN;
+ LDAPConnection ldapconn = null;
+ boolean founduser=false;
+ try {
+ // the group could potentially have many thousands
+ // of members, (many values of the uniquemember
+ // attribute). So, we don't want to fetch this
+ // list each time. We'll just fetch the CN.
+ String attrs[]= new String[1];
+ attrs[0] = "cn";
+
+ ldapconn = getConn();
+
+
+ String filter = "(uniquemember="+userid+")";
+ Debug.trace("authorization search base: "+basedn);
+ Debug.trace("authorization search filter: "+filter);
+ LDAPSearchResults res =
+ ldapconn.search(basedn, LDAPv2.SCOPE_BASE,
+ filter,
+ attrs, false);
+ // If the result had at least one entry, we know
+ // that the filter matched, and so the user correctly
+ // authenticated.
+ if (res.hasMoreElements()) {
+ // actually read the entry
+ LDAPEntry entry = (LDAPEntry)res.nextElement();
+ founduser=true;
+ }
+ Debug.trace("authorization result: "+founduser);
+ } catch (LDAPException e) {
+ String errMsg =
+ "isMemberOfLdapGroup: could not find group "+groupname+". Error "+e;
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "isMemberOfLdapGroup: "+"Internal DB is unavailable";
+ }
+ Debug.trace("authorization exception: "+errMsg);
+ // too chatty in system log
+ // log(ILogger.LL_FAILURE, errMsg);
+ }
+ catch (ELdapException e) {
+ String errMsg =
+ "isMemberOfLdapGroup: Could not get connection to internaldb. Error "+e;
+ Debug.trace("authorization exception: "+errMsg);
+ log(ILogger.LL_FAILURE, errMsg);
+ }
+ finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return founduser;
+ }
+
+ /**
+ * Adds a group of identities.
+ */
+ public void addGroup(IGroup group) throws EUsrGrpException {
+ Group grp = (Group) group;
+
+ if (grp == null) {
+ return;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ String oc[] = {"top", "groupOfUniqueNames"};
+
+ attrs.add(new LDAPAttribute("objectclass", oc));
+ attrs.add(new LDAPAttribute("cn", group.getGroupID()));
+ attrs.add(new LDAPAttribute("description", group.getDescription()));
+ Enumeration e = grp.getMemberNames();
+
+ if (e.hasMoreElements() == true) {
+ LDAPAttribute attrMembers = new LDAPAttribute("uniquemember");
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ // DOES NOT SUPPORT NESTED GROUPS...
+ attrMembers.addValue("uid=" + name + "," +
+ getUserBaseDN());
+ }
+ attrs.add(attrMembers);
+ }
+ LDAPEntry entry = new LDAPEntry("cn=" + grp.getGroupID() +
+ "," + getGroupBaseDN(), attrs);
+
+ ldapconn = getConn();
+ ldapconn.add(entry);
+ } catch (LDAPException e) {
+ String errMsg = "addGroup()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "addGroup: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_GROUP", e.toString()));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_GROUP_FAIL"));
+ } catch (ELdapException e) {
+ String errMsg =
+ "add Group: Could not get connection to internaldb. Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_GROUP", e.toString()));
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_GROUP_FAIL"));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ /**
+ * Removes a group. Can't remove SUPER_CERT_ADMINS
+ */
+ public void removeGroup(String name) throws EUsrGrpException {
+ if (name == null) {
+ return;
+ } else if (name.equalsIgnoreCase(SUPER_CERT_ADMINS)) {
+ log(ILogger.LL_WARN, "removing Certificate Server Administrators group is not allowed");
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_REMOVE_GROUP_FAIL"));
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ ldapconn.delete("cn=" + name + "," + getGroupBaseDN());
+ } catch (LDAPException e) {
+ String errMsg = "removeGroup()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "removeGroup: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_GROUP", e.toString()));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_REMOVE_GROUP_FAIL"));
+ } catch (ELdapException e) {
+ String errMsg =
+ "remove Group: Could not get connection to internaldb. " +
+ "Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_REMOVE_GROUP", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ public void modifyGroup(IGroup group) throws EUsrGrpException {
+ Group grp = (Group) group;
+
+ if (grp == null) {
+ return;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ LDAPAttribute attrMembers = new LDAPAttribute("uniquemember");
+ LDAPModificationSet mod = new LDAPModificationSet();
+ String st = null;
+
+ String desc = grp.getDescription();
+
+ if (desc != null) {
+ mod.add(LDAPModification.REPLACE,
+ new LDAPAttribute("description", desc));
+ }
+
+ Enumeration e = grp.getMemberNames();
+
+ if (e.hasMoreElements() == true) {
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ // DOES NOT SUPPORT NESTED GROUPS...
+ attrMembers.addValue("uid=" + name + "," +
+ getUserBaseDN());
+ }
+ mod.add(LDAPModification.REPLACE, attrMembers);
+ } else {
+ if (!grp.getName().equalsIgnoreCase(SUPER_CERT_ADMINS)) {
+ mod.add(LDAPModification.DELETE, attrMembers);
+ } else {
+ // not allowed
+ throw new
+ EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ILL_GRP_MOD"));
+ }
+ }
+
+ ldapconn = getConn();
+ ldapconn.modify("cn=" + grp.getGroupID() +
+ "," + getGroupBaseDN(), mod);
+ } catch (LDAPException e) {
+ String errMsg = " modifyGroup()" + e.toString();
+
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
+ errMsg = "modifyGroup: " + "Internal DB is unavailable";
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_MODIFY_GROUP", e.toString()));
+
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_MOD_GROUP_FAIL"));
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_MODIFY_GROUP", e.toString()));
+ throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_MOD_GROUP_FAIL"));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ /**
+ * Evalutes the given context with the attribute
+ * critieria.
+ */
+ public boolean evaluate(String type, IUser id,
+ String op, String value) {
+ if (op.equals("=")) {
+ if (type.equalsIgnoreCase("user")) {
+ if (isMatched(value, id.getName()))
+ return true;
+ }
+ if (type.equalsIgnoreCase("group")) {
+ return isMemberOf(id, value);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Converts an uid attribute to a DN.
+ */
+ protected String convertUIDtoDN(String uid) throws
+ LDAPException {
+ String u = uid;
+
+ if (u == null) {
+ return null;
+ }
+
+ LDAPConnection ldapconn = null;
+
+ try {
+ ldapconn = getConn();
+ LDAPSearchResults res = ldapconn.search(getUserBaseDN(),
+ LDAPv2.SCOPE_SUB, "(uid=" + u + ")", null, false);
+
+ if (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ return entry.getDN();
+ }
+ } catch (ELdapException e) {
+ String errMsg =
+ "convertUIDtoDN: Could not get connection to internaldb. " +
+ "Error " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_CONVERT_UID", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ return null;
+ }
+
+ /**
+ * Checks if the given DNs are the same after
+ * normalization.
+ */
+ protected boolean isMatched(String dn1, String dn2) {
+ String rdn1[] = LDAPDN.explodeDN(dn1, false);
+ String rdn2[] = LDAPDN.explodeDN(dn2, false);
+
+ if (rdn1.length == rdn2.length) {
+ for (int j = 0; j < rdn1.length; j++) {
+ if (!rdn1[j].equalsIgnoreCase(rdn2[j])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Converts certificate into string format.
+ * should eventually go into the locator itself
+ */
+ protected String getCertificateStringWithoutVersion(X509Certificate cert) {
+ if (cert == null) {
+ return null;
+ }
+ // note that it did not represent a certificate fully
+ return "-1;" + cert.getSerialNumber().toString() +
+ ";" + cert.getIssuerDN() + ";" + cert.getSubjectDN();
+ }
+
+ public String getCertificateString(X509Certificate cert) {
+ if (cert == null) {
+ return null;
+ }
+
+ // note that it did not represent a certificate fully
+ return cert.getVersion() + ";" + cert.getSerialNumber().toString() +
+ ";" + cert.getIssuerDN() + ";" + cert.getSubjectDN();
+ }
+
+ /**
+ * Retrieves user base dn.
+ */
+ private String getUserBaseDN() {
+ return "ou=People," + mBaseDN;
+ }
+
+ /**
+ * Retrieves group base dn.
+ */
+ private String getGroupBaseDN() {
+ return "ou=Groups," + mBaseDN;
+ }
+
+ protected LDAPConnection getConn() throws ELdapException {
+ if (mLdapConnFactory == null)
+ return null;
+ return mLdapConnFactory.getConn();
+ }
+
+ protected void returnConn(LDAPConnection conn) {
+ if (mLdapConnFactory != null)
+ mLdapConnFactory.returnConn(conn);
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_USRGRP,
+ level, "UGSubsystem: " + msg);
+ }
+
+ public ICertUserLocator getCertUserLocator() {
+ return new ExactMatchCertUserLocator();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/usrgrp/User.java b/pki/base/common/src/com/netscape/cmscore/usrgrp/User.java
new file mode 100644
index 000000000..5ecb4f169
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/usrgrp/User.java
@@ -0,0 +1,216 @@
+// --- 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.cmscore.usrgrp;
+
+
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a user.
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class User implements IUser {
+
+ public static final String ATTR_X509_CERTIFICATES = "userCertificates";
+ private IUsrGrp mBase = null;
+ private String mUserid = null;
+ private String mUserDN = null;
+ private String mFullName = null;
+ private String mPassword = null;
+ private String mEmail = null;
+ private String mPhone = null;
+ private String mState = null;
+ private String mCertDN = null;
+ private String mUserType = null;
+ private X509Certificate mx509Certs[] = null;
+
+ private static final Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_NAME);
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_FULLNAME);
+ mNames.addElement(ATTR_PASSWORD);
+ mNames.addElement(ATTR_STATE);
+ mNames.addElement(ATTR_EMAIL);
+ // mNames.addElement(ATTR_PHONENUMBER);
+ mNames.addElement(ATTR_X509_CERTIFICATES);
+ mNames.addElement(ATTR_USERTYPE);
+ }
+
+ /**
+ * Constructs a user.
+ */
+ public User(IUsrGrp base, String userid) {
+ mBase = base;
+ mUserid = userid;
+ }
+
+ /**
+ * Retrieves the name of this identity.
+ */
+ public String getName() {
+ // return mScope.getId() + "://" + mUserid;
+ return mUserid;
+ }
+
+ /**
+ * Retrieves user identifier.
+ */
+ public String getUserID() {
+ return mUserid;
+ }
+
+ /**
+ * Retrieves user full name.
+ */
+ public String getFullName() {
+ return mFullName;
+ }
+
+ public void setFullName(String name) {
+ mFullName = name;
+ }
+
+ /**
+ * Retrieves user ldap dn
+ */
+ public String getUserDN() {
+ return mUserDN;
+ }
+
+ public void setUserDN(String userdn) {
+ mUserDN = userdn;
+ }
+
+ public String getUserType() {
+ return mUserType;
+ }
+
+ public void setUserType(String userType) {
+ mUserType = userType;
+ }
+
+ /**
+ * Retrieves user password.
+ */
+ public String getPassword() {
+ return mPassword;
+ }
+
+ public void setPassword(String password) {
+ mPassword = password;
+ }
+
+ public String getEmail() {
+ return mEmail;
+ }
+
+ public void setEmail(String email) {
+ mEmail = email;
+ }
+
+ public String getPhone() {
+ return mPhone;
+ }
+
+ public String getState() {
+ return mState;
+ }
+
+ public void setPhone(String phone) {
+ mPhone = phone;
+ }
+
+ public void setState(String state) {
+ mState = state;
+ }
+
+ public X509Certificate[] getX509Certificates() {
+ return mx509Certs;
+ }
+
+ public void setX509Certificates(X509Certificate certs[]) {
+ mx509Certs = certs;
+ }
+
+ public String getCertDN() {
+ return mCertDN;
+ }
+
+ public void setCertDN(String dn) {
+ mCertDN = dn;
+ }
+
+ public void set(String name, Object object) throws EBaseException {
+ if (name.equals(ATTR_NAME)) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ } else if (name.equals(ATTR_ID)) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ } else if (name.equals(ATTR_FULLNAME)) {
+ setFullName((String) object);
+ } else if (name.equals(ATTR_STATE)) {
+ setState((String) object);
+ } else if (name.equals(ATTR_PASSWORD)) {
+ setPassword((String) object);
+ } else if (name.equals(ATTR_X509_CERTIFICATES)) {
+ setX509Certificates((X509Certificate[]) object);
+ } else if (name.equals(ATTR_USERTYPE)) {
+ setUserType((String) object);
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public Object get(String name) throws EBaseException {
+ if (name.equals(ATTR_NAME)) {
+ return getName();
+ } else if (name.equals(ATTR_ID)) {
+ return getUserID();
+ } else if (name.equals(ATTR_STATE)) {
+ return getState();
+ } else if (name.equals(ATTR_FULLNAME)) {
+ return getFullName();
+ } else if (name.equals(ATTR_PASSWORD)) {
+ return getPassword();
+ } else if (name.equals(ATTR_X509_CERTIFICATES)) {
+ return getX509Certificates();
+ } else if (name.equals(ATTR_USERTYPE)) {
+ return getUserType();
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/Assert.java b/pki/base/common/src/com/netscape/cmscore/util/Assert.java
new file mode 100644
index 000000000..afc38f49b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/Assert.java
@@ -0,0 +1,49 @@
+// --- 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.cmscore.util;
+
+
+public class Assert {
+ public static final boolean ON = true;
+
+ public static void Assertion(boolean e) {
+ if (!e) {
+ throw new AssertionException("assertion");
+ }
+ }
+
+ public static void NotReached(String msg) {
+ throw new AssertionException("not reached: " + msg);
+ }
+
+ public static void NotYetImplemented(String msg) {
+ throw new AssertionException("not yet implemented: " + msg);
+ }
+
+ public static void PreCondition(boolean e) {
+ if (!e) {
+ throw new AssertionException("precondition");
+ }
+ }
+
+ public static void PostCondition(boolean e) {
+ if (!e) {
+ throw new AssertionException("precondition");
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/AssertionException.java b/pki/base/common/src/com/netscape/cmscore/util/AssertionException.java
new file mode 100644
index 000000000..7b0675b12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/AssertionException.java
@@ -0,0 +1,32 @@
+// --- 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.cmscore.util;
+
+
+/**
+ * Assertion exceptions are thrown when assertion code is invoked
+ * and fails to operate properly.
+ */
+public class AssertionException extends Error {
+ public AssertionException() {
+ }
+
+ public AssertionException(String msg) {
+ super(msg);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/Debug.java b/pki/base/common/src/com/netscape/cmscore/util/Debug.java
new file mode 100644
index 000000000..b9b794e9c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/Debug.java
@@ -0,0 +1,363 @@
+// --- 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.cmscore.util;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.cmsutil.util.*;
+
+import java.lang.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+
+public class Debug
+ implements ISubsystem {
+
+ private static Debug mInstance = new Debug();
+ private static boolean mShowCaller = false;
+
+
+ /* This dateformatter is used to put the date on each
+ debug line. But the DateFormatter is not thread safe,
+ so I create a thread-local DateFormatter for each thread
+ */
+ private static String DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss";
+ private static ThreadLocal mFormatObject = new ThreadLocal() {
+ protected synchronized Object initialValue() {
+ return new SimpleDateFormat(DATE_PATTERN);
+ }
+ };
+
+ /* the dateformatter should be accessed with this function */
+ private static SimpleDateFormat getDateFormatter() {
+ return ((SimpleDateFormat)(mFormatObject.get()));
+ }
+
+ public static final boolean ON = false;
+ public static final int OBNOXIOUS = 10;
+ public static final int VERBOSE = 5;
+ public static final int INFORM = 1;
+
+ // the difference between this and 'ON' is that this is always
+ // guaranteed to log to 'mOut', whereas other parts of the server
+ // may do:
+ // if (Debug.ON) {
+ // System.out.println("..");
+ // }
+ // I want to make sure that any Debug.trace() is not logged to
+ // System.out if the server is running under watchdog
+
+ private static boolean TRACE_ON = false;
+
+ private static int mDebugLevel = VERBOSE;
+
+ private static PrintStream mOut = null;
+ private static Hashtable mHK = null;
+
+ static {
+ if (TRACE_ON == true) {
+ mOut = System.out;
+ }
+ }
+
+ public static void trace(int level, String t) {
+ trace(level, t, null, true);
+ }
+
+ /**
+ * Output a debug message at the output stream sepcified in the init()
+ * method. This method is very lightweight if debugging is turned off, since
+ * it will return immediately. However, the caller should be aware that
+ * if the argument to Debug.trace() is an object whose toString() is
+ * expensive, that this toString() will still be called in any case.
+ * In such a case, it is wise to wrap the Debug.trace like this: <pre>
+ * if (Debug.on()) { Debug.trace("obj is: "+obj); }
+ * </pre>
+ * @param level the message level. If this is >= than the currently set
+ * level (set with setLevel() ), the message is printed
+ * @param t the message to print
+ * @param ignoreStack when walking the stack to determine the
+ * location of the method that called the trace() method,
+ * ignore any classes with this string in. Can be null
+ * @param printCaller if true, (and if static mShowCaller is true)
+ * dump caller information in this format:
+ * (source-file:line) methodname():
+ */
+ public static void trace(int level, String t, String ignoreStack, boolean printCaller) {
+ String callerinfo = "";
+ if (!TRACE_ON) return;
+ if (level >= mDebugLevel) {
+ if (mShowCaller && printCaller) {
+ String method = "";
+ String fileAndLine = "";
+
+ try {
+ Throwable tr = new Throwable();
+ StackTraceElement ste[] = tr.getStackTrace();
+ int i=0;
+ while ((i < ste.length) &&
+ (ste[i].getMethodName().toLowerCase().indexOf("debug") >-1) ||
+ (ste[i].getMethodName().toLowerCase().indexOf("hashkey") >-1) ||
+ (ste[i].getClassName().toLowerCase().indexOf("propconfigstore") >-1) ||
+ (ste[i].getClassName().toLowerCase().indexOf("argblock") >-1) ||
+ (ste[i].getClassName().toLowerCase().indexOf("debug") >-1) ||
+ (ste[i].getMethodName().toLowerCase().indexOf("trace") >-1)) i++;
+
+ if (i < ste.length) {
+ fileAndLine = ste[i].getFileName()+":"+
+ ste[i].getLineNumber();
+ method = ste[i].getMethodName()+"()";
+ }
+
+ callerinfo = fileAndLine +":"+ method + " ";
+ } catch (Exception f) {
+ }
+ }
+
+ outputTraceMessage(callerinfo + t);
+ }
+ }
+
+ private static void outputTraceMessage(String t)
+ {
+ if (!TRACE_ON) return;
+ SimpleDateFormat d = getDateFormatter();
+ if (mOut != null && d != null) {
+ mOut.println("[" + d.format(new Date()) + "][" + Thread.currentThread().getName() + "]: " + t);
+ mOut.flush();
+ }
+ }
+
+ private static boolean hkdotype(String type)
+ {
+ if (mHK!= null && mHK.get(type) != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void traceHashKey(String type, String key) {
+ if (hkdotype(type)) {
+ trace("GET r=" + type+ ",k=" + key);
+ }
+ }
+
+ public static void traceHashKey(String type, String key, String val) {
+ if (hkdotype(type)) {
+ trace("GET r=" + type+ ",k=" + key + ",v=" + val);
+ }
+ }
+
+ public static void traceHashKey(String type, String key, String val, String def) {
+ if (hkdotype(type)) {
+ trace("GET r=" + type+ ",k=" +
+ key + ",v=" + val +",d="+def);
+ }
+ }
+
+ public static void putHashKey(String type, String key, String value) {
+ if (hkdotype(type)) {
+ outputTraceMessage("PUT r=" + type+ ",k=" + key + ",v=" + value);
+ }
+ }
+
+ public static void trace(String t) {
+ trace(VERBOSE, t);
+ }
+
+ public static void print(int level, String t) {
+ if (!TRACE_ON) return;
+ if (mOut != null) {
+ if (level >= mDebugLevel)
+ mOut.print(t);
+ }
+ }
+
+ public static void print(String t) {
+ print(VERBOSE, t);
+ }
+
+ private static void printNybble(byte b) {
+ if (mOut == null) return;
+ if (b < 10) mOut.write('0' + b);
+ else mOut.write('a' + b - 10);
+ }
+
+ /**
+ * If tracing enabled, dump a byte array to debugging printstream
+ * as hex, colon-seperated bytes, 16 bytes to a line
+ */
+ public static void print(byte[] b) {
+ if (!TRACE_ON) return;
+ if (mOut == null) return;
+
+ for (int i = 0; i < b.length; i++) {
+ printNybble((byte) ((b[i] & 0xf0) >> 4));
+ printNybble((byte) (b[i] & 0x0f));
+ mOut.print(" ");
+ if (((i % 16) == 15) && i != b.length) mOut.println("");
+ }
+ mOut.println("");
+ mOut.flush();
+ }
+
+ /**
+ * Print the current stack trace to the debug printstream
+ */
+ public static void printStackTrace() {
+ if (!TRACE_ON) return;
+ Exception e = new Exception("Debug");
+
+ printStackTrace(e);
+ }
+
+ /**
+ * Print the stack trace of the named exception
+ * to the debug printstream
+ */
+ public static void printStackTrace(Throwable e) {
+ if (!TRACE_ON) return;
+ if (mOut == null) return;
+
+ e.printStackTrace(mOut);
+ }
+
+ /**
+ * Set the current debugging level. You can use: <pre>
+ * OBNOXIOUS = 10
+ * VERBOSE = 5
+ * INFORM = 1
+ * </pre> Or another value
+ */
+
+ public static void setLevel(int level) {
+ mDebugLevel = level;
+ }
+
+ public static int getLevel(int level) {
+ return mDebugLevel;
+ }
+
+ /**
+ * Test if debugging is on. Do NOT write to System.out in your debug code
+ */
+ public static boolean on() {
+ return TRACE_ON;
+ }
+
+ /* ISubsystem methods: */
+
+ public static String ID = "debug";
+ private static IConfigStore mConfig = null;
+
+ public String getId() {
+ return ID;
+ }
+
+ public void setId(String id) {
+ ID = id;
+ }
+
+ private static final String PROP_ENABLED = "enabled";
+ private static final String PROP_FILENAME = "filename";
+ private static final String PROP_HASHKEYS = "hashkeytypes";
+ private static final String PROP_SHOWCALLER = "showcaller";
+ private static final String PROP_LEVEL = "level";
+ private static final String PROP_APPEND = "append";
+
+ /**
+ * Debug subsystem initialization. This subsystem is usually
+ * given the following parameters: <pre>
+ * debug.enabled : (true|false) default false
+ * debug.filename : can be a pathname, or STDOUT
+ * debug.hashkeytypes: comma-separated list of hashkey types
+ * possible values: "CS.cfg"
+ * debug.showcaller: (true|false) default false [show caller method name for Debug.trace()]
+ * </pre>
+ */
+ public void init(ISubsystem owner, IConfigStore config) {
+ mConfig = config;
+ String filename = null;
+ String hashkeytypes = null;
+ boolean append=true;
+
+ try {
+ TRACE_ON = mConfig.getBoolean(PROP_ENABLED, false);
+ if (TRACE_ON) {
+ filename = mConfig.getString(PROP_FILENAME, null);
+ if (filename == null) {
+ TRACE_ON = false;
+ }
+ hashkeytypes = mConfig.getString(PROP_HASHKEYS, null);
+ mShowCaller = mConfig.getBoolean(PROP_SHOWCALLER, false);
+ append = mConfig.getBoolean(PROP_APPEND, true);
+ }
+ if (TRACE_ON) {
+ if (filename.equals("STDOUT")) {
+ mOut = System.out;
+ } else {
+ if( !Utils.isNT() ) {
+ // Always insure that a physical file exists!
+ Utils.exec( "touch " + filename );
+ Utils.exec( "chmod 00640 " + filename );
+ }
+ OutputStream os = new FileOutputStream(filename, append);
+ mOut = new PrintStream(os, true); /* true == autoflush */
+ }
+ if (hashkeytypes != null) {
+ StringTokenizer st = new StringTokenizer(hashkeytypes,
+ ",", false);
+ mHK = new Hashtable();
+ while (st.hasMoreElements()) {
+ String hkr = st.nextToken();
+ mHK.put(hkr, "true");
+ }
+ }
+ }
+ outputTraceMessage("============================================");
+ outputTraceMessage("===== DEBUG SUBSYSTEM INITIALIZED =======");
+ outputTraceMessage("============================================");
+ int level = mConfig.getInteger(PROP_LEVEL, VERBOSE);
+ setLevel(level);
+ } catch (Exception e) {
+ // Don't do anything. Logging is not set up yet, and
+ // we can't write to STDOUT.
+ }
+ }
+
+ public void startup() {
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ // for singleton
+
+ public static Debug getInstance() {
+ return mInstance;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java b/pki/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java
new file mode 100644
index 000000000..61f6f49ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java
@@ -0,0 +1,91 @@
+// --- 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.cmscore.util;
+
+
+import java.io.*;
+
+
+public class ExceptionFormatter {
+
+ /**
+ * Routines for pretty-printing java exceptions
+ * prints okay in a single-line.
+ */
+ /*
+ * Take an exception stacktrace, and reformat it so that is
+ * prints okay in a single-line.
+ */
+
+ public static String getStackTraceAsString(Throwable e) {
+ String returnvalue = e.toString();
+
+ try {
+ PipedOutputStream po = new PipedOutputStream();
+ PipedInputStream pi = new PipedInputStream(po);
+
+ PrintWriter ps = new PrintWriter(po);
+
+ e.printStackTrace(ps);
+ ps.flush();
+
+ int avail = pi.available();
+ byte[] b = new byte[avail];
+
+ pi.read(b, 0, avail);
+ returnvalue = new String(b);
+ } catch (Exception ex) {
+ }
+ return returnvalue;
+
+ }
+
+ /* test code below */
+
+ public static void test()
+ throws TestException {
+ throw new TestException("** testexception **");
+ }
+
+ public static void main(String[] argv) {
+ try {
+ test();
+ } catch (Exception e) {
+ System.out.println("\n------- Exception.toString() ------");
+ System.out.println(e.toString());
+ System.out.println("\n------- Exception.printStackTrace() ------");
+ e.printStackTrace();
+ System.out.println("\n------- ExceptionFormatter.format() ------");
+ System.out.println(ExceptionFormatter.getStackTraceAsString(e));
+ }
+ }
+
+}
+
+
+class TestException extends Exception {
+
+ public TestException() {
+ }
+
+ public TestException(String s) {
+ super(s);
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/util/FileAsString.java b/pki/base/common/src/com/netscape/cmscore/util/FileAsString.java
new file mode 100644
index 000000000..968f9cb80
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/FileAsString.java
@@ -0,0 +1,123 @@
+// --- 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.cmscore.util;
+
+
+import java.io.*;
+import java.lang.StringBuffer;
+
+
+public class FileAsString {
+
+ protected String mFilename;
+ protected long mLastRead = 0;
+
+ private String fileContents = null;
+ private Object userObject = null;
+
+ /**
+ * This class enables you to get treat a file as a string
+ * If the file changes underneath you, it will automatically
+ * be read
+ */
+ public FileAsString(String filename) throws IOException {
+ mFilename = filename;
+ readFile();
+ }
+
+ public boolean fileHasChanged() throws IOException {
+ File file = new File(mFilename);
+ long lastmodified = file.lastModified();
+
+ return (lastmodified != mLastRead);
+ }
+
+ private void readFile()
+ throws IOException {
+ BufferedReader br = createBufferedReader(mFilename);
+ StringBuffer buf = new StringBuffer("");
+ int bytesread = 0;
+
+ do {
+ char cbuf[] = new char[16];
+
+ bytesread = br.read(cbuf, 0, cbuf.length);
+ if (bytesread > 0) {
+ buf.append(cbuf, 0, bytesread);
+ }
+ String s = new String(buf);
+ }
+ while (bytesread != -1);
+ br.close();
+
+ fileContents = new String(buf);
+ }
+
+ private BufferedReader createBufferedReader(String filename)
+ throws IOException {
+ Debug.trace("createBufferedReader(filename=" + filename + ")");
+ BufferedReader br = null;
+ FileReader fr = null;
+
+ try {
+ File file = new File(filename);
+
+ mLastRead = file.lastModified();
+ fr = new FileReader(file);
+ br = new BufferedReader(fr);
+ mFilename = filename;
+ } catch (IOException e) {
+ try {
+ if (fr != null) {
+ fr.close();
+ }
+ } catch (Exception f) {
+ }
+ throw e;
+ }
+ return br;
+ }
+
+ public String getAsString()
+ throws IOException {
+ if (fileHasChanged()) {
+ readFile();
+ }
+ return fileContents;
+ }
+
+ public Object getUserObject() {
+ try {
+ if (fileHasChanged()) {
+ userObject = null;
+ }
+ } catch (Exception e) {
+ userObject = null;
+ }
+ return userObject;
+ }
+
+ public void setUserObject(Object x) {
+ userObject = x;
+ }
+
+ public String getFilename() {
+ return mFilename;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java b/pki/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java
new file mode 100644
index 000000000..98a2e8422
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java
@@ -0,0 +1,146 @@
+// --- 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.cmscore.util;
+
+
+import java.io.*;
+
+
+/**
+ * checks the filename and directory with the specified filter
+ * checks with multiple "*".
+ * the filter has to start with a '*' character.
+ * this to keep the search the same as in the motif version
+ * <P>
+ * Copied verbatium from sun.awt.tiny.TinyFileDialogPeer. Used by
+ * RollingLogFile expiration code
+ * <P>
+ * @author mikep
+ * @version $Revision$, $Date$
+ */
+public class FileDialogFilter implements FilenameFilter {
+
+ String filter;
+
+ public FileDialogFilter(String f) {
+ filter = f;
+ }
+
+ public String toString() {
+ return filter;
+ }
+
+ /**
+ * return true if match
+ */
+ public boolean accept(File dir, String fileName) {
+
+ File f = new File(dir, fileName);
+
+ if (f.isDirectory()) {
+ return true;
+ } else {
+ return searchPattern(fileName, filter);
+ }
+ }
+
+ /**
+ * start searching
+ */
+ boolean searchPattern(String fileName, String filter) {
+ int filterCursor = 0;
+ int fileNameCursor = 0;
+
+ int filterChar = filter.charAt(filterCursor);
+
+ if (filterCursor == 0 && filterChar != '*') {
+ return false;
+ }
+ String ls = filter.substring(filterCursor + 1);
+
+ return handleStar(fileName, ls);
+ }
+
+ /**
+ * call this method when character was an *
+ */
+ boolean handleStar(String fileName, String filter) {
+ int ftLen = filter.length();
+ int flLen = fileName.length();
+ char ftChar;
+ char flChar;
+ int ftCur = 0;
+ int flCur = 0;
+ int c = 0;
+
+ if (ftLen == 0) {
+ return true;
+ }
+
+ while (c < flLen) {
+ ftChar = filter.charAt(ftCur);
+
+ if (ftChar == '*') {
+ String ls = filter.substring(ftCur + 1);
+ String fs = fileName.substring(flCur);
+
+ if (handleStar(fs, ls)) {
+ return true;
+ }
+ c++;
+ flCur = c;
+ ftCur = 0;
+ continue;
+ }
+ flChar = fileName.charAt(flCur);
+
+ if (ftChar == flChar) {
+ ftCur++;
+ flCur++;
+
+ if (flCur == flLen && ftCur == ftLen) {
+ return true;
+ }
+
+ if (flCur < flLen && ftCur == ftLen) {
+ return false;
+ }
+
+ if (flCur == flLen) {
+ c = flLen;
+ }
+ } else {
+ c++;
+ flCur = c;
+ ftCur = 0;
+ if (c == flLen) {
+ return false;
+ }
+ }
+ }
+
+ for (int i = ftCur; i < ftLen; i++) {
+ ftChar = filter.charAt(i);
+ if (ftChar != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cmscore/util/OsSubsystem.java b/pki/base/common/src/com/netscape/cmscore/util/OsSubsystem.java
new file mode 100644
index 000000000..a3cdcbdef
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/OsSubsystem.java
@@ -0,0 +1,488 @@
+// --- 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.cmscore.util;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.osutil.*;
+
+
+/**
+ * This object contains the OS independent interfaces. It's currently
+ * used for Unix signal and user handling, but could eventually be extended
+ * for NT interfaces.
+ * <P>
+ *
+ * @author mikep
+ * @version $Revision$, $Date$
+ */
+public final class OsSubsystem implements ISubsystem {
+
+ public static final String ID = "os";
+ protected IConfigStore mConfig;
+ protected String mInstanceDir;
+ protected ISubsystem mOwner;
+ protected ILogger mLogger = null;
+ protected static SignalThread mSignalThread = null;
+
+ private static final String PROP_OS = "os";
+ private static final String PROP_USERID = "userid";
+
+ // singleton enforcement
+
+ private static OsSubsystem mInstance = new OsSubsystem();
+
+ public static OsSubsystem getInstance() {
+ return mInstance;
+ }
+
+ // end singleton enforcement.
+
+ /**
+ * Constructor for an OS subsystem
+ */
+ private OsSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem name.
+ */
+ public String getId() {
+ return ID;
+ }
+
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Initializes this subsystem with the given configuration
+ * store.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ mOwner = owner;
+ mConfig = config;
+ mLogger = CMS.getLogger();
+
+ mInstanceDir = CMS.getConfigStore().getString("instanceRoot");
+
+ // We currently only deal with Unix and NT
+ if (isUnix()) {
+ //initUnix();
+ } else {
+ initNT();
+ }
+ try {
+ //System.out.println(" The dir I'm seeing is " + mInstanceDir);
+ String pidName = mInstanceDir + File.separator + "config" + File.separator + "cert-pid";
+ BufferedWriter pidOut = new BufferedWriter(new FileWriter(pidName));
+ int pid = OsSubsystem.getpid();
+
+ pidOut.write(Integer.toString(pid));
+ pidOut.close();
+ OSUtil.getFileWriteLock(pidName);
+ } catch (Exception e) {
+ //XX to stderr XXXXXX
+ //e.printStackTrace();
+ }
+ }
+
+ /**
+ * Starts up OS
+ */
+ public void startup() throws EBaseException {
+ if (isUnix()) {
+ String pf = mConfig.getString("pidFile", null);
+
+ if (pf == null) {
+ return; // development environment does not rely on this
+ }
+ // dont ever call detach in Java environment,
+ // it does a fork()
+ // LibC.detach();
+
+ // need to do pid here, pid will be changed after detach
+ int pid = LibC.getpid();
+ String pidStr = Integer.toString(pid);
+
+ try {
+ FileOutputStream fos = new FileOutputStream(pf);
+
+ fos.write(pidStr.getBytes());
+ fos.close();
+ } catch (IOException e) {
+
+ /*LogDoc
+ *
+ * @phase start OS subsystem
+ * @message OS: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, "OS: " + e.toString());
+ }
+ }
+ }
+
+ /**
+ * Returns the process ID of the Certificate Server process. Works
+ * on Unix and NT.
+ */
+ public static int getpid() {
+ if (isUnix()) {
+ return LibC.getpid();
+ } else {
+ return OSUtil.getNTpid();
+ }
+ }
+
+ /**
+ * Hooks up unix signals.
+ */
+ private void initUnix() throws EBaseException {
+ // Set up signal handling. We pretty much exit on anything
+ // Signal.watch(Signal.SIGHUP);
+ // Signal.watch(Signal.SIGTERM);
+ // Signal.watch(Signal.SIGINT);
+ // mSignalThread = new SignalThread();
+ // mSignalThread.setDaemon(true);
+ // mSignalThread.start();
+
+ Signal.addSignalListener(Signal.SIGHUP, new SIGHUPListener(this));
+ Signal.addSignalListener(Signal.SIGTERM, new SIGTERMListener(this));
+ Signal.addSignalListener(Signal.SIGINT, new SIGINTListener(this));
+
+ /* Increase the maximum number of file descriptors */
+ int i = mConfig.getInteger("maxFiles",
+ ResourceLimit.getHardLimit(ResourceLimit.RLIMIT_NOFILE));
+
+ ResourceLimit.setLimits(ResourceLimit.RLIMIT_NOFILE,
+ i, ResourceLimit.getHardLimit(ResourceLimit.RLIMIT_NOFILE));
+
+ // write current pid to specified file
+ String pf = mConfig.getString("pidFile", null);
+
+ if (pf == null) {
+ return; // development environment does not rely on this
+ }
+ File pidFile = new File(pf);
+
+ if (pidFile.exists()) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PID_EXIST"));
+ }
+ }
+
+ /**
+ * Used to change the process user id usually called after the appropriate
+ * network ports have been opened.
+ */
+ public void setUserId() throws EBaseException {
+ if (!isUnix())
+ return;
+
+ String userid;
+
+ userid = mConfig.getString(PROP_USERID, null);
+ String id = String.valueOf(UserID.get());
+
+ // Change the userid to the prefered Unix user
+ if (userid == null) {
+
+ /*LogDoc
+ *
+ * @phase set user id
+ * @arg0 default user id
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ "OS: No user id in config file. Running as {0}", id);
+ } else {
+ Object[] params = {userid, id};
+
+ try {
+ UserID.set(userid);
+ } catch (IllegalArgumentException e) {
+
+ /*LogDoc
+ *
+ * @phase set user id
+ * @arg0 supplied user id in config
+ * @arg1 default user id
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ "OS: No such user as {0}. Running as {1}", params);
+ } catch (SecurityException e) {
+
+ /*LogDoc
+ *
+ * @phase set user id
+ * @arg0 supplied user id in config
+ * @arg1 default user id
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ "OS: Can't change process uid to {0}. Running as {1}",
+ params);
+ }
+ }
+ }
+
+ private void initNT() {
+ }
+
+ /**
+ * Stops the watchdog. You need to call this if you want the
+ * server to really shutdown, otherwise the watchdog will just
+ * restart us.
+ * <P>
+ */
+ public static void stop() {
+ if (isUnix()) {
+ shutdownUnix();
+ Signal.send(LibC.getppid(), Signal.SIGTERM);
+ } else {
+
+ /*LogDoc
+ *
+ * @phase stop watchdog
+ */
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "OS: stop the NT watchdog!");
+ }
+ }
+
+ /**
+ * Stops this system.
+ * <P>
+ */
+ public void shutdown() {
+ if (isUnix()) {
+ shutdownUnix();
+ } else {
+ shutdownNT();
+ }
+ }
+
+ /**
+ * Shutdown the unix system handlers
+ * <P>
+ */
+ private static void shutdownUnix() {
+
+ // Don't accidentally stop this thread
+ //if (Thread.currentThread() != mSignalThread && mSignalThread != null) {
+ // mSignalThread.stop();
+ // mSignalThread = null;
+ //}
+
+ /* Don't release this signals to protect the process
+ Signal.release(Signal.SIGHUP);
+ Signal.release(Signal.SIGTERM);
+ Signal.release(Signal.SIGINT);
+ */
+ }
+
+ /**
+ * Shutdown the NT system handlers
+ * <P>
+ */
+ private void shutdownNT() {
+ }
+
+ /**
+ * Restart the server
+ * <P>
+ */
+ public void restart() {
+
+ /**
+ if (isUnix()) {
+ restartUnix();
+ } else {
+ restartNT();
+ }
+ **/
+ }
+
+ /**
+ * Unix restart
+ * <P>
+ */
+ private void restartUnix() {
+ // Tell watch dog to restart us
+ int ppid = LibC.getppid();
+
+ Signal.send(ppid, Signal.SIGHUP);
+ }
+
+ /**
+ * NT restart
+ * <P>
+ */
+ private void restartNT() {
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * A universal routine to decide if we are Unix or something else.
+ * This is mostly used for signal handling and uids.
+ *
+ * <P>
+ * @return true if these OS the JavaVM is running on is some Unix varient
+ */
+ public static boolean isUnix() {
+ // XXX What about MacOS?
+ return (File.separatorChar == '/');
+ }
+
+ /**
+ * Unix signal thread. Sleep for a second and then check on the
+ * signals we're interested in. If one is set, do the right stuff
+ */
+ final class SignalThread extends Thread {
+
+ /**
+ * Signal thread constructor
+ */
+ public SignalThread() {
+ super();
+ super.setName("OsSignal-" + (Thread.activeCount() + 1));
+ }
+
+ /**
+ * Check for signal changes every second
+ */
+ public void run() {
+ while (true) {
+ // Sleep for the interval and then check for caught signals
+ // synchronized (Thread.this) {
+ synchronized (this) {
+ try {
+ // Thread.this.wait(1000);
+ this.wait(1000);
+ } catch (InterruptedException e) {
+ // Not very interesting...
+ }
+ }
+
+ // wants us to exit?
+ if (Signal.caught(Signal.SIGINT) > 0 ||
+ Signal.caught(Signal.SIGTERM) > 0) {
+
+ /*LogDoc
+ *
+ * @phase watchdog check
+ */
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "OS: Received shutdown signal");
+ SubsystemRegistry.getInstance().get("MAIN").shutdown();
+ return;
+ }
+
+ // Tell to restart us
+ if (Signal.caught(Signal.SIGHUP) > 0) {
+
+ /*LogDoc
+ *
+ * @phase watchdog check
+ */
+ mLogger.log(ILogger.EV_SYSTEM,
+ ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "OS: Received restart signal");
+ restart();
+ return;
+ }
+
+ }
+ }
+
+ }
+}
+
+
+class SIGTERMListener extends SignalListener {
+ private OsSubsystem mOS;
+ public SIGTERMListener(OsSubsystem os) {
+ mOS = os;
+ }
+
+ public void process() {
+ System.out.println("SIGTERMListener process");
+ // XXX - temp, should call shutdown
+ System.exit(0);
+ //PKIServer.getPKIServer().shutdown();
+ }
+}
+
+
+class SIGINTListener extends SignalListener {
+ private OsSubsystem mOS;
+ public SIGINTListener(OsSubsystem os) {
+ mOS = os;
+ }
+
+ public void process() {
+ System.out.println("SIGINTListener process");
+ // XXX - temp, should call shutdown
+ System.exit(0);
+ //PKIServer.getPKIServer().shutdown();
+ }
+}
+
+
+class SIGHUPListener extends SignalListener {
+ private OsSubsystem mOS;
+ public SIGHUPListener(OsSubsystem os) {
+ mOS = os;
+ }
+
+ public void process() {
+ System.out.println("SIGHUPListener process");
+ // XXX - temp, should call shutdown
+ // System.exit(0);
+ //PKIServer.getPKIServer().shutdown();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/PFXUtils.java b/pki/base/common/src/com/netscape/cmscore/util/PFXUtils.java
new file mode 100644
index 000000000..ed268df46
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/PFXUtils.java
@@ -0,0 +1,162 @@
+// --- 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.cmscore.util;
+
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+import java.security.*;
+import java.security.cert.*;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.pkcs12.*;
+import org.mozilla.jss.pkix.primitive.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.*;
+
+
+public class PFXUtils {
+
+ /**
+ * Creates a PKCS12 package.
+ */
+ public static byte[] createPFX(String pwd, X509Certificate x509cert,
+ byte privateKeyInfo[]) throws EBaseException {
+ try {
+ // add certificate
+ SEQUENCE encSafeContents = new SEQUENCE();
+ ASN1Value cert = new OCTET_STRING(
+ x509cert.getEncoded());
+ byte localKeyId[] = createLocalKeyId(x509cert);
+ SET certAttrs = createBagAttrs(
+ x509cert.getSubjectDN().toString(), localKeyId);
+ // attributes: user friendly name, Local Key ID
+ SafeBag certBag = new SafeBag(SafeBag.CERT_BAG,
+ new CertBag(CertBag.X509_CERT_TYPE, cert),
+ certAttrs);
+
+ encSafeContents.addElement(certBag);
+
+ // add key
+ org.mozilla.jss.util.Password pass = new
+ org.mozilla.jss.util.Password(
+ pwd.toCharArray());
+
+ SEQUENCE safeContents = new SEQUENCE();
+ PasswordConverter passConverter = new
+ PasswordConverter();
+
+ // XXX - should generate salt
+ byte salt[] = {0x01, 0x01, 0x01, 0x01};
+ PrivateKeyInfo pki = (PrivateKeyInfo)
+ ASN1Util.decode(PrivateKeyInfo.getTemplate(),
+ privateKeyInfo);
+ ASN1Value key = EncryptedPrivateKeyInfo.createPBE(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC,
+ pass, salt, 1, passConverter, pki);
+ SET keyAttrs = createBagAttrs(
+ x509cert.getSubjectDN().toString(),
+ localKeyId);
+ SafeBag keyBag = new SafeBag(
+ SafeBag.PKCS8_SHROUDED_KEY_BAG, key,
+ keyAttrs); // ??
+
+ safeContents.addElement(keyBag);
+
+ // build contents
+ AuthenticatedSafes authSafes = new
+ AuthenticatedSafes();
+
+ authSafes.addSafeContents(safeContents);
+ authSafes.addSafeContents(encSafeContents);
+
+ // authSafes.addEncryptedSafeContents(
+ // authSafes.DEFAULT_KEY_GEN_ALG,
+ // pass, null, 1,
+ // encSafeContents);
+ PFX pfx = new PFX(authSafes);
+
+ pfx.computeMacData(pass, null, 5); // ??
+ ByteArrayOutputStream fos = new
+ ByteArrayOutputStream();
+
+ pfx.encode(fos);
+ pass.clear();
+
+ // put final PKCS12 into volatile request
+ return fos.toByteArray();
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Failed to create PKCS12 - " + e.toString()));
+ }
+ }
+
+ /**
+ * Creates local key identifier.
+ */
+ public static byte[] createLocalKeyId(X509Certificate cert)
+ throws EBaseException {
+ try {
+ byte certDer[] = cert.getEncoded();
+ MessageDigest md = MessageDigest.getInstance("SHA");
+
+ md.update(certDer);
+ return md.digest();
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Failed to create Key ID - " + e.toString()));
+ }
+ }
+
+ /**
+ * Creates bag attributes.
+ */
+ public static SET createBagAttrs(String nickName, byte localKeyId[])
+ throws EBaseException {
+ try {
+ SET attrs = new SET();
+ SEQUENCE nickNameAttr = new SEQUENCE();
+
+ nickNameAttr.addElement(SafeBag.FRIENDLY_NAME);
+ SET nickNameSet = new SET();
+
+ nickNameSet.addElement(new BMPString(nickName));
+ nickNameAttr.addElement(nickNameSet);
+ attrs.addElement(nickNameAttr);
+ SEQUENCE localKeyAttr = new SEQUENCE();
+
+ localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
+ SET localKeySet = new SET();
+
+ localKeySet.addElement(new OCTET_STRING(localKeyId));
+ localKeyAttr.addElement(localKeySet);
+ attrs.addElement(localKeyAttr);
+ return attrs;
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Failed to create Key Bag - " + e.toString()));
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java b/pki/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java
new file mode 100644
index 000000000..d7ba11c02
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java
@@ -0,0 +1,294 @@
+// --- 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.cmscore.util;
+
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents a internal subsystem. This subsystem
+ * can be loaded into cert server kernel to perform
+ * run time system profiling.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ProfileSubsystem extends Frame implements ISubsystem, Runnable {
+
+ private String mId = null;
+ private Thread mMonitoring = new Thread(this);
+ private TextArea mTextArea = null;
+ private JScrollPane mThreads = null;
+ private JTable mThreadTable = null;
+ private JButton mGC = null;
+ private ThreadTableModel mThreadModel = null;
+
+ /**
+ * Constructs a certificate server.
+ */
+ public ProfileSubsystem() {
+ super();
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * Initializes this subsystem with the given
+ * configuration store.
+ * It first initializes resident subsystems,
+ * and it loads and initializes loadable
+ * subsystem specified in the configuration
+ * store.
+ * <P>
+ * Note that individual subsystem should be
+ * initialized in a separated thread if
+ * it has dependency on the initialization
+ * of other subsystems.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ */
+ public synchronized void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ JTabbedPane tabPane = new JTabbedPane();
+
+ // general panel
+ JPanel pane = new JPanel();
+
+ mTextArea = new TextArea();
+ // mTextArea.setSize(500, 180);
+ //mGC = new JButton("GC");
+ // pane.setLayout(new GridLayout(2, 1));
+ pane.add(mTextArea);
+ // pane.add(mGC);
+ mTextArea.setEditable(false);
+ tabPane.addTab("General", mTextArea);
+ tabPane.setSelectedIndex(0);
+
+ // thread panel
+ mThreadModel = new ThreadTableModel();
+ updateThreadPanel();
+ mThreadTable = new JTable(mThreadModel);
+ // table.setEditable(false);
+ mThreads = JTable.createScrollPaneForTable(mThreadTable);
+ tabPane.addTab("Threads", mThreads);
+
+ mThreadTable.addMouseListener(new ThreadTableEvent(mThreadTable));
+
+ add(tabPane);
+ setSize(500, 200);
+ setVisible(true);
+ mMonitoring.start();
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Stops this system.
+ */
+ public synchronized void shutdown() {
+ }
+
+ /*
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+
+ public void updateGeneralPanel() {
+ Runtime.getRuntime().gc();
+ String text =
+ "JDK VM Information " + "\n" +
+ "Total Memory: " +
+ Runtime.getRuntime().totalMemory() + "\n" +
+ "Used Memory: " +
+ (Runtime.getRuntime().totalMemory() -
+ Runtime.getRuntime().freeMemory()) + "\n" +
+ "Free Memory: " +
+ Runtime.getRuntime().freeMemory() + "\n" +
+ "Number of threads: " +
+ Thread.activeCount() + "\n";
+
+ mTextArea.setText(text);
+ }
+
+ public void updateThreadPanel() {
+ Thread currentThread = Thread.currentThread();
+ Vector data = new Vector();
+ Thread threads[] = new Thread[100];
+ int numThreads = Thread.enumerate(threads);
+
+ for (int i = 0; i < numThreads; i++) {
+ Vector row = new Vector();
+
+ row.addElement(threads[i].getName());
+ row.addElement(threads[i].getThreadGroup().getName());
+ row.addElement(Integer.toString(threads[i].getPriority()));
+ if (currentThread.getName().equals(threads[i].getName())) {
+ row.addElement("true");
+ } else {
+ row.addElement("false");
+ }
+ row.addElement(Boolean.toString(threads[i].isInterrupted()));
+ row.addElement(Boolean.toString(threads[i].isDaemon()));
+ data.addElement(row);
+ }
+
+ Vector colNames = new Vector();
+
+ colNames.addElement("Name");
+ colNames.addElement("Group");
+ colNames.addElement("Priority");
+ colNames.addElement("isCurrent");
+ colNames.addElement("isInterrupted");
+ colNames.addElement("isDaemon");
+
+ mThreadModel.setInfo(data, colNames);
+ if (mThreadTable != null) {
+ mThreadTable.setModel(mThreadModel);
+ mThreadTable.updateUI();
+ }
+ }
+
+ public void run() {
+ while (true) {
+ // To get exact memory statistics
+ try {
+ updateGeneralPanel();
+ updateThreadPanel();
+ // update every second
+ mMonitoring.sleep(1000);
+ } catch (Exception e) {
+ }
+ }
+ }
+}
+
+
+class ThreadTableModel extends AbstractTableModel {
+ Vector rowData;
+ Vector columnNames;
+
+ public ThreadTableModel() {
+ }
+
+ public void setInfo(Vector _rowData, Vector _columnNames) {
+ rowData = _rowData;
+ columnNames = _columnNames;
+ }
+
+ public String getColumnName(int column) {
+ return columnNames.elementAt(column).toString();
+ }
+
+ public int getRowCount() {
+ return rowData.size();
+ }
+
+ public int getColumnCount() {
+ return columnNames.size();
+ }
+
+ public Object getValueAt(int row, int column) {
+ return ((Vector) rowData.elementAt(row)).elementAt(column);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return false;
+ }
+
+ public void setValueAt(Object value, int row, int column) {
+ ((Vector) rowData.elementAt(row)).setElementAt(value, column);
+ fireTableCellUpdated(row, column);
+ }
+}
+
+
+class ThreadTableEvent extends MouseAdapter {
+
+ private JTable mThreadTable = null;
+
+ public ThreadTableEvent(JTable table) {
+ mThreadTable = table;
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ int row = mThreadTable.getSelectedRow();
+
+ if (row != -1) {
+ String name = (String) mThreadTable.getValueAt(row, 0);
+ JDialog dialog = new JDialog();
+ JTextArea field = new JTextArea();
+ JScrollPane pane = new JScrollPane(field);
+
+ field.setEditable(false);
+
+ // get stack trace
+ Thread threads[] = new Thread[100];
+ int numThreads = Thread.enumerate(threads);
+
+ ByteArrayOutputStream outArray = new ByteArrayOutputStream();
+
+ for (int i = 0; i < numThreads; i++) {
+ if (!threads[i].getName().equals(name))
+ continue;
+ PrintStream err = System.err;
+
+ System.setErr(new PrintStream(outArray));
+ threads[i].dumpStack(); // not working, print only current thread
+ System.setErr(err);
+ }
+
+ String str = outArray.toString();
+
+ field.setText(str);
+ dialog.setTitle(name);
+ dialog.setSize(500, 400);
+ dialog.setVisible(true);
+
+ dialog.setContentPane(pane);
+ dialog.show();
+ }
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java b/pki/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java
new file mode 100644
index 000000000..ba07b2ca0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java
@@ -0,0 +1,210 @@
+// --- 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.cmscore.util;
+
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.apps.*;
+
+/**
+ * A class represents a internal subsystem. This subsystem
+ * can be loaded into cert server kernel to perform
+ * statistics collection.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StatsSubsystem implements IStatsSubsystem
+{
+ private String mId = null;
+ private StatsEvent mAllTrans = new StatsEvent(null);
+ private Date mStartTime = new Date();
+ private Hashtable mHashtable = new Hashtable();
+
+ /**
+ * Constructs a certificate server.
+ */
+ public StatsSubsystem() {
+ super();
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * Initializes this subsystem with the given
+ * configuration store.
+ * It first initializes resident subsystems,
+ * and it loads and initializes loadable
+ * subsystem specified in the configuration
+ * store.
+ * <P>
+ * Note that individual subsystem should be
+ * initialized in a separated thread if
+ * it has dependency on the initialization
+ * of other subsystems.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ */
+ public synchronized void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException
+ {
+ }
+
+ public Date getStartTime()
+ {
+ return mStartTime;
+ }
+
+ public void startTiming(String id)
+ {
+ startTiming(id, false /* not the main */);
+ }
+
+ public void startTiming(String id, boolean mainAction)
+ {
+ Thread t = Thread.currentThread();
+ Vector milestones = null;
+ if (mHashtable.containsKey(t.toString())) {
+ milestones = (Vector)mHashtable.get(t.toString());
+ } else {
+ milestones = new Vector();
+ mHashtable.put(t.toString(), milestones);
+ }
+ long startTime = CMS.getCurrentDate().getTime();
+ StatsEvent currentST = null;
+ for (int i = 0; i < milestones.size(); i++) {
+ StatsMilestone se = (StatsMilestone)milestones.elementAt(i);
+ if (currentST == null) {
+ currentST = mAllTrans.getSubEvent(se.getId());
+ } else {
+ currentST = currentST.getSubEvent(se.getId());
+ }
+ }
+ if (currentST == null) {
+ if (!mainAction) {
+ return; /* ignore none main action */
+ }
+ currentST = mAllTrans;
+ }
+ StatsEvent newST = currentST.getSubEvent(id);
+ if (newST == null) {
+ newST = new StatsEvent(currentST);
+ newST.setName(id);
+ currentST.addSubEvent(newST);
+ }
+ milestones.addElement(new StatsMilestone(id, startTime, newST));
+ }
+
+ public void endTiming(String id)
+ {
+ long endTime = CMS.getCurrentDate().getTime();
+ Thread t = Thread.currentThread();
+ if (!mHashtable.containsKey(t.toString())) {
+ return; /* error */
+ }
+ Vector milestones = (Vector)mHashtable.get(t.toString());
+ if (milestones.size() == 0) {
+ return; /* error */
+ }
+ StatsMilestone last = (StatsMilestone)milestones.remove(milestones.size() - 1);
+ StatsEvent st = last.getStatsEvent();
+ st.incNoOfOperations(1);
+ st.incTimeTaken(endTime - last.getStartTime());
+ if (milestones.size() == 0) {
+ mHashtable.remove(t.toString());
+ }
+ }
+
+ public void resetCounters()
+ {
+ mStartTime = CMS.getCurrentDate();
+ mAllTrans.resetCounters();
+ }
+
+ public StatsEvent getMainStatsEvent()
+ {
+ return mAllTrans;
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Stops this system.
+ */
+ public synchronized void shutdown() {
+ }
+
+ /*
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+}
+
+class StatsMilestone
+{
+ private String mId = null;
+ private long mStartTime = 0;
+ private StatsEvent mST = null;
+
+ public StatsMilestone(String id, long startTime, StatsEvent st)
+ {
+ mId = id;
+ mStartTime = startTime;
+ mST = st;
+ }
+
+ public String getId()
+ {
+ return mId;
+ }
+
+ public long getStartTime()
+ {
+ return mStartTime;
+ }
+
+ public StatsEvent getStatsEvent()
+ {
+ return mST;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/UtilMessage.java b/pki/base/common/src/com/netscape/cmscore/util/UtilMessage.java
new file mode 100644
index 000000000..e9b2a6cdd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/UtilMessage.java
@@ -0,0 +1,179 @@
+// --- 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.cmscore.util;
+
+
+import com.netscape.certsrv.base.MessageFormatter;
+import java.util.Locale;
+
+
+/**
+ * This object is used to easily create I18N messages for utility
+ * classes and standalone programs.
+ *
+ * @author mikep
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.base.MessageFormatter
+ * @see com.netscape.cmscore.util.UtilResources
+ */
+public class UtilMessage {
+
+ protected Object mParams[] = null;
+
+ private String mMessage = null;
+
+ /**
+ * The bundle name for this event.
+ */
+ static String mBundleName = UtilResources.class.getName();
+
+ /**
+ * Constructs a message event
+ * <P>
+ *
+ * @param msgFormat the message string
+ */
+ public UtilMessage(String msgFormat) {
+ mMessage = msgFormat;
+ mParams = null;
+ }
+
+ /**
+ * Constructs a message with a parameter. For example,
+ * <PRE>
+ * new UtilMessage("failed to load {0}", fileName);
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat details in message string format
+ * @param param message string parameter
+ */
+ public UtilMessage(String msgFormat, String param) {
+ this(msgFormat);
+ mParams = new String[1];
+ mParams[0] = param;
+ }
+
+ /**
+ * Constructs a message from an exception. It can be used to carry
+ * a system exception that may contain information about
+ * the context. For example,
+ * <PRE>
+ * try {
+ * ...
+ * } catch (IOExeption e) {
+ * out.println(new UtilMessage("Encountered System Error {0}", e);
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param msgFormat exception details in message string format
+ * @param exception system exception
+ */
+ public UtilMessage(String msgFormat, Exception exception) {
+ this(msgFormat);
+ mParams = new Exception[1];
+ mParams[0] = exception;
+ }
+
+ /**
+ * Constructs a message from a base exception. This will use the msgFormat
+ * from the exception itself.
+ * <PRE>
+ * try {
+ * ...
+ * } catch (Exception e) {
+ * System.out.println(new UtilMessage(e));
+ * }
+ * </PRE>
+ * <P>
+ *
+ * @param exception CMS exception
+ */
+ public UtilMessage(Exception e) {
+ this(e.getMessage());
+ mParams = new Exception[1];
+ mParams[0] = e;
+ }
+
+ /**
+ * Constructs a message event with a list of parameters
+ * that will be substituted into the message format.
+ * <P>
+ *
+ * @param msgFormat message string format
+ * @param params list of message format parameters
+ */
+ public UtilMessage(String msgFormat, Object params[]) {
+ this(msgFormat);
+ mParams = params;
+ }
+
+ /**
+ * Returns the current message format string.
+ * <P>
+ *
+ * @return details message
+ */
+ public String getMessage() {
+ return mMessage;
+ }
+
+ /**
+ * Returns a list of parameters.
+ * <P>
+ *
+ * @return list of message format parameters
+ */
+ public Object[] getParameters() {
+ return mParams;
+ }
+
+ /**
+ * Returns localized message string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return details message
+ */
+ public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * <P>
+ *
+ * @param locale locale
+ * @return details message
+ */
+ public String toString(Locale locale) {
+ return MessageFormatter.getLocalizedString(locale, getBundleName(),
+ getMessage(),
+ getParameters());
+ }
+
+ /**
+ * Gets the resource bundle name for this class instance. This should
+ * be overridden by subclasses who have their own resource bundles.
+ */
+ protected String getBundleName() {
+ return mBundleName;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/util/UtilResources.java b/pki/base/common/src/com/netscape/cmscore/util/UtilResources.java
new file mode 100644
index 000000000..8114413b0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/util/UtilResources.java
@@ -0,0 +1,74 @@
+// --- 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.cmscore.util;
+
+
+import java.util.*;
+
+
+/**
+ * A class represents a resource bundle for miscellanous utilities
+ * <P>
+ *
+ * @author mikep
+ * @version $Revision$, $Date$
+ * @see java.util.ListResourceBundle
+ */
+public class UtilResources extends ListResourceBundle {
+
+ /**
+ * Returns the content of this resource.
+ */
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ /**
+ * Constants. The suffix represents the number of
+ * possible parameters.
+ */
+ public final static String HASH_FILE_CHECK_USAGE = "hashFileCheckUsage";
+ public final static String BAD_ARG_COUNT = "badArgCount";
+ public final static String NO_SUCH_FILE_1 = "noSuchFile";
+ public final static String DIGEST_MATCH_1 = "digestMatch";
+ public final static String DIGEST_DONT_MATCH_1 = "digestDontMatch";
+ public final static String FILE_TRUNCATED = "fileTruncated";
+ public final static String EXCEPTION_1 = "exception";
+ public final static String LOG_PASSWORD = "logPassword";
+ public final static String NO_USERID = "noUserId";
+ public final static String NO_SUCH_USER_2 = "noSuchUser";
+ public final static String NO_UID_PERMISSION_2 = "noUidPermission";
+ public final static String SHUTDOWN_SIG = "shutdownSignal";
+ public final static String RESTART_SIG = "restartSignal";
+
+ static final Object[][] contents = {
+ {HASH_FILE_CHECK_USAGE, "usage: HashFileCheck <filename>"},
+ {BAD_ARG_COUNT, "incorrect number of arguments"},
+ {NO_SUCH_FILE_1, "can''t find file {0}"},
+ {FILE_TRUNCATED, "Log file has been truncated."},
+ {DIGEST_MATCH_1, "Hash digest matches log file. {0} OK"},
+ {DIGEST_DONT_MATCH_1, "Hash digest does NOT match log file. {0} and/or hash file is corrupt or the password is incorrect."},
+ {EXCEPTION_1, "Caught unexpected exception {0}"},
+ {LOG_PASSWORD, "Please enter the log file hash digest password: "},
+ {NO_USERID, "No user id in config file. Running as {0}"},
+ {NO_SUCH_USER_2, "No such user as {0}. Running as {1}"},
+ {NO_UID_PERMISSION_2, "Can''t change process uid to {0}. Running as {1}"},
+ {SHUTDOWN_SIG, "Received shutdown signal"},
+ {RESTART_SIG, "Received restart signal"},
+ };
+}
diff --git a/pki/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java b/pki/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java
new file mode 100644
index 000000000..3977b05c5
--- /dev/null
+++ b/pki/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java
@@ -0,0 +1,540 @@
+package com.netscape.certsrv.app;
+
+import com.netscape.certsrv.apps.ICMSEngine;
+import com.netscape.certsrv.apps.ICommandQueue;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.connector.*;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.notification.*;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.cmsutil.net.ISocketFactory;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+import java.util.*;
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CRL;
+import java.security.NoSuchAlgorithmException;
+
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.GeneralName;
+import netscape.security.util.ObjectIdentifier;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import org.mozilla.jss.util.PasswordCallback;
+
+/**
+ * Default engine stub for testing.
+ */
+public class CMSEngineDefaultStub implements ICMSEngine {
+ public String getId() {
+ return null;
+ }
+
+ public void setId(String id) throws EBaseException {
+ }
+
+ public void init(ISubsystem owner, IConfigStore config) throws EBaseException {
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+
+ public int getpid() {
+ return 0;
+ }
+
+ public void reinit(String id) throws EBaseException {
+ }
+
+ public int getCSState() {
+ return 0;
+ }
+
+ public void setCSState(int mode) {
+ }
+
+ public boolean isPreOpMode() {
+ return false;
+ }
+
+ public boolean isRunningMode() {
+ return false;
+ }
+
+ public String getInstanceDir() {
+ return null;
+ }
+
+ public Date getCurrentDate() {
+ return null;
+ }
+
+ public long getStartupTime() {
+ return 0;
+ }
+
+ public boolean isInRunningState() {
+ return false;
+ }
+
+ public Enumeration getSubsystemNames() {
+ return null;
+ }
+
+ public Enumeration getSubsystems() {
+ return null;
+ }
+
+ public ISubsystem getSubsystem(String name) {
+ return null;
+ }
+
+ public ILogger getLogger() {
+ return null;
+ }
+
+ public ILogger getSignedAuditLogger() {
+ return null;
+ }
+
+ public void debug(byte data[]) {
+ }
+
+ public void debug(String msg) {
+ }
+
+ public void debug(int level, String msg) {
+ }
+
+ public void debug(Throwable e) {
+ }
+
+ public boolean debugOn() {
+ return false;
+ }
+
+ public void debugStackTrace() {
+ }
+
+ public void traceHashKey(String type, String key) {
+ }
+
+ public void traceHashKey(String type, String key, String val) {
+ }
+
+ public void traceHashKey(String type, String key, String val, String def) {
+ }
+
+ public byte[] getPKCS7(Locale locale, IRequest req) {
+ return new byte[0];
+ }
+
+ public String getUserMessage(Locale locale, String msgID) {
+ return null;
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p[]) {
+ return null;
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p1) {
+ return null;
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p1, String p2) {
+ return null;
+ }
+
+ public String getUserMessage(Locale locale, String msgID, String p1, String p2, String p3) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p[]) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8) {
+ return null;
+ }
+
+ public String getLogMessage(String msgID, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+ return null;
+ }
+
+ public IACL parseACL(String resACLs) throws EACLsException {
+ return null;
+ }
+
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return null;
+ }
+
+ public String getCRLIssuingPointRecordName() {
+ return null;
+ }
+
+ public String getFingerPrint(Certificate cert) throws CertificateEncodingException, NoSuchAlgorithmException {
+ return null;
+ }
+
+ public String getFingerPrints(Certificate cert) throws NoSuchAlgorithmException, CertificateEncodingException {
+ return null;
+ }/*
+ * Returns the finger print of the given certificate.
+*
+* @param certDer DER byte array of certificate
+* @return finger print of certificate
+*/
+public String getFingerPrints(byte[] certDer) throws NoSuchAlgorithmException {
+ return null;
+}
+
+ public IRepositoryRecord createRepositoryRecord() {
+ return null;
+ }
+
+ public IPKIMessage getHttpPKIMessage() {
+ return null;
+ }
+
+ public IRequestEncoder getHttpRequestEncoder() {
+ return null;
+ }
+
+ public String BtoA(byte data[]) {
+ return null;
+ }
+
+ public byte[] AtoB(String data) {
+ return new byte[0];
+ }
+
+ public String getEncodedCert(X509Certificate cert) {
+ return null;
+ }
+
+ public IPrettyPrintFormat getPrettyPrintFormat(String delimiter) {
+ return null;
+ }
+
+ public IExtPrettyPrint getExtPrettyPrint(Extension e, int indent) {
+ return null;
+ }
+
+ public ICertPrettyPrint getCertPrettyPrint(X509Certificate cert) {
+ return null;
+ }
+
+ public ICRLPrettyPrint getCRLPrettyPrint(X509CRL crl) {
+ return null;
+ }
+
+ public ICRLPrettyPrint getCRLCachePrettyPrint(ICRLIssuingPoint ip) {
+ return null;
+ }
+
+ public ILdapConnInfo getLdapConnInfo(IConfigStore config) throws EBaseException, ELdapException {
+ return null;
+ }
+
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory(String certNickname) {
+ return null;
+ }
+
+ public LDAPSSLSocketFactoryExt getLdapJssSSLSocketFactory() {
+ return null;
+ }
+
+ public ILdapAuthInfo getLdapAuthInfo() {
+ return null;
+ }
+
+ public ILdapConnFactory getLdapBoundConnFactory() throws ELdapException {
+ return null;
+ }
+
+ public LDAPConnection getBoundConnection(String host, int port, int version, LDAPSSLSocketFactoryExt fac, String bindDN, String bindPW) throws LDAPException {
+ return null;
+ }
+
+ public ILdapConnFactory getLdapAnonConnFactory() throws ELdapException {
+ return null;
+ }
+
+ public IPasswordCheck getPasswordChecker() {
+ return null;
+ }
+
+ public void putPasswordCache(String tag, String pw) {
+ }
+
+ public PasswordCallback getPasswordCallback() {
+ return null;
+ }
+
+ public String getServerCertNickname() {
+ return null;
+ }
+
+ public void setServerCertNickname(String tokenName, String nickName) {
+ }
+
+ public void setServerCertNickname(String newName) {
+ }
+
+ public String getEEHost() {
+ return null;
+ }
+
+ public String getEENonSSLHost() {
+ return null;
+ }
+
+ public String getEENonSSLIP() {
+ return null;
+ }
+
+ public String getEENonSSLPort() {
+ return null;
+ }
+
+ public String getEESSLHost() {
+ return null;
+ }
+
+ public String getEESSLIP() {
+ return null;
+ }
+
+ public String getEESSLPort() {
+ return null;
+ }
+
+ public String getAgentHost() {
+ return null;
+ }
+
+ public String getAgentIP() {
+ return null;
+ }
+
+ public String getAgentPort() {
+ return null;
+ }
+
+ public String getAdminHost() {
+ return null;
+ }
+
+ public String getAdminIP() {
+ return null;
+ }
+
+ public String getAdminPort() {
+ return null;
+ }
+
+ public boolean isSigningCert(X509Certificate cert) {
+ return false;
+ }
+
+ public boolean isEncryptionCert(X509Certificate cert) {
+ return false;
+ }
+
+ public X509CertInfo getDefaultX509CertInfo() {
+ return null;
+ }
+
+ public IEmailFormProcessor getEmailFormProcessor() {
+ return null;
+ }
+
+ public IEmailTemplate getEmailTemplate(String path) {
+ return null;
+ }
+
+ public IMailNotification getMailNotification() {
+ return null;
+ }
+
+ public IEmailResolverKeys getEmailResolverKeys() {
+ return null;
+ }
+
+ public IEmailResolver getReqCertSANameEmailResolver() {
+ return null;
+ }
+
+ public ObjectIdentifier checkOID(String attrName, String value) throws EBaseException {
+ return null;
+ }
+
+ public GeneralName form_GeneralNameAsConstraints(String generalNameChoice, String value) throws EBaseException {
+ return null;
+ }
+
+ public GeneralName form_GeneralName(String generalNameChoice, String value) throws EBaseException {
+ return null;
+ }
+
+ public void getGeneralNameConfigDefaultParams(String name, boolean isValueConfigured, Vector params) {
+ }
+
+ public void getGeneralNamesConfigDefaultParams(String name, boolean isValueConfigured, Vector params) {
+ }
+
+ public void getGeneralNameConfigExtendedPluginInfo(String name, boolean isValueConfigured, Vector info) {
+ }
+
+ public void getGeneralNamesConfigExtendedPluginInfo(String name, boolean isValueConfigured, Vector info) {
+ }
+
+ public IGeneralNamesConfig createGeneralNamesConfig(String name, IConfigStore config, boolean isValueConfigured, boolean isPolicyEnabled) throws EBaseException {
+ return null;
+ }
+
+ public IGeneralNameAsConstraintsConfig createGeneralNameAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured, boolean isPolicyEnabled) throws EBaseException {
+ return null;
+ }
+
+ public IGeneralNamesAsConstraintsConfig createGeneralNamesAsConstraintsConfig(String name, IConfigStore config, boolean isValueConfigured, boolean isPolicyEnabled) throws EBaseException {
+ return null;
+ }
+
+ public void getSubjAltNameConfigDefaultParams(String name, Vector params) {
+ }
+
+ public void getSubjAltNameConfigExtendedPluginInfo(String name, Vector params) {
+ }
+
+ public ISubjAltNameConfig createSubjAltNameConfig(String name, IConfigStore config, boolean isValueConfigured) throws EBaseException {
+ return null;
+ }
+
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority, ISocketFactory factory) {
+ return null;
+ }
+
+ public IHttpConnection getHttpConnection(IRemoteAuthority authority, ISocketFactory factory, int timeout) {
+ return null;
+ }
+
+ public IResender getResender(IAuthority authority, String nickname, IRemoteAuthority remote, int interval) {
+ return null;
+ }
+
+ public ICommandQueue getCommandQueue() {
+ return null;
+ }
+
+ public void disableRequests() {
+ }
+
+ public void terminateRequests() {
+ }
+
+ public boolean areRequestsDisabled() {
+ return false;
+ }
+
+ public IConfigStore createFileConfigStore(String path) throws EBaseException {
+ return null;
+ }
+
+ public IArgBlock createArgBlock() {
+ return null;
+ }
+
+ public IArgBlock createArgBlock(String realm, Hashtable httpReq) {
+ return null;
+ }
+
+ public IArgBlock createArgBlock(Hashtable httpReq) {
+ return null;
+ }
+
+ public boolean isRevoked(X509Certificate[] certificates) {
+ return false;
+ }
+
+ public void setListOfVerifiedCerts(int size, long interval, long unknownStateInterval) {
+ }
+
+ public void forceShutdown() {
+ }
+
+ public IPasswordStore getPasswordStore() {
+ return null;
+ }
+
+ public ISecurityDomainSessionTable getSecurityDomainSessionTable() {
+ return null;
+ }
+
+ public void setConfigSDSessionId(String id) {
+ }
+
+ public String getConfigSDSessionId() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java b/pki/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java
new file mode 100644
index 000000000..0df5ac1aa
--- /dev/null
+++ b/pki/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java
@@ -0,0 +1,274 @@
+package com.netscape.certsrv.authentication;
+
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.certsrv.app.CMSEngineDefaultStub;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.usrgrp.Certificates;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Date;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.io.IOException;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.util.DerValue;
+import netscape.security.util.DerOutputStream;
+
+public class AuthTokenTest extends CMSBaseTestCase {
+
+ AuthToken authToken;
+ CMSMemoryStub cmsStub;
+
+ public AuthTokenTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ authToken = new AuthToken(null);
+
+ // this is needed because of CMS.AtoB/BtoA calls
+ cmsStub = new CMSMemoryStub();
+ CMS.setCMSEngine(cmsStub);
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(AuthTokenTest.class);
+ }
+
+ public void testGetSetString() {
+ authToken.set("key", "value");
+ assertEquals("value", authToken.mAttrs.get("key"));
+ assertEquals("value", authToken.getInString("key"));
+
+ assertFalse(authToken.set("key", (String)null));
+ }
+
+ public void testGetSetByteArray() {
+ byte[] data = new byte[] { -12, 0, 14, 15 };
+
+ assertFalse(cmsStub.bToACalled);
+ authToken.set("key", data);
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ byte[] retval = authToken.getInByteArray("key");
+ assertEquals(data, retval);
+
+ assertFalse(authToken.set("key2", (byte[])null));
+ }
+
+ public void testGetSetInteger() {
+ authToken.set("key", Integer.valueOf(432));
+ assertEquals("432", authToken.mAttrs.get("key"));
+ assertEquals(Integer.valueOf(432), authToken.getInInteger("key"));
+
+ assertNull(authToken.getInInteger("notfound"));
+
+ authToken.set("key2", "value");
+ assertNull(authToken.getInInteger("key2"));
+
+ assertFalse(authToken.set("key3", (Integer)null));
+ }
+
+ public void testGetSetBigIntegerArray() {
+ BigInteger[] data = new BigInteger[] {
+ new BigInteger("111111111"),
+ new BigInteger("222222222"),
+ new BigInteger("333333333")
+ };
+ authToken.set("key", data);
+ assertEquals("111111111,222222222,333333333",
+ authToken.mAttrs.get("key"));
+ BigInteger[] retval = authToken.getInBigIntegerArray("key");
+ assertEquals(3, retval.length);
+ assertEquals(data[0], retval[0]);
+ assertEquals(data[1], retval[1]);
+ assertEquals(data[2], retval[2]);
+
+ authToken.set("key2", "123456");
+ retval = authToken.getInBigIntegerArray("key2");
+ assertEquals(1, retval.length);
+ assertEquals(new BigInteger("123456"), retval[0]);
+
+ authToken.set("key3", "oops");
+ assertNull(authToken.getInBigIntegerArray("key3"));
+
+ // corner case test
+ authToken.set("key",",");
+ retval = authToken.getInBigIntegerArray("key");
+ assertNull(retval);
+
+ assertFalse(authToken.set("key4", (BigInteger[])null));
+ }
+
+ public void testGetSetDate() {
+ Date value = new Date();
+ authToken.set("key", value);
+ assertEquals(String.valueOf(value.getTime()),
+ authToken.mAttrs.get("key"));
+ assertEquals(value, authToken.getInDate("key"));
+
+ authToken.set("key2", "234567");
+ Date retval = authToken.getInDate("key2");
+ assertEquals(234567L, retval.getTime());
+
+ authToken.set("key3", "oops");
+ assertNull(authToken.getInDate("key3"));
+
+ assertFalse(authToken.set("key4", (Date)null));
+ }
+
+ public void testGetSetStringArray() throws IOException {
+ String[] value = new String[] {
+ "eenie", "meenie", "miny", "moe"
+ };
+
+ assertFalse(cmsStub.bToACalled);
+ authToken.set("key", value);
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ String[] retval = authToken.getInStringArray("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertEquals(4, retval.length);
+ assertEquals(value[0], retval[0]);
+ assertEquals(value[1], retval[1]);
+ assertEquals(value[2], retval[2]);
+ assertEquals(value[3], retval[3]);
+
+ // illegal value parsing
+ authToken.set("key2", new byte[] { 1, 2, 3, 4});
+ assertNull(authToken.getInStringArray("key2"));
+
+
+ DerOutputStream out = new DerOutputStream();
+ out.putPrintableString("testing");
+ authToken.set("key3", out.toByteArray());
+ assertNull(authToken.getInStringArray("key3"));
+
+ assertFalse(authToken.set("key4", (String[])null));
+ }
+
+ public void testGetSetCert() throws CertificateException {
+ X509CertImpl cert = getFakeCert();
+
+ assertFalse(cmsStub.bToACalled);
+ authToken.set("key", cert);
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ X509CertImpl retval = authToken.getInCert("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertNotNull(retval);
+ assertEquals(cert, retval);
+
+ assertFalse(authToken.set("key2", (X509CertImpl)null));
+ }
+
+ public void testGetSetCertExts() throws IOException {
+ CertificateExtensions certExts = new CertificateExtensions();
+ BasicConstraintsExtension ext = new BasicConstraintsExtension(false, 1);
+
+ assertTrue(authToken.set("key", certExts));
+ assertTrue(authToken.mAttrs.containsKey("key"));
+ CertificateExtensions retval = authToken.getInCertExts("key");
+ assertNotNull(retval);
+ assertEquals(0, retval.size());
+
+ certExts.set(PKIXExtensions.BasicConstraints_Id.toString(), ext);
+ assertTrue(authToken.set("key2", certExts));
+
+ retval = authToken.getInCertExts("key2");
+ assertTrue(authToken.mAttrs.containsKey("key2"));
+ assertNotNull(retval);
+ assertEquals(1, retval.size());
+
+ assertFalse(authToken.set("key3", (CertificateExtensions)null));
+ }
+
+ public void testGetSetCertificates() throws CertificateException {
+ X509CertImpl cert1 = getFakeCert();
+ X509CertImpl cert2 = getFakeCert();
+ X509CertImpl[] certArray = new X509CertImpl[] {cert1, cert2};
+ Certificates certs = new Certificates(certArray);
+
+ assertFalse(cmsStub.bToACalled);
+ authToken.set("key", certs);
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ Certificates retval = authToken.getInCertificates("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertNotNull(retval);
+
+ X509Certificate[] retCerts = retval.getCertificates();
+ assertEquals(2, retCerts.length);
+ assertEquals(cert1, retCerts[0]);
+ assertEquals(cert2, retCerts[1]);
+
+ assertFalse(authToken.set("key2", (Certificates)null));
+ }
+
+ public void testGetSetByteArrayArray() {
+ byte[][] value = new byte[][] {
+ new byte[] { 1, 2, 3, 4 },
+ new byte[] {12, 13, 14},
+ new byte[] { 50, -12, 0, 100}
+ };
+
+ assertFalse(cmsStub.bToACalled);
+ assertTrue(authToken.set("key", value));
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ byte[][] retval = authToken.getInByteArrayArray("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertNotNull(retval);
+ assertEquals(value.length, retval.length);
+ for (int i = 0; i < value.length; i++) {
+ assertEquals(value[i].length, retval[i].length);
+ for (int j = 0; j < value[i].length; j++) {
+ assertEquals(value[i][j], retval[i][j]);
+ }
+ }
+
+ assertFalse(authToken.set("key2", (byte[][])null));
+ }
+
+ /**
+ * CMSMemoryStub
+ *
+ * This class is used to help test methods that rely on setting and then
+ * getting a value out. It assumes BtoA is always called first, stores
+ * the value passed in, and then returns that value for BtoA.
+ */
+ class CMSMemoryStub extends CMSEngineDefaultStub {
+ boolean bToACalled = false;
+ byte[] bToACalledWith = null;
+
+ boolean aToBCalled = false;
+ String aToBCalledWith = null;
+
+ public String BtoA(byte data[]) {
+ bToACalled = true;
+ bToACalledWith = data;
+ return "garbagetostoreinthehash";
+ }
+
+ public byte[] AtoB(String data) {
+ aToBCalled = true;
+ aToBCalledWith = data;
+ return bToACalledWith;
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java b/pki/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java
new file mode 100644
index 000000000..b7772bb27
--- /dev/null
+++ b/pki/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java
@@ -0,0 +1,70 @@
+package com.netscape.certsrv.logging;
+
+import java.util.Properties;
+
+/**
+ * Default logging stub for testing.
+ */
+public class LoggerDefaultStub implements ILogger {
+ public void log(int evtClass, int source, String msg) {
+ }
+
+ public void log(int evtClass, Properties props, int source, String msg) {
+ }
+
+ public void log(int evtClass, int source, int level, String msg) {
+ }
+
+ public void log(int evtClass, Properties props, int source, int level, String msg) {
+ }
+
+ public void log(int evtClass, int source, int level, String msg, Object param) {
+ }
+
+ public void log(int evtClass, int source, int level, String msg, Object params[]) {
+ }
+
+ public void log(int evtClass, Properties props, int source, String msg, Object param) {
+ }
+
+ public void log(int evtClass, Properties props, int source, int level, String msg, Object param) {
+ }
+
+ public void log(int evtClass, Properties prop, int source, int level, String msg, Object params[]) {
+ }
+
+ public void log(int evtClass, int source, String msg, boolean multiline) {
+ }
+
+ public void log(int evtClass, Properties props, int source, String msg, boolean multiline) {
+ }
+
+ public void log(int evtClass, int source, int level, String msg, boolean multiline) {
+ }
+
+ public void log(int evtClass, Properties props, int source, int level, String msg, boolean multiline) {
+ }
+
+ public void log(int evtClass, int source, int level, String msg, Object param, boolean multiline) {
+ }
+
+ public void log(int evtClass, Properties props, int source, String msg, Object param, boolean multiline) {
+ }
+
+ public void log(int evtClass, Properties props, int source, int level, String msg, Object param, boolean multiline) {
+ }
+
+ public void log(int evtClass, Properties prop, int source, int level, String msg, Object params[], boolean multiline) {
+ }
+
+ public ILogEvent create(int evtClass, Properties prop, int source, int level, String msg, Object params[], boolean multiline) {
+ return null;
+ }
+
+ public void register(int evtClass, ILogEventFactory f) {
+ }
+
+ public ILogQueue getLogQueue() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java b/pki/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java
new file mode 100644
index 000000000..222944a7e
--- /dev/null
+++ b/pki/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java
@@ -0,0 +1,81 @@
+package com.netscape.certsrv.request;
+
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Vector;
+
+public class AgentApprovalsTest extends CMSBaseTestCase {
+
+ AgentApprovals agentApprovals;
+
+ public AgentApprovalsTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ agentApprovals = new AgentApprovals();
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(AgentApprovalsTest.class);
+ }
+
+ public void testToFromStringVector() {
+ AgentApproval approval1 = new AgentApproval("user1");
+ AgentApproval approval2 = new AgentApproval("user2");
+ AgentApproval approval3 = new AgentApproval(";user4;messy name");
+ agentApprovals.mVector.add(approval1);
+ agentApprovals.mVector.add(approval2);
+ agentApprovals.mVector.add(approval3);
+
+ Vector stringVector = agentApprovals.toStringVector();
+ assertNotNull(stringVector);
+ assertEquals(3, stringVector.size());
+ assertEquals(approval1.getDate().getTime() + ";" + approval1.getUserName(),
+ stringVector.get(0));
+ assertEquals(approval2.getDate().getTime() + ";" + approval2.getUserName(),
+ stringVector.get(1));
+ assertEquals(approval3.getDate().getTime() + ";" + approval3.getUserName(),
+ stringVector.get(2));
+
+ AgentApprovals approvals = AgentApprovals.fromStringVector(stringVector);
+ assertNotNull(approvals);
+ assertEquals(3, approvals.mVector.size());
+
+ AgentApproval approval = (AgentApproval)approvals.mVector.get(0);
+ assertEquals(approval1.getUserName(), approval.getUserName());
+ assertEquals(approval1.getDate(), approval.getDate());
+
+ approval = (AgentApproval)approvals.mVector.get(1);
+ assertEquals(approval2.getUserName(), approval.getUserName());
+ assertEquals(approval2.getDate(), approval.getDate());
+
+ approval = (AgentApproval)approvals.mVector.get(2);
+ assertEquals(approval3.getUserName(), approval.getUserName());
+ assertEquals(approval3.getDate(), approval.getDate());
+
+ // test bad data
+ stringVector = new Vector();
+ stringVector.add("foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector();
+ stringVector.add(";foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector();
+ stringVector.add("bar;foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector();
+ stringVector.add("00123b;foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ assertNull(AgentApprovals.fromStringVector(null));
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java b/pki/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java
new file mode 100644
index 000000000..2d419b720
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java
@@ -0,0 +1,86 @@
+// --- 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.cmscore.dbs;
+
+import junit.framework.*;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+public class CertRecordListTest extends CMSBaseTestCase {
+
+ public CertRecordListTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(CertRecordListTest.class);
+ }
+
+ public void testProcessCertRecordsUsesSize() throws EBaseException {
+ DBVirtualListStub dbList = new DBVirtualListStub();
+ dbList.size = 5;
+
+ CertRecordList certList = new CertRecordList(dbList);
+
+ assertEquals(5, dbList.size);
+ assertEquals(0, dbList.getElementAtCallCount);
+ assertEquals(0, dbList.lastIndexGetElementAtCalledWith);
+
+ certList.processCertRecords(0, 4, new ElementProcessorStub());
+
+ assertEquals(8, dbList.size);
+ assertEquals(8, dbList.getElementAtCallCount);
+ assertEquals(7, dbList.lastIndexGetElementAtCalledWith);
+ }
+
+
+ public class DBVirtualListStub extends DBVirtualListDefaultStub {
+ public int size = 0;
+ public int getElementAtCallCount = 0;
+ public int lastIndexGetElementAtCalledWith = 0;
+
+ public Object getElementAt(int index) {
+ getElementAtCallCount++;
+ lastIndexGetElementAtCalledWith = index;
+
+ // This simulates the size changing in the middle of
+ // processing
+ if (index == 3) {
+ size = 8;
+ }
+ return null;
+ }
+
+ public int getSize() {
+ return size;
+ }
+ }
+
+ public class ElementProcessorStub implements IElementProcessor {
+ public void process(Object o) throws EBaseException {
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java
new file mode 100644
index 000000000..b533475a1
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java
@@ -0,0 +1,74 @@
+package com.netscape.cmscore.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.*;
+import netscape.ldap.LDAPAttributeSet;
+
+/**
+ * A default stub ojbect for tests to extend.
+ */
+public class DBRegistryDefaultStub implements IDBRegistry {
+
+
+ public void registerObjectClass(String className, String ldapNames[]) throws EDBException {
+ }
+
+ public boolean isObjectClassRegistered(String className) {
+ return false;
+ }
+
+ public void registerAttribute(String ufName, IDBAttrMapper mapper) throws EDBException {
+ }
+
+ public boolean isAttributeRegistered(String ufName) {
+ return false;
+ }
+
+ public void registerDynamicMapper(IDBDynAttrMapper mapper) {
+ }
+
+ public String getFilter(String filter) throws EBaseException {
+ return null;
+ }
+
+ public String getFilter(String filter, IFilterConverter c) throws EBaseException {
+ return null;
+ }
+
+ public void mapObject(IDBObj parent, String name, Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ }
+
+ public String[] getLDAPAttributes(String attrs[]) throws EBaseException {
+ return new String[0];
+ }
+
+ public LDAPAttributeSet createLDAPAttributeSet(IDBObj obj) throws EBaseException {
+ return null;
+ }
+
+ public IDBObj createObject(LDAPAttributeSet attrs) throws EBaseException {
+ return null;
+ }
+
+ public String getId() {
+ return null;
+ }
+
+ public void setId(String id) throws EBaseException {
+ }
+
+ public void init(ISubsystem owner, IConfigStore config) throws EBaseException {
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java b/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java
new file mode 100644
index 000000000..6517c6bf1
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java
@@ -0,0 +1,170 @@
+package com.netscape.cmscore.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.cmscore.request.DBDynAttrMapperDefaultStub;
+import com.netscape.cmscore.request.RequestRecord;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.cmscore.test.TestHelper;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPAttribute;
+
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Arrays;
+
+public class DBRegistryTest extends CMSBaseTestCase {
+
+ DBSubsystemStub db;
+ DBRegistry registry;
+ DBDynAttrMapperStub extAttrMapper;
+ RequestRecordStub requestRecordStub = new RequestRecordStub();
+
+ public DBRegistryTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ db = new DBSubsystemStub();
+ registry = new DBRegistry();
+ db.registry = registry;
+
+ // Emulate the registration of mappers.
+ // Normally RequestRepository calls RequestRecord.register() as part
+ // of a long chain of initialization calls.
+ extAttrMapper = new DBDynAttrMapperStub();
+ try {
+ registry.registerObjectClass(requestRecordStub.getClass().getName(),
+ new String[] {"ocvalue"} );
+ registry.registerAttribute(IRequestRecord.ATTR_EXT_DATA, extAttrMapper);
+ registry.registerAttribute(IRequestRecord.ATTR_SOURCE_ID,
+ new StringMapper("sourceIdOut"));
+ registry.registerDynamicMapper(extAttrMapper);
+ } catch (EDBException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(DBRegistryTest.class);
+ }
+
+ public void testMapObject() throws EBaseException {
+ assertFalse(extAttrMapper.mapObjectCalled);
+ registry.mapObject(null, IRequestRecord.ATTR_EXT_DATA, null,
+ new LDAPAttributeSet());
+ assertTrue(extAttrMapper.mapObjectCalled);
+ }
+
+ public void testGetLDAPAttributesForExtData() throws EBaseException {
+ String inAttrs[] = new String[] {
+ "extData-foo",
+ "extData-foo12",
+ "EXTDATA-bar;baz",
+ IRequestRecord.ATTR_SOURCE_ID
+ };
+ String outAttrs[] = registry.getLDAPAttributes(inAttrs);
+
+ assertTrue(TestHelper.contains(outAttrs, inAttrs[0]));
+ assertTrue(TestHelper.contains(outAttrs, inAttrs[1]));
+ assertTrue(TestHelper.contains(outAttrs, inAttrs[2]));
+ assertTrue(TestHelper.contains(outAttrs, "sourceIdOut"));
+
+ try {
+ registry.getLDAPAttributes(new String[] {"badattr"});
+ fail("Should not be able to map badattr");
+ } catch (EBaseException e) { /* good */ }
+ }
+
+ public void testCreateLDAPAttributeSet() throws EBaseException {
+ assertFalse(extAttrMapper.mapObjectCalled);
+
+ registry.createLDAPAttributeSet(requestRecordStub);
+ assertTrue(requestRecordStub.getCalled);
+ assertEquals(requestRecordStub.getCalledWith,
+ IRequestRecord.ATTR_EXT_DATA);
+
+ // This asserts that mapObject() is called and makes it down to the
+ // extDataDynAttrMapper.mapObjectToLDAPAttributeSet() call.
+ assertTrue(extAttrMapper.mapObjectCalled);
+ }
+
+ public void testCreateObject() throws EBaseException {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectclass", "ocvalue"));
+ attrs.add(new LDAPAttribute("extdata-foo"));
+
+ assertFalse(extAttrMapper.mapLDAPAttrsCalled);
+
+ registry.createObject(attrs);
+
+ assertTrue(extAttrMapper.mapLDAPAttrsCalled);
+ }
+
+
+ class DBSubsystemStub extends DBSubsystemDefaultStub {
+ DBRegistry registry;
+
+ public IDBRegistry getRegistry() {
+ return registry;
+ }
+ }
+
+
+ class DBDynAttrMapperStub extends DBDynAttrMapperDefaultStub {
+ boolean mapObjectCalled = false;
+ Object mapObjectCalledWithObject = null;
+ boolean mapLDAPAttrsCalled = false;
+
+ public boolean supportsLDAPAttributeName(String attrName) {
+ return (attrName != null) &&
+ attrName.toLowerCase().startsWith("extdata-");
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs, String name, IDBObj parent) throws EBaseException {
+ mapLDAPAttrsCalled = true;
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj,
+ LDAPAttributeSet attrs)
+ throws EBaseException {
+ mapObjectCalled = true;
+ mapObjectCalledWithObject = obj;
+ }
+ }
+
+}
+
+/*
+ * This class is purposefully placed outside the test because
+ * DBRegistry.createObject() calls Class.newInstance() to create
+ * this stub. This fails if the class is nested.
+ */
+ class RequestRecordStub extends RequestRecordDefaultStub {
+
+ String[] attrs = new String[] { IRequestRecord.ATTR_EXT_DATA };
+
+ boolean getCalled = false;
+ String getCalledWith = null;
+ boolean getSerializedAttrNamesCalled = false;
+
+ public Object get(String name) {
+ getCalled = true;
+ getCalledWith = name;
+ return "foo";
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ getSerializedAttrNamesCalled = true;
+ return Collections.enumeration(Arrays.asList(attrs));
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java
new file mode 100644
index 000000000..d5a6088d4
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java
@@ -0,0 +1,70 @@
+package com.netscape.cmscore.dbs;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.IConfigStore;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPSearchResults;
+
+/**
+ * A default stub ojbect for tests to extend.
+ */
+public class DBSSessionDefaultStub implements IDBSSession {
+
+ public ISubsystem getDBSubsystem() {
+ return null;
+ }
+
+ public void close() throws EDBException {
+ }
+
+ public void add(String name, IDBObj obj) throws EBaseException {
+ }
+
+ public IDBObj read(String name) throws EBaseException {
+ return null;
+ }
+
+ public IDBObj read(String name, String attrs[]) throws EBaseException {
+ return null;
+ }
+
+ public void delete(String name) throws EBaseException {
+ }
+
+ public void modify(String name, ModificationSet mods) throws EBaseException {
+ }
+
+ public IDBSearchResults search(String base, String filter) throws EBaseException {
+ return null;
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize) throws EBaseException {
+ return null;
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize, int timeLimit) throws EBaseException {
+ return null;
+ }
+
+ public IDBSearchResults search(String base, String filter, String attrs[]) throws EBaseException {
+ return null;
+ }
+
+ public IDBVirtualList createVirtualList(String base, String filter, String attrs[]) throws EBaseException {
+ return null;
+ }
+
+ public LDAPSearchResults persistentSearch(String base, String filter, String attrs[]) throws EBaseException {
+ return null;
+ }
+
+ public IDBVirtualList createVirtualList(String base, String filter, String attrs[], String sortKey, int pageSize) throws EBaseException {
+ return null;
+ }
+
+ public IDBVirtualList createVirtualList(String base, String filter, String attrs[], String startFrom, String sortKey, int pageSize) throws EBaseException {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java
new file mode 100644
index 000000000..84e0c1b3e
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java
@@ -0,0 +1,84 @@
+package com.netscape.cmscore.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import netscape.ldap.LDAPConnection;
+
+import java.math.BigInteger;
+
+/**
+ * A default stub ojbect for tests to extend.
+ */
+public class DBSubsystemDefaultStub implements IDBSubsystem {
+
+
+ public String getBaseDN() {
+ return null;
+ }
+
+ public IDBRegistry getRegistry() {
+ return null;
+ }
+
+ public IDBSSession createSession() throws EDBException {
+ return null;
+ }
+
+ public boolean enableSerialNumberRecovery() {
+ return false;
+ }
+
+ public void setNextSerialConfig(BigInteger serial) throws EBaseException {
+ }
+
+ public BigInteger getNextSerialConfig() {
+ return null;
+ }
+
+ public void setMaxSerialConfig(String serial) throws EBaseException {
+ }
+
+ public String getMinSerialConfig() {
+ return null;
+ }
+
+ public String getMaxSerialConfig() {
+ return null;
+ }
+
+ public String getMinRequestConfig() {
+ return null;
+ }
+
+ public String getMaxRequestConfig() {
+ return null;
+ }
+
+ public void returnConn(LDAPConnection conn) {
+ }
+
+ public String getId() {
+ return null;
+ }
+
+ public void setId(String id) throws EBaseException {
+ }
+
+ public void init(ISubsystem owner, IConfigStore config) throws EBaseException {
+ }
+
+ public void startup() throws EBaseException {
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java
new file mode 100644
index 000000000..45fda77db
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java
@@ -0,0 +1,87 @@
+// --- 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.cmscore.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.IElementProcessor;
+
+/**
+ * A default stub ojbect for tests to extend.
+ * This class helps test avoid the problem of test stubs having to
+ * implement a new stub method every time the interface changes.
+ * It also makes the tests clearer by not cluttered them with empty methods.
+ *
+ * Do not put any behaviour in this class.
+ */
+public class DBVirtualListDefaultStub implements IDBVirtualList {
+
+ public void setPageSize(int size) {
+ }
+
+ public void setSortKey(String sortKey) throws EBaseException {
+ }
+
+ public void setSortKey(String[] sortKeys) throws EBaseException {
+ }
+
+ public int getSize() {
+ return 0;
+ }
+
+ public int getSizeBeforeJumpTo() {
+ return 0;
+ }
+
+ public int getSizeAfterJumpTo() {
+ return 0;
+ }
+
+ public int getCurrentIndex() {
+ return 0;
+ }
+
+ public boolean getPage(int first) {
+ return false;
+ }
+
+ public boolean getPage(String text) {
+ return false;
+ }
+
+ public Object getElementAt(int index) {
+ return null;
+ }
+
+ public Object getJumpToElementAt(int i) {
+ return null;
+ }
+
+ public void processElements(int startidx, int endidx, IElementProcessor ep)
+ throws EBaseException {
+ }
+
+ public int getSelectedIndex() {
+ return 0;
+ }
+
+ public int getFirstIndex() {
+ return 0;
+ }
+
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java
new file mode 100644
index 000000000..ad0572aab
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java
@@ -0,0 +1,39 @@
+package com.netscape.cmscore.dbs;
+
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+
+import java.util.Enumeration;
+
+/**
+ * Default stub for RequestRecord tests.
+ */
+public class RequestRecordDefaultStub implements IRequestRecord, IDBObj {
+ public RequestId getRequestId() {
+ return null;
+ }
+
+ public Enumeration getAttrNames() {
+ return null;
+ }
+
+ public Object get(String name) {
+ return null;
+ }
+
+ public void set(String name, Object o) {
+ }
+
+ public void delete(String name) throws EBaseException {
+ }
+
+ public Enumeration getElements() {
+ return null;
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java
new file mode 100644
index 000000000..3beda6a90
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java
@@ -0,0 +1,31 @@
+package com.netscape.cmscore.request;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import netscape.ldap.LDAPAttributeSet;
+
+import java.util.Enumeration;
+
+/**
+ * Default testing stub for the IRequest interface.
+ */
+public class DBDynAttrMapperDefaultStub implements IDBDynAttrMapper {
+ public boolean supportsLDAPAttributeName(String attrName) {
+ return false;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return null;
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name, Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs, String name, IDBObj parent) throws EBaseException {
+ }
+
+ public String mapSearchFilter(String name, String op, String value) throws EBaseException {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java b/pki/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java
new file mode 100644
index 000000000..4c8aaddaa
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java
@@ -0,0 +1,279 @@
+package com.netscape.cmscore.request;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPAttribute;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmscore.dbs.RequestRecordDefaultStub;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+public class ExtAttrDynMapperTest extends CMSBaseTestCase {
+
+ ExtAttrDynMapper mapper;
+
+ public ExtAttrDynMapperTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ mapper = new ExtAttrDynMapper();
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(ExtAttrDynMapperTest.class);
+ }
+
+ public void testSupportLDAPAttributeName() {
+ assertNotNull(mapper);
+
+ assertTrue(mapper.supportsLDAPAttributeName("extData-green"));
+ assertTrue(mapper.supportsLDAPAttributeName("EXTDATA-green"));
+ assertTrue(mapper.supportsLDAPAttributeName("extData-foo;0"));
+ assertTrue(mapper.supportsLDAPAttributeName("extData-bar;baz"));
+
+ assertFalse(mapper.supportsLDAPAttributeName("extDatagreen"));
+ assertFalse(mapper.supportsLDAPAttributeName("extDatafoo;0"));
+ assertFalse(mapper.supportsLDAPAttributeName("extDatabar;baz"));
+
+ assertFalse(mapper.supportsLDAPAttributeName(";extData"));
+ assertFalse(mapper.supportsLDAPAttributeName("fooextData"));
+ assertFalse(mapper.supportsLDAPAttributeName("foo-extData"));
+
+ assertFalse(mapper.supportsLDAPAttributeName(""));
+ assertFalse(mapper.supportsLDAPAttributeName(null));
+ }
+
+ public void testGetSupportedLdapAttributesNames() {
+ Enumeration attrs = mapper.getSupportedLDAPAttributeNames();
+ ArrayList attrsList = new ArrayList();
+ while (attrs.hasMoreElements()) {
+ attrsList.add(attrs.nextElement());
+ }
+
+ assertEquals(1, attrsList.size());
+ assertEquals(Schema.LDAP_ATTR_EXT_ATTR, attrsList.get(0));
+ }
+
+ public void testIsAlphaNum() {
+ assertTrue(mapper.isAlphaNum('a'));
+ assertTrue(mapper.isAlphaNum('l'));
+ assertTrue(mapper.isAlphaNum('z'));
+ assertTrue(mapper.isAlphaNum('A'));
+ assertTrue(mapper.isAlphaNum('K'));
+ assertTrue(mapper.isAlphaNum('Z'));
+ assertTrue(mapper.isAlphaNum('0'));
+ assertTrue(mapper.isAlphaNum('5'));
+ assertTrue(mapper.isAlphaNum('9'));
+
+ assertFalse(mapper.isAlphaNum('!'));
+ assertFalse(mapper.isAlphaNum('-'));
+ assertFalse(mapper.isAlphaNum('\u00ef'));
+ }
+
+ public void testEncodeDecodeKey() {
+ // ; is 003b
+ // $ is 0024
+ // % is 0025
+ // - is 002d
+
+ String decoded = ";a$c%d-";
+ String encoded = "--003ba--0024c--0025d-";
+ assertEquals(encoded, mapper.encodeKey(decoded));
+ assertEquals(decoded, mapper.decodeKey(encoded));
+
+ decoded = ";-a-";
+ encoded = "--003b--002da-";
+ assertEquals(encoded, mapper.encodeKey(decoded));
+ assertEquals(decoded, mapper.decodeKey(encoded));
+
+ decoded = "-ab;ab";
+ encoded = "-ab--003bab";
+ assertEquals(encoded, mapper.encodeKey(decoded));
+ assertEquals(decoded, mapper.decodeKey(encoded));
+
+ decoded = "--a--b-a-b-";
+ encoded = "--002d--002da--002d--002db-a-b-";
+ assertEquals(encoded, mapper.encodeKey(decoded));
+ assertEquals(decoded, mapper.decodeKey(encoded));
+
+ decoded = "--a;-";
+ encoded = "--002d--002da--003b--002d";
+ assertEquals(encoded, mapper.encodeKey(decoded));
+ assertEquals(decoded, mapper.decodeKey(encoded));
+ }
+
+ public void testMapObjectToLDAPAttributeSet() throws EBaseException {
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ // test with a key-value entry.
+ Hashtable extAttrsHash = new Hashtable();
+ extAttrsHash.put("foo;", "bar");
+
+ mapper.mapObjectToLDAPAttributeSet(null, null, extAttrsHash, attrs);
+ assertEquals(1, attrs.size());
+ assertEquals(ExtAttrDynMapper.extAttrPrefix + "foo--003b",
+ attrs.elementAt(0).getName());
+ String vals[] = attrs.elementAt(0).getStringValueArray();
+ assertEquals(1, vals.length);
+ assertEquals("bar", vals[0]);
+
+ // test with a sub-hash.
+ // this is used by vector/arrays and hashtables
+ Hashtable extAttrsValueHash = new Hashtable();
+ extAttrsValueHash.put("Baz", "Val1");
+ extAttrsValueHash.put("bi;m", "val2");
+
+ extAttrsHash.clear();
+ extAttrsHash.put("top;key", extAttrsValueHash);
+
+ attrs = new LDAPAttributeSet();
+ mapper.mapObjectToLDAPAttributeSet(null, null, extAttrsHash, attrs);
+ assertEquals(2, attrs.size());
+ LDAPAttribute attrBaz = attrs.elementAt(0);
+ LDAPAttribute attrBim = attrs.elementAt(1);
+ // swap attributes if necessary
+ if (attrBaz.getName().equals(ExtAttrDynMapper.extAttrPrefix +
+ "top--003bkey;bi--003bm")) {
+ attrBaz = attrs.elementAt(1);
+ attrBim = attrs.elementAt(0);
+ }
+
+ assertEquals(ExtAttrDynMapper.extAttrPrefix + "top--003bkey;Baz",
+ attrBaz.getName());
+ vals = attrBaz.getStringValueArray();
+ assertEquals(1, vals.length);
+ assertEquals("Val1", vals[0]);
+ assertTrue(attrBaz.hasSubtype("Baz"));
+
+ assertEquals(ExtAttrDynMapper.extAttrPrefix + "top--003bkey;bi--003bm",
+ attrBim.getName());
+ vals = attrBim.getStringValueArray();
+ assertEquals(1, vals.length);
+ assertEquals("val2", vals[0]);
+ assertTrue(attrBim.hasSubtype("bi--003bm"));
+ }
+
+
+ public void testMapLDAPAttributeSetToObject() throws EBaseException {
+ //
+ // Test simple key-value pairs
+ //
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "o--003bkey1", "val1"));
+ attrs.add(new LDAPAttribute("junk", "junkval"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "okey2", "val2"));
+
+ RequestRecordStub requestRecord = new RequestRecordStub();
+
+ mapper.mapLDAPAttributeSetToObject(attrs, IRequestRecord.ATTR_EXT_DATA,
+ requestRecord);
+
+ assertEquals(1, requestRecord.setCallCounter);
+ Hashtable extData = (Hashtable)requestRecord.extAttrData.get(
+ IRequestRecord.ATTR_EXT_DATA);
+ assertNotNull(extData);
+
+ assertEquals(2, extData.keySet().size());
+ assertTrue(extData.containsKey("o;key1"));
+ assertEquals("val1", extData.get("o;key1"));
+ assertTrue(extData.containsKey("okey2"));
+ assertEquals("val2", extData.get("okey2"));
+
+ //
+ // Test subkeys
+ //
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "o--003bkey1;i--003bkey11", "val11"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix.toUpperCase() + "o--003bkey1;ikey12", "val12"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "o--003bkey1;ikey13", "val13"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "okey2;ikey21", "val21"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "okey2;ikey22", "val22"));
+ attrs.add(new LDAPAttribute("foo", "bar"));
+
+ requestRecord = new RequestRecordStub();
+
+ mapper.mapLDAPAttributeSetToObject(attrs, IRequestRecord.ATTR_EXT_DATA,
+ requestRecord);
+
+ assertEquals(1, requestRecord.setCallCounter);
+ extData = (Hashtable)requestRecord.extAttrData.get(
+ IRequestRecord.ATTR_EXT_DATA);
+ assertNotNull(extData);
+
+ assertTrue(extData.containsKey("o;key1"));
+ Hashtable okey1Data = (Hashtable)extData.get("o;key1");
+ assertEquals(3, okey1Data.keySet().size());
+ assertTrue(okey1Data.containsKey("i;key11"));
+ assertEquals("val11", (String)okey1Data.get("i;key11"));
+ assertTrue(okey1Data.containsKey("ikey12"));
+ assertEquals("val12", (String)okey1Data.get("ikey12"));
+ assertTrue(okey1Data.containsKey("ikey13"));
+ assertEquals("val13", (String)okey1Data.get("ikey13"));
+
+ assertTrue(extData.containsKey("okey2"));
+ Hashtable okey2Data = (Hashtable)extData.get("okey2");
+ assertEquals(2, okey2Data.keySet().size());
+ assertTrue(okey2Data.containsKey("ikey21"));
+ assertEquals("val21", (String)okey2Data.get("ikey21"));
+ assertTrue(okey2Data.containsKey("ikey22"));
+ assertEquals("val22", (String)okey2Data.get("ikey22"));
+
+ assertFalse(extData.containsKey("foo"));
+
+ //
+ // test illegal data combination
+ //
+ attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "okey1", "val11"));
+ attrs.add(new LDAPAttribute(
+ ExtAttrDynMapper.extAttrPrefix + "okey1;ikey12", "val12"));
+
+ requestRecord = new RequestRecordStub();
+
+ try {
+ mapper.mapLDAPAttributeSetToObject(attrs, IRequestRecord.ATTR_EXT_DATA,
+ requestRecord);
+ fail("Should have thrown EBaseException on illegal data");
+ } catch (EBaseException e) {
+ // good
+ }
+
+ }
+
+
+ class RequestRecordStub extends RequestRecordDefaultStub {
+ Hashtable extAttrData = new Hashtable();
+ int setCallCounter = 0;
+
+
+ public void set(String name, Object o) {
+ setCallCounter++;
+ if (IRequestRecord.ATTR_EXT_DATA.equals(name)) {
+ extAttrData.put(name, o);
+ }
+ }
+
+ public RequestId getRequestId() {
+ return new RequestId("1");
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java b/pki/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java
new file mode 100644
index 000000000..177ccbbc3
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java
@@ -0,0 +1,87 @@
+package com.netscape.cmscore.request;
+
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.cmscore.dbs.RequestRecordDefaultStub;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.*;
+
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPAttribute;
+
+public class ExtDataHashtableTest extends CMSBaseTestCase {
+
+ ExtDataHashtable hash;
+
+ public ExtDataHashtableTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ hash = new ExtDataHashtable();
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(ExtDataHashtableTest.class);
+ }
+
+ public void testContainsKey() {
+ hash.put("FOO", "bar");
+ assertTrue(hash.containsKey("foo"));
+ assertTrue(hash.containsKey("Foo"));
+ }
+
+ public void testGet() {
+ hash.put("FOO", "bar");
+ assertEquals("bar", hash.get("foo"));
+ assertEquals("bar", hash.get("fOO"));
+ }
+
+ public void testPut() {
+ hash.put("FOO", "bar");
+ hash.put("foo", "bar2");
+ assertEquals(1, hash.keySet().size());
+ assertEquals("bar2", hash.get("foo"));
+ }
+
+ public void testPutAll() {
+ Hashtable hash2 = new Hashtable();
+ hash2.put("KEY1", "VAL1");
+ hash2.put("KEY2", "val2");
+
+ hash.putAll(hash2);
+
+ assertTrue(hash.containsKey("key1"));
+ assertEquals("VAL1", hash.get("key1"));
+ assertEquals("val2", hash.get("Key2"));
+ }
+
+ public void testRemove() {
+ hash.put("foo", "bar");
+ hash.put("one", "two");
+
+ hash.remove("FOO");
+ assertFalse(hash.containsKey("foo"));
+ assertTrue(hash.containsKey("one"));
+ }
+
+ public void testMapConstructor() {
+ Hashtable hash2 = new Hashtable();
+ hash2.put("KEY1", "VAL1");
+ hash2.put("KEY2", "val2");
+
+ hash = new ExtDataHashtable(hash2);
+
+ assertTrue(hash.containsKey("key1"));
+ assertEquals("VAL1", hash.get("key1"));
+ assertEquals("val2", hash.get("Key2"));
+ }
+
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java
new file mode 100644
index 000000000..884405362
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java
@@ -0,0 +1,269 @@
+package com.netscape.cmscore.request;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.authentication.IAuthToken;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.math.BigInteger;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+
+/**
+ * Default testing stub for the IRequest interface.
+ */
+public class RequestDefaultStub implements IRequest {
+ public RequestId getRequestId() {
+ return null;
+ }
+
+ public RequestStatus getRequestStatus() {
+ return null;
+ }
+
+ public String getSourceId() {
+ return null;
+ }
+
+ public void setSourceId(String id) {
+ }
+
+ public String getRequestOwner() {
+ return null;
+ }
+
+ public void setRequestOwner(String owner) {
+ }
+
+ public String getRequestType() {
+ return null;
+ }
+
+ public void setRequestType(String type) {
+ }
+
+ public String getRequestVersion() {
+ return null;
+ }
+
+ public Date getCreationTime() {
+ return null;
+ }
+
+ public Date getModificationTime() {
+ return null;
+ }
+
+ public void set(String type, Object value) {
+ }
+
+ public Object get(String type) {
+ return null;
+ }
+
+ public Enumeration getAttrNames() {
+ return null;
+ }
+
+ public void deleteExtData(String type) {
+ }
+
+ public void copyContents(IRequest req) {
+ }
+
+ public String getContext() {
+ return null;
+ }
+
+ public void setContext(String ctx) {
+ }
+
+ public void setRequestStatus(RequestStatus s) {
+ }
+
+ public boolean isSuccess() {
+ return false;
+ }
+
+ public String getError(Locale locale) {
+ return null;
+ }
+
+ public boolean setExtData(String key, String value) {
+ return false;
+ }
+
+ public boolean setExtData(String key, Hashtable value) {
+ return false;
+ }
+
+ public boolean isSimpleExtDataValue(String key) {
+ return false;
+ }
+
+ public String getExtDataInString(String key) {
+ return null;
+ }
+
+ public Hashtable getExtDataInHashtable(String key) {
+ return null;
+ }
+
+ public Enumeration getExtDataKeys() {
+ return null;
+ }
+
+ public boolean setExtData(String key, String[] values) {
+ return false;
+ }
+
+ public String[] getExtDataInStringArray(String key) {
+ return new String[0];
+ }
+
+ public boolean setExtData(String key, String subkey, String value) {
+ return false;
+ }
+
+ public String getExtDataInString(String key, String subkey) {
+ return null;
+ }
+
+ public boolean setExtData(String key, Integer value) {
+ return false;
+ }
+
+ public Integer getExtDataInInteger(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, Integer[] values) {
+ return false;
+ }
+
+ public Integer[] getExtDataInIntegerArray(String key) {
+ return new Integer[0];
+ }
+
+ public boolean setExtData(String key, BigInteger value) {
+ return false;
+ }
+
+ public BigInteger getExtDataInBigInteger(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, BigInteger[] values) {
+ return false;
+ }
+
+ public BigInteger[] getExtDataInBigIntegerArray(String key) {
+ return new BigInteger[0];
+ }
+
+ public boolean setExtData(String key, Throwable e) {
+ return false;
+ }
+
+ public boolean setExtData(String key, byte[] data) {
+ return false;
+ }
+
+ public byte[] getExtDataInByteArray(String key) {
+ return new byte[0];
+ }
+
+ public boolean setExtData(String key, X509CertImpl data) {
+ return false;
+ }
+
+ public X509CertImpl getExtDataInCert(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, X509CertImpl[] data) {
+ return false;
+ }
+
+ public X509CertImpl[] getExtDataInCertArray(String key) {
+ return new X509CertImpl[0];
+ }
+
+ public boolean setExtData(String key, X509CertInfo data) {
+ return false;
+ }
+
+ public X509CertInfo getExtDataInCertInfo(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, X509CertInfo[] data) {
+ return false;
+ }
+
+ public X509CertInfo[] getExtDataInCertInfoArray(String key) {
+ return new X509CertInfo[0];
+ }
+
+ public boolean setExtData(String key, RevokedCertImpl[] data) {
+ return false;
+ }
+
+ public RevokedCertImpl[] getExtDataInRevokedCertArray(String key) {
+ return new RevokedCertImpl[0];
+ }
+
+ public boolean setExtData(String key, Vector data) {
+ return false;
+ }
+
+ public Vector getExtDataInStringVector(String key) {
+ return null;
+ }
+
+ public boolean getExtDataInBoolean(String type, boolean defVal) {
+ return false;
+ }
+
+ public boolean getExtDataInBoolean(String prefix, String type, boolean defVal) {
+ return false;
+ }
+
+ public boolean setExtData(String key, IAuthToken data) {
+ return false;
+ }
+
+ public IAuthToken getExtDataInAuthToken(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, CertificateExtensions data) {
+ return false;
+ }
+
+ public CertificateExtensions getExtDataInCertExts(String key) {
+ return null;
+ }
+
+ public boolean setExtData(String key, CertificateSubjectName data) {
+ return false;
+ }
+
+ public CertificateSubjectName getExtDataInCertSubjectName(String key) {
+ return null;
+ }
+
+ public IAttrSet asIAttrSet() {
+ return null;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java b/pki/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java
new file mode 100644
index 000000000..648f019f3
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java
@@ -0,0 +1,21 @@
+package com.netscape.cmscore.request;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.ldap.IRequestMod;
+
+import java.util.Date;
+
+/**
+ * Default testing stub for the IRequest interface.
+ */
+public class RequestModDefaultStub implements IRequestMod {
+ public void modRequestStatus(IRequest r, RequestStatus s) {
+ }
+
+ public void modCreationTime(IRequest r, Date d) {
+ }
+
+ public void modModificationTime(IRequest r, Date d) {
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java b/pki/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java
new file mode 100644
index 000000000..02ffbc6b2
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java
@@ -0,0 +1,59 @@
+package com.netscape.cmscore.request;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.certsrv.base.EBaseException;
+
+import java.util.Enumeration;
+import java.util.Arrays;
+import java.util.Collections;
+
+public class RequestQueueTest extends CMSBaseTestCase {
+ RequestStub request;
+ RequestQueue queue;
+
+ public RequestQueueTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ request = new RequestStub();
+ try {
+ queue = new RequestQueue("", 1, null, null, null, null);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(RequestQueueTest.class);
+ }
+
+ public void testAddRequest() throws EBaseException {
+ assertFalse(request.getExtDataKeysCalled);
+ queue.addRequest(request);
+ assertTrue(request.getExtDataKeysCalled);
+ }
+
+ class RequestStub extends RequestDefaultStub {
+ String[] keys = new String[] {"key1", "key2"};
+ boolean getExtDataKeysCalled = false;
+
+ public Enumeration getExtDataKeys() {
+ getExtDataKeysCalled = true;
+ return Collections.enumeration(Arrays.asList(keys));
+ }
+
+ public boolean isSimpleExtDataValue(String key) {
+ return true;
+ }
+
+ public String getExtDataInString(String key) {
+ return "";
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java b/pki/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java
new file mode 100644
index 000000000..40f90a0da
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java
@@ -0,0 +1,168 @@
+package com.netscape.cmscore.request;
+
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.cmscore.test.TestHelper;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.cmscore.dbs.DBSubsystemDefaultStub;
+import com.netscape.cmscore.dbs.DBRegistryDefaultStub;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Hashtable;
+
+public class RequestRecordTest extends CMSBaseTestCase {
+
+ RequestRecord requestRecord;
+ Request request;
+
+ public RequestRecordTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ requestRecord = new RequestRecord();
+ request = new Request(new RequestId("testid"));
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(RequestRecordTest.class);
+ }
+
+ public void testGetExtData() {
+ Hashtable hash = new Hashtable();
+
+ assertNotSame(hash, requestRecord.get(IRequestRecord.ATTR_EXT_DATA));
+ requestRecord.mExtData = hash;
+ assertSame(hash, requestRecord.get(IRequestRecord.ATTR_EXT_DATA));
+ }
+
+ public void testSetExtData() {
+ Hashtable hash = new Hashtable();
+
+ assertNotSame(requestRecord.mExtData, hash);
+ requestRecord.set(IRequestRecord.ATTR_EXT_DATA, hash);
+ assertSame(requestRecord.mExtData, hash);
+ }
+
+ public void testGetElements() {
+ assertTrue(TestHelper.enumerationContains(requestRecord.getElements(),
+ IRequestRecord.ATTR_EXT_DATA));
+ }
+
+ public void testAddExtData() throws EBaseException {
+ request.setExtData("foo", "bar");
+ Hashtable requestHashValue = new Hashtable();
+ requestHashValue.put("red", "rum");
+ requestHashValue.put("blue", "gin");
+ request.setExtData("hashkey", requestHashValue);
+
+ requestRecord.add(request);
+
+ assertEquals(request.mExtData, requestRecord.mExtData);
+ assertNotSame(request.mExtData, requestRecord.mExtData);
+ }
+
+ public void testReadExtData() throws EBaseException {
+ Hashtable extData = new Hashtable();
+ extData.put("foo", "bar");
+ Hashtable extDataHashValue = new Hashtable();
+ extDataHashValue.put("red", "rum");
+ extDataHashValue.put("blue", "gin");
+ extData.put("hashkey", extDataHashValue);
+ requestRecord.set(IRequestRecord.ATTR_EXT_DATA, extData);
+ requestRecord.mRequestType = "foo";
+
+
+ requestRecord.read(new RequestModDefaultStub(), request);
+
+ // the request stores other attributes inside its mExtData when some
+ // of its setters are called, so we have to compare manually.
+ assertEquals("bar", request.mExtData.get("foo"));
+ assertEquals(extDataHashValue, request.mExtData.get("hashkey"));
+ assertNotSame(requestRecord.mExtData, request.mExtData);
+ }
+
+ public void testModExtData() throws EBaseException {
+ ModificationSetStub mods = new ModificationSetStub();
+ request.setExtData("foo", "bar");
+
+ RequestRecord.mod(mods, request);
+
+ assertTrue(mods.addCalledWithExtData);
+ assertEquals(mods.addExtDataObject, request.mExtData);
+ }
+
+ public void testRegister() throws EDBException {
+ DBSubsystemStub db = new DBSubsystemStub();
+
+ RequestRecord.register(db);
+
+ assertTrue(db.registry.registerCalledWithExtAttr);
+ assertTrue(db.registry.extAttrMapper instanceof ExtAttrDynMapper);
+
+ assertTrue(db.registry.registerObjectClassCalled);
+ assertTrue(TestHelper.contains(db.registry.registerObjectClassLdapNames,
+ "extensibleObject"));
+
+ assertTrue(db.registry.registerDynamicMapperCalled);
+ assertTrue(db.registry.dynamicMapper instanceof ExtAttrDynMapper);
+ }
+
+
+ class ModificationSetStub extends ModificationSet {
+ public boolean addCalledWithExtData = false;
+ public Object addExtDataObject = null;
+
+ public void add(String name, int op, Object value) {
+ if (IRequestRecord.ATTR_EXT_DATA.equals(name)) {
+ addCalledWithExtData = true;
+ addExtDataObject = value;
+ }
+ }
+ }
+
+
+ class DBSubsystemStub extends DBSubsystemDefaultStub {
+ DBRegistryStub registry = new DBRegistryStub();
+
+
+ public IDBRegistry getRegistry() {
+ return registry;
+ }
+ }
+
+
+ class DBRegistryStub extends DBRegistryDefaultStub {
+ boolean registerCalledWithExtAttr = false;
+ IDBAttrMapper extAttrMapper = null;
+
+ boolean registerObjectClassCalled = false;
+ String[] registerObjectClassLdapNames = null;
+
+ private boolean registerDynamicMapperCalled = false;
+ private IDBDynAttrMapper dynamicMapper;
+
+ public void registerObjectClass(String className, String ldapNames[]) throws EDBException {
+ registerObjectClassCalled = true;
+ registerObjectClassLdapNames = ldapNames;
+ }
+
+ public void registerAttribute(String ufName, IDBAttrMapper mapper) throws EDBException {
+ if (IRequestRecord.ATTR_EXT_DATA.equals(ufName)) {
+ registerCalledWithExtAttr = true;
+ extAttrMapper = mapper;
+ }
+ }
+
+ public void registerDynamicMapper(IDBDynAttrMapper mapper) {
+ registerDynamicMapperCalled = true;
+ dynamicMapper = mapper;
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/request/RequestTest.java b/pki/base/common/test/com/netscape/cmscore/request/RequestTest.java
new file mode 100644
index 000000000..310469437
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/request/RequestTest.java
@@ -0,0 +1,650 @@
+package com.netscape.cmscore.request;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CRLException;
+import java.math.BigInteger;
+import java.io.IOException;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.app.CMSEngineDefaultStub;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.cmscore.test.TestHelper;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+
+public class RequestTest extends CMSBaseTestCase {
+
+ Request request;
+ CMSMemoryStub cmsStub;
+
+ public RequestTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ // this is needed because of CMS.AtoB/BtoA calls
+ cmsStub = new CMSMemoryStub();
+ CMS.setCMSEngine(cmsStub);
+
+ request = new Request(new RequestId("testid"));
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(RequestTest.class);
+ }
+
+ public void testIsValidKey() {
+ assertTrue(request.isValidExtDataKey("foo"));
+ assertTrue(request.isValidExtDataKey("BARBAZ"));
+ assertTrue(request.isValidExtDataKey("1122"));
+ assertTrue(request.isValidExtDataKey("-"));
+ assertTrue(request.isValidExtDataKey("1a-22"));
+ assertTrue(request.isValidExtDataKey("a;b"));
+ assertTrue(request.isValidExtDataKey("_"));
+ assertTrue(request.isValidExtDataKey("this.is.encoded"));
+ assertTrue(request.isValidExtDataKey("spaces are too"));
+
+ assertFalse(request.isValidExtDataKey(null));
+ assertFalse(request.isValidExtDataKey(""));
+ }
+
+ public void testIsSimpleExtDataValue() {
+ request.mExtData.put("simple1", "foo");
+ request.mExtData.put("complex1", new Hashtable());
+
+ assertTrue(request.isSimpleExtDataValue("simple1"));
+ assertFalse(request.isSimpleExtDataValue("complex1"));
+ assertFalse(request.isSimpleExtDataValue("doesn't exist"));
+ }
+
+ public void testSetExtStringData() {
+ request.setExtData("foo", "bar");
+ request.setExtData("foo2", "bar2");
+ assertEquals("bar", request.mExtData.get("foo"));
+ assertEquals("bar2", request.mExtData.get("foo2"));
+
+ request.setExtData("foo", "newvalue");
+ assertEquals("newvalue", request.mExtData.get("foo"));
+
+ request.setExtData("UPPER", "CASE");
+ assertEquals("CASE", request.mExtData.get("upper"));
+
+ assertFalse(request.setExtData("key", (String)null));
+ }
+
+ public void testVerifyValidExtDataHashtable() {
+ Hashtable valueHash = new Hashtable();
+
+ valueHash.put("key1", "val1");
+ valueHash.put("key;2", "val2");
+ assertTrue(request.isValidExtDataHashtableValue(valueHash));
+
+ valueHash.clear();
+ valueHash.put("", "bar");
+ assertFalse(request.isValidExtDataHashtableValue(valueHash));
+
+ valueHash.clear();
+ valueHash.put(new Integer("0"), "bar");
+ assertFalse(request.isValidExtDataHashtableValue(valueHash));
+
+ valueHash.clear();
+ valueHash.put("okay", new Integer(5));
+ assertFalse(request.isValidExtDataHashtableValue(valueHash));
+
+ }
+
+ public void testSetExtHashtableData() {
+ Hashtable valueHash = new Hashtable();
+
+ valueHash.put("key1", "val1");
+ valueHash.put("KEY2", "val2");
+
+ request.setExtData("TOPKEY", valueHash);
+
+ Hashtable out = request.getExtDataInHashtable("topkey");
+ assertNotNull(out);
+
+ assertTrue(out.containsKey("key1"));
+ assertEquals("val1", out.get("key1"));
+
+ assertTrue(out.containsKey("key2"));
+ assertEquals("val2", out.get("key2"));
+
+ valueHash.put("", "value");
+ assertFalse(request.setExtData("topkey2", valueHash));
+
+ assertFalse(request.setExtData("topkey3", (Hashtable)null));
+ }
+
+ public void testGetExtDataInString() {
+ request.mExtData.put("strkey", "strval");
+ Hashtable hashValue = new Hashtable();
+ hashValue.put("uh", "oh");
+ request.mExtData.put("hashkey", hashValue);
+
+ assertEquals("strval", request.getExtDataInString("strkey"));
+ assertEquals("strval", request.getExtDataInString("STRKEY"));
+ assertEquals(null, request.getExtDataInString("notfound"));
+
+ assertNull(request.getExtDataInString("hashkey"));
+ }
+
+ public void testGetExtDataInHashtable() {
+ request.mExtData.put("strkey", "strval");
+ Hashtable hashValue = new Hashtable();
+ hashValue.put("uh", "oh");
+ request.mExtData.put("hashkey", hashValue);
+
+ Hashtable out = request.getExtDataInHashtable("HASHKEY");
+ assertNotNull(out);
+ assertNull(request.getExtDataInHashtable("notfound"));
+ assertNull(request.getExtDataInHashtable("strkey"));
+
+ // Check the bevaiour of the returned hash
+ assertEquals("oh", out.get("UH"));
+
+ // check that we can't change the ExtData by altering the Hashtable
+ hashValue = request.getExtDataInHashtable("hashkey");
+ hashValue.put("newhashkey", "newhashvalue");
+ hashValue = request.getExtDataInHashtable("hashkey");
+ assertFalse(hashValue.containsKey("newhashkey"));
+ }
+
+ public void testGetExtDataKeys() {
+ request.setExtData("FOO", "val1");
+ request.setExtData("bar", new Hashtable());
+
+ assertTrue(TestHelper.enumerationContains(request.getExtDataKeys(), "foo"));
+ assertTrue(TestHelper.enumerationContains(request.getExtDataKeys(), "bar"));
+ }
+
+ public void testSetExtDataSubkeyValue() {
+ // creates hashtable first time
+ assertNull(request.getExtDataInHashtable("topkey"));
+ request.setExtData("TOPKEY", "SUBKEY", "value");
+ Hashtable value = request.getExtDataInHashtable("topkey");
+ assertNotNull(value);
+ assertTrue(value.containsKey("subkey"));
+ assertEquals("value", value.get("subkey"));
+
+ // adds to existing hashtable
+ assertNull(request.getExtDataInHashtable("topkey2"));
+ value = new Hashtable();
+ value.put("subkey2", "value2");
+ request.setExtData("topkey2", value);
+ request.setExtData("TOPKEY2", "subkey3", "value3");
+ value = request.getExtDataInHashtable("topkey2");
+ assertNotNull(value);
+ assertTrue(value.containsKey("subkey2"));
+ assertTrue(value.containsKey("subkey3"));
+ assertEquals("value3", value.get("subkey3"));
+
+ // can't sneak a bad topkey or subkey in this way
+ assertFalse(request.setExtData("", "value", "value"));
+ assertNull(request.getExtDataInHashtable(""));
+
+ assertFalse(request.setExtData("key", "", "value"));
+ assertNull(request.getExtDataInHashtable("key"));
+
+ // can't sneak into an existing hashtable
+ // this key was added above
+ assertFalse(request.setExtData("topkey", "", "value"));
+ value = request.getExtDataInHashtable("topkey");
+ assertNotNull(value);
+ assertFalse(value.containsKey(""));
+
+ // Illegal values
+ assertFalse(request.setExtData((String)null, "b", "c"));
+ assertFalse(request.setExtData("a", (String)null, "c"));
+ assertFalse(request.setExtData("a", "b", (String)null));
+ }
+
+ public void testGetExtDataSubkeyValue() {
+ Hashtable value = new Hashtable();
+ value.put("subkey", "value");
+
+ request.setExtData("topkey", value);
+
+ assertEquals("value", request.getExtDataInString("topkey", "SUBKEY"));
+ assertNull(request.getExtDataInString("badkey", "subkey"));
+ assertNull(request.getExtDataInString("topkey", "badkey"));
+ }
+
+ public void testGetSetExtDataInteger() {
+ request.setExtData("foo", new Integer(234));
+
+ assertNotNull(request.mExtData.get("foo"));
+ assertEquals("234", request.mExtData.get("foo"));
+
+ assertEquals(new Integer(234),
+ request.getExtDataInInteger("foo"));
+
+ request.setExtData("strkey", "bar");
+ assertNull(request.getExtDataInInteger("strkey"));
+ assertNull(request.getExtDataInInteger("notfound"));
+
+ assertFalse(request.setExtData("key", (Integer)null));
+ }
+
+ public void testGetSetExtDataIntegerArray() {
+ Integer[] data = new Integer[] {
+ new Integer(5),
+ new Integer(23),
+ new Integer(12)
+ };
+ assertTrue(request.setExtData("topkey1", data));
+ Integer[] retval = request.getExtDataInIntegerArray("topkey1");
+ assertEquals(3, retval.length);
+ assertEquals(data[0], retval[0]);
+ assertEquals(data[1], retval[1]);
+ assertEquals(data[2], retval[2]);
+
+ // invalid conversion
+ Hashtable hashValue = new Hashtable();
+ hashValue.put("0", "5");
+ hashValue.put("1", "bar");
+ request.setExtData("topkey2", hashValue);
+ assertNull(request.getExtDataInIntegerArray("topkey2"));
+
+ assertFalse(request.setExtData("key", (Integer[])null));
+ }
+
+ public void testGetSetExtDataBigInteger() {
+ request.setExtData("foo", new BigInteger("234234234234"));
+
+ assertNotNull(request.mExtData.get("foo"));
+ assertEquals("234234234234", request.mExtData.get("foo"));
+
+ assertEquals(new BigInteger("234234234234"),
+ request.getExtDataInBigInteger("foo"));
+
+ request.setExtData("strkey", "bar");
+ assertNull(request.getExtDataInBigInteger("strkey"));
+ assertNull(request.getExtDataInBigInteger("notfound"));
+
+ assertFalse(request.setExtData("key", (BigInteger)null));
+ }
+
+ public void testGetSetExtDataBigIntegerArray() {
+ BigInteger[] data = new BigInteger[] {
+ new BigInteger("111111111"),
+ new BigInteger("222222222"),
+ new BigInteger("333333333")
+ };
+ assertTrue(request.setExtData("topkey1", data));
+ BigInteger[] retval = request.getExtDataInBigIntegerArray("topkey1");
+ assertEquals(3, retval.length);
+ assertEquals(data[0], retval[0]);
+ assertEquals(data[1], retval[1]);
+ assertEquals(data[2], retval[2]);
+
+ // invalid conversion
+ Hashtable hashValue = new Hashtable();
+ hashValue.put("0", "5");
+ hashValue.put("1", "bar");
+ request.setExtData("topkey2", hashValue);
+ assertNull(request.getExtDataInBigIntegerArray("topkey2"));
+
+ assertFalse(request.setExtData("key", (BigInteger[])null));
+ }
+
+ public void testSetExtDataThrowable() {
+ EBaseException e = new EBaseException("This is an error");
+
+ request.setExtData("key", e);
+
+ assertEquals(e.toString(), request.mExtData.get("key"));
+
+ assertFalse(request.setExtData("key", (Throwable)null));
+ }
+
+ public void testGetSetByteArray() {
+ byte[] data = new byte[] { 112, 96, 0, -12 };
+
+ assertFalse(cmsStub.bToACalled);
+ request.setExtData("key", data);
+ assertTrue(cmsStub.bToACalled);
+ assertEquals(data, cmsStub.bToACalledWith);
+
+ assertFalse(cmsStub.aToBCalled);
+ byte[] out = request.getExtDataInByteArray("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertEquals(data, out);
+
+ assertFalse(request.setExtData("key", (byte[])null));
+ }
+
+ public void testGetSetCert() throws CertificateException {
+ X509CertImpl cert = getFakeCert();
+
+ assertFalse(cmsStub.bToACalled);
+ assertTrue(request.setExtData("key", cert));
+ assertTrue(cmsStub.bToACalled);
+
+ assertFalse(cmsStub.aToBCalled);
+ X509CertImpl retval = request.getExtDataInCert("key");
+ assertTrue(cmsStub.aToBCalled);
+ assertEquals(cert, retval);
+
+ assertFalse(request.setExtData("key", (X509CertImpl)null));
+ }
+
+ public void testGetSetCertArray() throws CertificateException {
+ // this test is also pretty weak, but fortunately relies on the
+ // building blocks.
+ X509CertImpl[] vals = new X509CertImpl[] {
+ getFakeCert(),
+ getFakeCert()
+ };
+
+ assertTrue(request.setExtData("key", vals));
+ Hashtable hashVals = (Hashtable)request.mExtData.get("key");
+ assertEquals(2, hashVals.keySet().size());
+
+ assertFalse(cmsStub.aToBCalled);
+ X509CertImpl[] retval = request.getExtDataInCertArray("key");
+ assertTrue(cmsStub.aToBCalled);
+
+ assertEquals(2, retval.length);
+ assertEquals(vals[0], retval[0]);
+ assertEquals(vals[1], retval[1]);
+
+ assertFalse(request.setExtData("key", (X509CertImpl[])null));
+ }
+
+ public void testGetSetStringArray() {
+ String[] value = new String[] {"blue", "green", "red", "orange"};
+ assertTrue(request.setExtData("key", value));
+
+ assertTrue(request.mExtData.containsKey("key"));
+ Hashtable hashValue = (Hashtable)request.mExtData.get("key");
+ assertTrue(hashValue.containsKey("0"));
+ assertTrue(hashValue.containsKey("1"));
+ assertTrue(hashValue.containsKey("2"));
+ assertTrue(hashValue.containsKey("3"));
+ assertEquals("blue", hashValue.get("0"));
+ assertEquals("green", hashValue.get("1"));
+ assertEquals("red", hashValue.get("2"));
+ assertEquals("orange", hashValue.get("3"));
+
+ String[] retval = request.getExtDataInStringArray("key");
+ assertEquals(4, retval.length);
+ assertEquals("blue", retval[0]);
+ assertEquals("green", retval[1]);
+ assertEquals("red", retval[2]);
+ assertEquals("orange", retval[3]);
+
+ // Try with sparse input
+ hashValue = new Hashtable();
+ hashValue.put("0", "square");
+ hashValue.put("4", "triangle");
+ hashValue.put("6", "octogon");
+ request.setExtData("kevin", hashValue);
+
+ retval = request.getExtDataInStringArray("kevin");
+ assertEquals(7, retval.length);
+ assertEquals("square", retval[0]);
+ assertNull(retval[1]);
+ assertNull(retval[2]);
+ assertNull(retval[3]);
+ assertEquals("triangle", retval[4]);
+ assertNull(retval[5]);
+ assertEquals("octogon", retval[6]);
+
+ // invalid conversion
+ hashValue = new Hashtable();
+ hashValue.put("0", "foo");
+ hashValue.put("badkey", "bar");
+ request.setExtData("cory", hashValue);
+ assertNull(request.getExtDataInStringArray("cory"));
+
+ assertFalse(request.setExtData("key", (String[])null));
+
+ }
+
+ public void testGetSetStringVector() {
+ Vector stringVector = new Vector();
+ stringVector.add("blue");
+ stringVector.add("green");
+ stringVector.add("red");
+ stringVector.add("orange");
+
+ assertTrue(request.setExtData("key", stringVector));
+
+ assertTrue(request.mExtData.containsKey("key"));
+ Hashtable hashValue = (Hashtable)request.mExtData.get("key");
+ assertTrue(hashValue.containsKey("0"));
+ assertTrue(hashValue.containsKey("1"));
+ assertTrue(hashValue.containsKey("2"));
+ assertTrue(hashValue.containsKey("3"));
+ assertEquals("blue", hashValue.get("0"));
+ assertEquals("green", hashValue.get("1"));
+ assertEquals("red", hashValue.get("2"));
+ assertEquals("orange", hashValue.get("3"));
+
+ Vector retval = request.getExtDataInStringVector("key");
+ assertEquals(4, retval.size());
+ assertEquals("blue", retval.elementAt(0));
+ assertEquals("green", retval.elementAt(1));
+ assertEquals("red", retval.elementAt(2));
+ assertEquals("orange", retval.elementAt(3));
+
+ // invalid conversion
+ hashValue = new Hashtable();
+ hashValue.put("0", "foo");
+ hashValue.put("badkey", "bar");
+ request.setExtData("cory", hashValue);
+ assertNull(request.getExtDataInStringVector("cory"));
+
+ assertFalse(request.setExtData("key", (Vector)null));
+ }
+
+ public void testGetSetCertInfo() {
+ X509CertInfoStub cert = new X509CertInfoStub();
+
+ assertFalse(cmsStub.bToACalled);
+ assertFalse(cert.getEncodedCalled);
+ assertTrue(request.setExtData("key", cert));
+ assertTrue(cmsStub.bToACalled);
+ assertTrue(cert.getEncodedCalled);
+
+ // this is a pretty weak test, but it's hard to assert much here
+ assertFalse(cmsStub.aToBCalled);
+ request.getExtDataInCertInfo("key");
+ assertTrue(cmsStub.aToBCalled);
+
+ assertFalse(request.setExtData("key", (X509CertInfo)null));
+ }
+
+ public void testGetSetCertInfoArray() {
+ X509CertInfo[] vals = new X509CertInfoStub[] {
+ new X509CertInfoStub(),
+ new X509CertInfoStub()
+ };
+
+ assertTrue(request.setExtData("key", vals));
+ Hashtable hashVals = (Hashtable)request.mExtData.get("key");
+ assertEquals(2, hashVals.keySet().size());
+
+ assertFalse(cmsStub.aToBCalled);
+ request.getExtDataInCertInfoArray("key");
+ assertTrue(cmsStub.aToBCalled);
+
+ assertFalse(request.setExtData("key", (X509CertInfo[])null));
+ }
+
+ public void testGetBoolean() {
+ Hashtable hashValue = new Hashtable();
+ hashValue.put("one", "false");
+ hashValue.put("two", "true");
+ hashValue.put("three", "on");
+ hashValue.put("four", "off");
+ request.mExtData.put("hashkey", hashValue);
+
+ assertFalse(request.getExtDataInBoolean("hashkey", "one", true));
+ assertTrue(request.getExtDataInBoolean("hashkey", "two", false));
+ assertTrue(request.getExtDataInBoolean("hashkey", "three", false));
+ assertFalse(request.getExtDataInBoolean("hashkey", "four", true));
+
+ assertTrue(request.getExtDataInBoolean("notfound", "nope", true));
+ assertTrue(request.getExtDataInBoolean("hashkey", "notfound", true));
+
+ assertFalse(request.getExtDataInBoolean("notfound", "nope", false));
+ assertFalse(request.getExtDataInBoolean("hashkey", "notfound", false));
+
+ request.mExtData.put("one", "false");
+ request.mExtData.put("two", "true");
+ request.mExtData.put("three", "on");
+ request.mExtData.put("four", "off");
+
+ assertFalse(request.getExtDataInBoolean("one", true));
+ assertTrue(request.getExtDataInBoolean("two", false));
+ assertTrue(request.getExtDataInBoolean("three", false));
+ assertFalse(request.getExtDataInBoolean("four", true));
+
+ assertTrue(request.getExtDataInBoolean("notfound", true));
+ assertFalse(request.getExtDataInBoolean("notfound", false));
+ }
+
+ public void testGetSetRevokedCertArray() {
+ RevokedCertImpl[] vals = new RevokedCertImplStub[] {
+ new RevokedCertImplStub(),
+ new RevokedCertImplStub()
+ };
+
+ assertTrue(request.setExtData("key", vals));
+ Hashtable hashVals = (Hashtable)request.mExtData.get("key");
+ assertEquals(2, hashVals.keySet().size());
+
+ assertFalse(cmsStub.aToBCalled);
+ request.getExtDataInCertInfoArray("key");
+ assertTrue(cmsStub.aToBCalled);
+
+ assertFalse(request.setExtData("key", (RevokedCertImpl[])null));
+ }
+
+ public void testGetSetCertExts() throws IOException {
+ CertificateExtensions exts = new CertificateExtensions();
+ BasicConstraintsExtension ext = new BasicConstraintsExtension(false, 1);
+
+ // check if empty CertificateExtensions work
+ assertTrue(request.setExtData("key", exts));
+ CertificateExtensions retval = request.getExtDataInCertExts("key");
+ assertNotNull(retval);
+ assertEquals(0, retval.size());
+
+ exts.set(PKIXExtensions.BasicConstraints_Id.toString(), ext);
+ assertTrue(request.setExtData("key2", exts));
+ assertTrue(request.mExtData.containsKey("key2"));
+
+ retval = request.getExtDataInCertExts("key2");
+ assertNotNull(retval);
+ assertEquals(1, retval.size());
+
+ assertFalse(request.setExtData("key", (CertificateExtensions)null));
+ }
+
+ public void testGetSetCertSubjectName() throws IOException {
+ CertificateSubjectName name = new CertificateSubjectName(
+ new X500Name("cn=kevin"));
+ assertTrue(request.setExtData("key", name));
+ assertTrue(request.mExtData.containsKey("key"));
+
+ CertificateSubjectName retval = request.getExtDataInCertSubjectName("key");
+ assertNotNull(retval);
+ // the 'CN=' is uppercased at some point
+ assertEquals("cn=kevin",
+ retval.get(CertificateSubjectName.DN_NAME).toString().toLowerCase());
+
+ assertFalse(request.setExtData("key", (CertificateSubjectName)null));
+ }
+
+ public void testGetSetAuthToken() {
+ AuthToken token = new AuthToken(null);
+ token.set("key1", "val1");
+ token.set("key2", "val2");
+ token.set("key3", Integer.valueOf(5));
+
+ assertTrue(request.setExtData("key", token));
+
+ IAuthToken retval = request.getExtDataInAuthToken("key");
+ assertNotNull(retval);
+
+ assertEquals(token.getInString("key1"), retval.getInString("key1"));
+ assertEquals(token.getInString("key2"), retval.getInString("key2"));
+ assertEquals(token.getInInteger("key3"), retval.getInInteger("key3"));
+
+ assertFalse(request.setExtData("key", (AuthToken)null));
+ }
+
+ /**
+ * CMSMemoryStub
+ *
+ * This class is used to help test methods that rely on setting and then
+ * getting a value out. It assumes BtoA is always called first, stores
+ * the value passed in, and then returns that value for BtoA.
+ */
+ class CMSMemoryStub extends CMSEngineDefaultStub {
+ boolean bToACalled = false;
+ byte[] bToACalledWith = null;
+
+ boolean aToBCalled = false;
+ String aToBCalledWith = null;
+
+ public String BtoA(byte data[]) {
+ bToACalled = true;
+ bToACalledWith = data;
+ return "garbagetostoreinthehash";
+ }
+
+ public byte[] AtoB(String data) {
+ aToBCalled = true;
+ aToBCalledWith = data;
+ return bToACalledWith;
+ }
+ }
+
+ class X509CertInfoStub extends X509CertInfo {
+ boolean getEncodedCalled = false;
+
+ public X509CertInfoStub() {
+ }
+
+ public byte[] getEncodedInfo(boolean ignoreCache) throws CertificateEncodingException {
+ getEncodedCalled = true;
+ return new byte[] {};
+ }
+ }
+
+ class RevokedCertImplStub extends RevokedCertImpl {
+ boolean getEncodedCalled = false;
+
+
+ public byte[] getEncoded() throws CRLException {
+ getEncodedCalled = true;
+ return new byte[] {};
+ }
+ }
+
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java b/pki/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java
new file mode 100644
index 000000000..14ed72090
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java
@@ -0,0 +1,98 @@
+package com.netscape.cmscore.test;
+
+import com.netscape.certsrv.app.CMSEngineDefaultStub;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.LoggerDefaultStub;
+import com.netscape.cmscore.dbs.DBRegistryDefaultStub;
+import com.netscape.cmscore.dbs.DBSSessionDefaultStub;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.dbs.DBSubsystemDefaultStub;
+import junit.framework.TestCase;
+import netscape.security.x509.X509CertImpl;
+
+import java.security.cert.CertificateException;
+
+/**
+ * The base class for all CMS unit tests. This sets up some basic stubs
+ * that allow unit tests to work without bumping into uninitialized subsystems
+ * (like the CMS logging system).
+ */
+public abstract class CMSBaseTestCase extends TestCase {
+ CMSEngineStub engine;
+ LoggerDefaultStub logger;
+ DBSubsystemStub db;
+ DBRegistryDefaultStub registry;
+ DBSSessionDefaultStub session;
+
+ public CMSBaseTestCase(String name) {
+ super(name);
+ }
+
+ public final void setUp() {
+ engine = new CMSEngineStub();
+ logger = new LoggerDefaultStub();
+ db = new DBSubsystemStub();
+ registry = new DBRegistryDefaultStub();
+ session = new DBSSessionDefaultStub();
+
+ CMS.setCMSEngine(engine);
+ DBSubsystem.setInstance(db);
+
+ cmsTestSetUp();
+ }
+
+ public final void tearDown() {
+ cmsTestTearDown();
+ }
+
+ public abstract void cmsTestSetUp();
+
+ public abstract void cmsTestTearDown();
+
+ public X509CertImpl getFakeCert() throws CertificateException {
+ byte[] certData = new byte[] {
+ 48, -126, 1, 18, 48, -127, -67, -96, 3, 2, 1, 2, 2, 1,
+ 1, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 4,
+ 5, 0, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19,
+ 7, 116, 101, 115, 116, 105, 110, 103, 48, 30, 23, 13, 48, 55,
+ 48, 55, 49, 50, 49, 55, 51, 56, 51, 52, 90, 23, 13, 48,
+ 55, 49, 48, 49, 50, 49, 55, 51, 56, 51, 52, 90, 48, 18,
+ 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 116, 101, 115,
+ 116, 105, 110, 103, 48, 92, 48, 13, 6, 9, 42, -122, 72, -122,
+ -9, 13, 1, 1, 1, 5, 0, 3, 75, 0, 48, 72, 2, 65,
+ 0, -65, 121, -119, -59, 105, 66, -122, -78, -30, -64, 63, -47, 44,
+ -48, -104, 103, -47, -108, 42, -38, 46, -8, 32, 49, -29, -26, -112,
+ -29, -86, 71, 24, -104, 78, -31, -75, -128, 90, -92, -34, -51, -125,
+ -13, 80, 101, -78, 39, -119, -38, 117, 28, 67, -19, -71, -124, -85,
+ 105, -53, -103, -59, -67, -38, -83, 118, 65, 2, 3, 1, 0, 1,
+ 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 4, 5,
+ 0, 3, 65, 0, -97, -62, 79, -28, 124, -81, 98, 119, -85, -49,
+ 62, -81, 46, -25, -29, 78, -40, 118, -2, 114, -128, 74, -47, -68,
+ 52, 11, -14, 30, -46, -95, -26, -108, -19, 110, -63, -70, 61, -75,
+ 64, 74, -33, -65, -96, 120, -109, 37, 77, -76, 38, -114, 58, -80,
+ -122, -39, -65, -31, 37, -30, -126, 126, 17, -82, 92, 64,
+ };
+
+ return new X509CertImpl(certData);
+ }
+
+ class CMSEngineStub extends CMSEngineDefaultStub {
+ public ILogger getLogger() {
+ return logger;
+ }
+ }
+
+ class DBSubsystemStub extends DBSubsystemDefaultStub {
+ public IDBSSession createSession() throws EDBException {
+ return session;
+ }
+
+ public IDBRegistry getRegistry() {
+ return registry;
+ }
+ }
+}
diff --git a/pki/base/common/test/com/netscape/cmscore/test/TestHelper.java b/pki/base/common/test/com/netscape/cmscore/test/TestHelper.java
new file mode 100644
index 000000000..cc19d8aba
--- /dev/null
+++ b/pki/base/common/test/com/netscape/cmscore/test/TestHelper.java
@@ -0,0 +1,30 @@
+package com.netscape.cmscore.test;
+
+import java.util.Enumeration;
+
+/**
+ * Testing helper methods
+ */
+public class TestHelper {
+
+ public static boolean enumerationContains(Enumeration enumeration,
+ Object element) {
+ while (enumeration.hasMoreElements()) {
+ if (enumeration.nextElement().equals(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(String[] list, String element) {
+ for (int index = 0; index < list.length; index++) {
+ if (list[index].equals(element)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}